Merge "Revert "Marshal dream overlay connection logic with Handler."" into tm-qpr-dev
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index b9673f2..f49cdbf 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -18,6 +18,7 @@
 
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
@@ -240,7 +241,7 @@
 
     /**
      * Default value for all regular jobs. As noted in {@link JobScheduler},
-     * these jobs have a general maximum execution time of 10 minutes.
+     * these jobs have a general execution time of 10 minutes.
      * Receives the standard job management policy.
      */
     public static final int PRIORITY_DEFAULT = 300;
@@ -249,7 +250,7 @@
      * This task should be ordered ahead of most other tasks. It may be
      * deferred a little, but if it doesn't run at some point, the user may think
      * something is wrong. Assuming all constraints remain satisfied
-     * (including ideal system load conditions), these jobs will have a maximum
+     * (including ideal system load conditions), these jobs can have an
      * execution time of at least 4 minutes. Setting all of your jobs to high
      * priority will not be beneficial to your app and in fact may hurt its
      * performance in the long run.
@@ -259,7 +260,7 @@
     /**
      * This task should be run ahead of all other tasks. Only Expedited Jobs
      * {@link Builder#setExpedited(boolean)} can have this priority and as such,
-     * are subject to the same maximum execution time details noted in
+     * are subject to the same execution time details noted in
      * {@link Builder#setExpedited(boolean)}.
      * A sample task of max priority: receiving a text message and processing it to
      * show a notification
@@ -1332,6 +1333,7 @@
                 builder.addCapability(NET_CAPABILITY_INTERNET);
                 builder.addCapability(NET_CAPABILITY_VALIDATED);
                 builder.removeCapability(NET_CAPABILITY_NOT_VPN);
+                builder.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
 
                 if (networkType == NETWORK_TYPE_ANY) {
                     // No other capabilities
@@ -1412,6 +1414,15 @@
          * you also need to define the network traffic used by each work item
          * when constructing them.
          *
+         * <p class="note">
+         * Prior to Android version {@link Build.VERSION_CODES#TIRAMISU}, JobScheduler used the
+         * estimated transfer numbers in a similar fashion to
+         * {@link #setMinimumNetworkChunkBytes(long)} (to estimate if the work would complete
+         * within the time available to job). In other words, JobScheduler treated the transfer as
+         * all-or-nothing. Starting from Android version {@link Build.VERSION_CODES#TIRAMISU},
+         * JobScheduler will only use the estimated transfer numbers in this manner if minimum
+         * chunk sizes have not been provided via {@link #setMinimumNetworkChunkBytes(long)}.
+         *
          * @param downloadBytes The estimated size of network traffic that will
          *            be downloaded by this job, in bytes.
          * @param uploadBytes The estimated size of network traffic that will be
@@ -1754,14 +1765,19 @@
          *
          * <p>
          * Assuming all constraints remain satisfied (including ideal system load conditions),
-         * expedited jobs will have a maximum execution time of at least 1 minute. If your
+         * expedited jobs can have an execution time of at least 1 minute. If your
          * app has remaining expedited job quota, then the expedited job <i>may</i> potentially run
          * longer until remaining quota is used up. Just like with regular jobs, quota is not
          * consumed while the app is on top and visible to the user.
          *
-         * <p>
+         * <p class="note">
          * Note: Even though expedited jobs are meant to run as soon as possible, they may be
          * deferred if the system is under heavy load or requested constraints are not satisfied.
+         * This delay may be true for expedited jobs of the foreground app on Android version
+         * {@link Build.VERSION_CODES#S}, but starting from Android version
+         * {@link Build.VERSION_CODES#TIRAMISU}, expedited jobs for the foreground app are
+         * guaranteed to be started before {@link JobScheduler#schedule(JobInfo)} returns (assuming
+         * all requested constraints are satisfied), similar to foreground services.
          *
          * @see JobInfo#isExpedited()
          */
@@ -1797,6 +1813,9 @@
          * and in the background, or the job failed due to unsatisfied constraints,
          * this job should be expected to behave like other jobs without this flag.
          *
+         * <p>
+         * Jobs marked as important-while-foreground are given {@link #PRIORITY_HIGH} by default.
+         *
          * @param importantWhileForeground whether to relax doze restrictions for this job when the
          *                                 app is in the foreground. False by default.
          * @see JobInfo#isImportantWhileForeground()
@@ -1829,8 +1848,9 @@
          * the specific user of this device. For example, fetching top headlines
          * of interest to the current user.
          * <p>
-         * Starting with Android version {@link Build.VERSION_CODES#TIRAMISU}, prefetch jobs are
-         * not allowed to have deadlines (set via {@link #setOverrideDeadline(long)}.
+         * Apps targeting Android version {@link Build.VERSION_CODES#TIRAMISU} or later are
+         * not allowed to have deadlines (set via {@link #setOverrideDeadline(long)} on their
+         * prefetch jobs.
          * <p>
          * The system may use this signal to relax the network constraints you
          * originally requested, such as allowing a
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
index 1429c45..ed72530 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
@@ -167,7 +167,7 @@
     /**
      * The job used up its maximum execution time and timed out. Each individual job has a maximum
      * execution time limit, regardless of how much total quota the app has. See the note on
-     * {@link JobScheduler} for the execution time limits.
+     * {@link JobScheduler} and {@link JobInfo} for the execution time limits.
      */
     public static final int STOP_REASON_TIMEOUT = 3;
     /**
diff --git a/apex/jobscheduler/framework/java/android/app/tare/EconomyManager.java b/apex/jobscheduler/framework/java/android/app/tare/EconomyManager.java
index dd0d07f..c3fc7b1 100644
--- a/apex/jobscheduler/framework/java/android/app/tare/EconomyManager.java
+++ b/apex/jobscheduler/framework/java/android/app/tare/EconomyManager.java
@@ -16,8 +16,10 @@
 
 package android.app.tare;
 
+import android.annotation.Nullable;
 import android.annotation.SystemService;
 import android.content.Context;
+import android.util.Log;
 
 /**
  * Provides access to the resource economy service.
@@ -26,6 +28,69 @@
  */
 @SystemService(Context.RESOURCE_ECONOMY_SERVICE)
 public class EconomyManager {
+    private static final String TAG = "TARE-" + EconomyManager.class.getSimpleName();
+
+    /**
+     * 1 ARC = 1 GIGA-CAKE!
+     *
+     * @hide
+     */
+    public static final long CAKE_IN_ARC = 1_000_000_000L;
+
+    /** @hide */
+    public static long arcToCake(int arcs) {
+        return arcs * CAKE_IN_ARC;
+    }
+
+    /**
+     * Parses a configuration string to get the value in cakes.
+     *
+     * @hide
+     */
+    public static long parseCreditValue(@Nullable final String val, final long defaultValCakes) {
+        String trunc;
+        if (val == null || (trunc = val.trim()).isEmpty()) {
+            return defaultValCakes;
+        }
+        long multiplier;
+        if (trunc.endsWith("c")) {
+            trunc = trunc.substring(0, trunc.length() - 1);
+            multiplier = 1;
+        } else if (trunc.endsWith("ck")) {
+            trunc = trunc.substring(0, trunc.length() - 2);
+            multiplier = 1;
+        } else if (trunc.endsWith("A")) {
+            trunc = trunc.substring(0, trunc.length() - 1);
+            multiplier = CAKE_IN_ARC;
+        } else if (trunc.endsWith("ARC")) {
+            trunc = trunc.substring(0, trunc.length() - 3);
+            multiplier = CAKE_IN_ARC;
+        } else {
+            // Don't risk using the wrong units
+            Log.e(TAG, "Couldn't determine units of credit value: " + val);
+            return defaultValCakes;
+        }
+
+        // Allow people to shorten notation (eg. Mc for Megacake).
+        if (trunc.endsWith("k")) {
+            trunc = trunc.substring(0, trunc.length() - 1);
+            multiplier *= 1_000;
+        } else if (trunc.endsWith("M")) {
+            trunc = trunc.substring(0, trunc.length() - 1);
+            multiplier *= 1_000_000;
+        } else if (trunc.endsWith("G")) {
+            trunc = trunc.substring(0, trunc.length() - 1);
+            multiplier *= 1_000_000_000;
+        }
+
+        try {
+            return Long.parseLong(trunc) * multiplier;
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "Malformed config string: " + val + " to " + trunc, e);
+            return defaultValCakes;
+        }
+    }
+
     // Keys for AlarmManager TARE factors
     /** @hide */
     public static final String KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED =
@@ -276,179 +341,201 @@
 
     // Default values AlarmManager factors
     /** @hide */
-    public static final int DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED = 500;
+    public static final long DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES = arcToCake(500);
     /** @hide */
-    public static final int DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP = 200;
+    public static final long DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES =
+            arcToCake(256);
     /** @hide */
-    public static final int DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP = 160;
+    public static final long DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES = arcToCake(160);
     /** @hide */
-    public static final int DEFAULT_AM_MAX_SATIATED_BALANCE = 1440;
+    public static final long DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES = arcToCake(960);
     /** @hide */
-    public static final int DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT = 4000;
+    public static final long DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES = arcToCake(2880);
     /** @hide */
-    public static final int DEFAULT_AM_HARD_CONSUMPTION_LIMIT = 28_800;
+    public static final long DEFAULT_AM_HARD_CONSUMPTION_LIMIT_CAKES = arcToCake(15_000);
     // TODO: add AlarmManager modifier default values
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT = 0;
+    public static final long DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES = arcToCake(0);
     /** @hide */
-    public static final float DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING = 0.01f;
+    // 10 megacakes = .01 ARC
+    public static final long DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES = 10_000_000;
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX = 500;
+    public static final long DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES = arcToCake(500);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT = 3;
+    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES = arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING = 0;
+    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES = arcToCake(0);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX = 60;
+    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES = arcToCake(60);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_INSTANT = 5;
+    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_INSTANT_CAKES =
+            arcToCake(5);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_ONGOING = 0;
+    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_ONGOING_CAKES =
+            arcToCake(0);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_MAX = 500;
+    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_MAX_CAKES =
+            arcToCake(500);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT = 5;
+    public static final long DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES =
+            arcToCake(5);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING = 0;
+    public static final long DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES =
+            arcToCake(0);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX = 500;
+    public static final long DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES = arcToCake(500);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT = 10;
+    public static final long DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES = arcToCake(10);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING = 0;
+    public static final long DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES = arcToCake(0);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX = 500;
+    public static final long DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES = arcToCake(500);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT = 10;
+    public static final long DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES = arcToCake(10);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING = 0;
+    public static final long DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES = arcToCake(0);
     /** @hide */
-    public static final int DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX = 500;
+    public static final long DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES = arcToCake(500);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP = 3;
+    public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES =
+            arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP = 3;
+    public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES =
+            arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP = 3;
+    public static final long DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES = arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP = 3;
+    public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES = arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP = 1;
+    public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES =
+            arcToCake(1);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP = 1;
+    public static final long DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES = arcToCake(1);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP = 1;
+    public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES =
+            arcToCake(1);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP = 1;
+    public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES = arcToCake(1);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP = 5;
+    public static final long DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES = arcToCake(5);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE = 5;
+    public static final long
+            DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(5);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE = 4;
+    public static final long
+            DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(4);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE = 4;
+    public static final long DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(4);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE = 3;
+    public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE = 3;
+    public static final long
+            DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE_CAKES =
+            arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE = 2;
+    public static final long DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES =
+            arcToCake(2);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE =
-            2;
+    public static final long
+            DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES =
+            arcToCake(2);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE = 1;
+    public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES =
+            arcToCake(1);
     /** @hide */
-    public static final int DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE = 10;
+    public static final long DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES = arcToCake(10);
 
     // Default values JobScheduler factors
     // TODO: add time_since_usage variable to min satiated balance factors
     /** @hide */
-    public static final int DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED = 20000;
+    public static final long DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES = arcToCake(15000);
     /** @hide */
-    public static final int DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP = 10000;
+    public static final long DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES =
+            arcToCake(7500);
     /** @hide */
-    public static final int DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP = 2000;
+    public static final long DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES = arcToCake(2000);
     /** @hide */
-    public static final int DEFAULT_JS_MAX_SATIATED_BALANCE = 60000;
+    public static final long DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES = arcToCake(60000);
     /** @hide */
-    public static final int DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT = 100_000;
+    public static final long DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES = arcToCake(29_000);
     /** @hide */
-    public static final int DEFAULT_JS_HARD_CONSUMPTION_LIMIT = 460_000;
+    // TODO: set hard limit based on device type (phone vs tablet vs etc) + battery size
+    public static final long DEFAULT_JS_HARD_CONSUMPTION_LIMIT_CAKES = arcToCake(250_000);
     // TODO: add JobScheduler modifier default values
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT = 0;
+    public static final long DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES = arcToCake(0);
     /** @hide */
-    public static final float DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING = 0.5f;
+    public static final long DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES = CAKE_IN_ARC / 2;
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX = 15000;
+    public static final long DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES = arcToCake(15000);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT = 1;
+    public static final long DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES = arcToCake(1);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING = 0;
+    public static final long DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES = arcToCake(0);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX = 10;
+    public static final long DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES = arcToCake(10);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT = 5;
+    public static final long DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES =
+            arcToCake(5);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING = 0;
+    public static final long DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES =
+            arcToCake(0);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX = 5000;
+    public static final long DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES = arcToCake(5000);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT = 10;
+    public static final long DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES = arcToCake(10);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING = 0;
+    public static final long DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES = arcToCake(0);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX = 5000;
+    public static final long DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES = arcToCake(5000);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT = 10;
+    public static final long DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES = arcToCake(10);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING = 0;
+    public static final long DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES = arcToCake(0);
     /** @hide */
-    public static final int DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX = 5000;
+    public static final long DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES = arcToCake(5000);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_MAX_START_CTP = 3;
+    public static final long DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES = arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP = 2;
+    public static final long DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES = arcToCake(2);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_HIGH_START_CTP = 3;
+    public static final long DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES = arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP = 2;
+    public static final long DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES = arcToCake(2);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP = 3;
+    public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES = arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP = 2;
+    public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES = arcToCake(2);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_LOW_START_CTP = 3;
+    public static final long DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES = arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP = 2;
+    public static final long DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES = arcToCake(2);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_MIN_START_CTP = 3;
+    public static final long DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES = arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP = 2;
+    public static final long DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES = arcToCake(2);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP = 30;
+    public static final long DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES = arcToCake(30);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE = 10;
+    public static final long DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES = arcToCake(10);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE = 5;
+    public static final long DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES = arcToCake(5);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE = 8;
+    public static final long DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES = arcToCake(8);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE = 4;
+    public static final long DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES = arcToCake(4);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE = 6;
+    public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES = arcToCake(6);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE = 3;
+    public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES = arcToCake(3);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE = 4;
+    public static final long DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES = arcToCake(4);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE = 2;
+    public static final long DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES = arcToCake(2);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE = 2;
+    public static final long DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES = arcToCake(2);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE = 1;
+    public static final long DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES = arcToCake(1);
     /** @hide */
-    public static final int DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE = 60;
+    public static final long DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES = arcToCake(60);
 }
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index c8ec894..c86353c 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -690,6 +690,12 @@
         int projectedRunningCount = numRunningJobs;
         while ((nextPending = pendingJobQueue.next()) != null) {
             if (mRunningJobs.contains(nextPending)) {
+                // Should never happen.
+                Slog.wtf(TAG, "Pending queue contained a running job");
+                if (DEBUG) {
+                    Slog.e(TAG, "Pending+running job: " + nextPending);
+                }
+                pendingJobQueue.remove(nextPending);
                 continue;
             }
 
@@ -1137,7 +1143,8 @@
             }
         }
 
-        if (mActiveServices.size() >= STANDARD_CONCURRENCY_LIMIT) {
+        final PendingJobQueue pendingJobQueue = mService.getPendingJobQueue();
+        if (mActiveServices.size() >= STANDARD_CONCURRENCY_LIMIT || pendingJobQueue.size() == 0) {
             worker.clearPreferredUid();
             // We're over the limit (because the TOP app scheduled a lot of EJs). Don't start
             // running anything new until we get back below the limit.
@@ -1145,7 +1152,6 @@
             return;
         }
 
-        final PendingJobQueue pendingJobQueue = mService.getPendingJobQueue();
         if (worker.getPreferredUid() != JobServiceContext.NO_PREFERRED_UID) {
             updateCounterConfigLocked();
             // Preemption case needs special care.
@@ -1162,6 +1168,12 @@
             pendingJobQueue.resetIterator();
             while ((nextPending = pendingJobQueue.next()) != null) {
                 if (mRunningJobs.contains(nextPending)) {
+                    // Should never happen.
+                    Slog.wtf(TAG, "Pending queue contained a running job");
+                    if (DEBUG) {
+                        Slog.e(TAG, "Pending+running job: " + nextPending);
+                    }
+                    pendingJobQueue.remove(nextPending);
                     continue;
                 }
 
@@ -1239,6 +1251,12 @@
             while ((nextPending = pendingJobQueue.next()) != null) {
 
                 if (mRunningJobs.contains(nextPending)) {
+                    // Should never happen.
+                    Slog.wtf(TAG, "Pending queue contained a running job");
+                    if (DEBUG) {
+                        Slog.e(TAG, "Pending+running job: " + nextPending);
+                    }
+                    pendingJobQueue.remove(nextPending);
                     continue;
                 }
 
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 9e13133..358c327 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1749,8 +1749,13 @@
         if (!removed) {
             // We never create JobStatus objects for the express purpose of removing them, and this
             // method is only ever called for jobs that were saved in the JobStore at some point,
-            // so if we can't find it, something went seriously wrong.
-            Slog.wtfStack(TAG, "Job didn't exist in JobStore");
+            // so if we can't find it, something may be wrong. As of Android T, there is a
+            // legitimate code path where removed is false --- when an actively running job is
+            // cancelled (eg. via JobScheduler.cancel() or the app scheduling a new job with the
+            // same job ID), we remove it from the JobStore and tell the JobServiceContext to stop
+            // running the job. Once the job stops running, we then call this method again.
+            // TODO: rework code so we don't intentionally call this method twice for the same job
+            Slog.w(TAG, "Job didn't exist in JobStore");
         }
         if (mReadyToRock) {
             for (int i = 0; i < mControllers.size(); i++) {
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
index c2e8188..d0f719b 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
@@ -16,43 +16,43 @@
 
 package com.android.server.tare;
 
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_AM_HARD_CONSUMPTION_LIMIT;
-import static android.app.tare.EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT;
-import static android.app.tare.EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE;
-import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED;
-import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_HARD_CONSUMPTION_LIMIT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES;
 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE;
 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP;
 import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE;
@@ -97,12 +97,12 @@
 import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
 import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
 import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
-import static com.android.server.tare.TareUtils.arcToCake;
 import static com.android.server.tare.TareUtils.cakeToString;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ContentResolver;
+import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.util.IndentingPrintWriter;
 import android.util.KeyValueListParser;
@@ -157,14 +157,15 @@
     AlarmManagerEconomicPolicy(InternalResourceService irs) {
         super(irs);
         mInternalResourceService = irs;
-        loadConstants("");
+        loadConstants("", null);
     }
 
     @Override
-    void setup() {
-        super.setup();
+    void setup(@NonNull DeviceConfig.Properties properties) {
+        super.setup(properties);
         ContentResolver resolver = mInternalResourceService.getContext().getContentResolver();
-        loadConstants(Settings.Global.getString(resolver, TARE_ALARM_MANAGER_CONSTANTS));
+        loadConstants(Settings.Global.getString(resolver, TARE_ALARM_MANAGER_CONSTANTS),
+                properties);
     }
 
     @Override
@@ -178,6 +179,11 @@
 
     @Override
     long getMaxSatiatedBalance() {
+        // TODO(230501287): adjust balance based on whether the app has the SCHEDULE_EXACT_ALARM
+        // permission granted. Apps without the permission granted shouldn't need a high balance
+        // since they won't be able to use exact alarms. Apps with the permission granted could
+        // have a higher balance, or perhaps just those with the USE_EXACT_ALARM permission since
+        // that is limited to specific use cases.
         return mMaxSatiatedBalance;
     }
 
@@ -209,7 +215,8 @@
         return mRewards.get(rewardId);
     }
 
-    private void loadConstants(String policyValuesString) {
+    private void loadConstants(String policyValuesString,
+            @Nullable DeviceConfig.Properties properties) {
         mActions.clear();
         mRewards.clear();
 
@@ -219,145 +226,159 @@
             Slog.e(TAG, "Global setting key incorrect: ", e);
         }
 
-        mMinSatiatedBalanceExempted = arcToCake(mParser.getInt(KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED,
-                DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED));
-        mMinSatiatedBalanceOther = arcToCake(mParser.getInt(KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP,
-                DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP));
-        mMaxSatiatedBalance = arcToCake(mParser.getInt(KEY_AM_MAX_SATIATED_BALANCE,
-                DEFAULT_AM_MAX_SATIATED_BALANCE));
-        mInitialSatiatedConsumptionLimit = arcToCake(mParser.getInt(
-                KEY_AM_INITIAL_CONSUMPTION_LIMIT, DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT));
+        mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
+                KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED,
+                DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES);
+        mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
+                KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP,
+                DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
+        mMaxSatiatedBalance = getConstantAsCake(mParser, properties,
+                KEY_AM_MAX_SATIATED_BALANCE,
+                DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES);
+        mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+                KEY_AM_INITIAL_CONSUMPTION_LIMIT, DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES);
         mHardSatiatedConsumptionLimit = Math.max(mInitialSatiatedConsumptionLimit,
-                arcToCake(mParser.getInt(
-                        KEY_AM_HARD_CONSUMPTION_LIMIT, DEFAULT_AM_HARD_CONSUMPTION_LIMIT)));
+                getConstantAsCake(mParser, properties,
+                        KEY_AM_HARD_CONSUMPTION_LIMIT, DEFAULT_AM_HARD_CONSUMPTION_LIMIT_CAKES));
 
-        final long exactAllowWhileIdleWakeupBasePrice = arcToCake(
-                mParser.getInt(KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE,
-                        DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE));
+        final long exactAllowWhileIdleWakeupBasePrice = getConstantAsCake(mParser, properties,
+                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE,
+                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES);
 
         mActions.put(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
                 new Action(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
-                        arcToCake(mParser.getInt(
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP)),
+                                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES),
                         exactAllowWhileIdleWakeupBasePrice));
         mActions.put(ACTION_ALARM_WAKEUP_EXACT,
                 new Action(ACTION_ALARM_WAKEUP_EXACT,
-                        arcToCake(mParser.getInt(KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP)),
-                        arcToCake(mParser.getInt(KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
-                                DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE))));
+                        getConstantAsCake(mParser, properties,
+                                KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
+                                DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES),
+                        getConstantAsCake(mParser, properties,
+                                KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
+                                DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES)));
 
         final long inexactAllowWhileIdleWakeupBasePrice =
-                arcToCake(mParser.getInt(
+                getConstantAsCake(mParser, properties,
                         KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE,
-                        DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE));
+                        DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES);
 
         mActions.put(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
                 new Action(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
-                        arcToCake(mParser.getInt(
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP)),
+                                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES),
                         inexactAllowWhileIdleWakeupBasePrice));
         mActions.put(ACTION_ALARM_WAKEUP_INEXACT,
                 new Action(ACTION_ALARM_WAKEUP_INEXACT,
-                        arcToCake(mParser.getInt(
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP)),
-                        arcToCake(mParser.getInt(
+                                DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE,
-                                DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE))));
+                                DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES)));
 
-        final long exactAllowWhileIdleNonWakeupBasePrice =
-                arcToCake(mParser.getInt(
-                        KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE,
-                        DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE));
-
+        final long exactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(mParser, properties,
+                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE,
+                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES);
         mActions.put(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
                 new Action(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
-                        arcToCake(mParser.getInt(
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP)),
+                                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES),
                         exactAllowWhileIdleNonWakeupBasePrice));
+
         mActions.put(ACTION_ALARM_NONWAKEUP_EXACT,
                 new Action(ACTION_ALARM_NONWAKEUP_EXACT,
-                        arcToCake(mParser.getInt(
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP)),
-                        arcToCake(mParser.getInt(
+                                DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE,
-                                DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE))));
+                                DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES)));
 
-        final long inexactAllowWhileIdleNonWakeupBasePrice =
-                arcToCake(mParser.getInt(
-                        KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE,
-                        DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE));
-
+        final long inexactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(mParser, properties,
+                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE,
+                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES);
+        final long inexactAllowWhileIdleNonWakeupCtp = getConstantAsCake(mParser, properties,
+                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP,
+                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES);
         mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
                 new Action(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
-                        arcToCake(mParser.getInt(
-                                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP)),
+                        inexactAllowWhileIdleNonWakeupCtp,
                         inexactAllowWhileIdleNonWakeupBasePrice));
+
         mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT,
                 new Action(ACTION_ALARM_NONWAKEUP_INEXACT,
-                        arcToCake(mParser.getInt(
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP)),
-                        arcToCake(mParser.getInt(
+                                DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE,
-                                DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE))));
+                                DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES)));
         mActions.put(ACTION_ALARM_CLOCK,
                 new Action(ACTION_ALARM_CLOCK,
-                        arcToCake(mParser.getInt(
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP,
-                                DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP)),
-                        arcToCake(mParser.getInt(
+                                DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE,
-                                DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE))));
+                                DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES)));
 
         mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
-                arcToCake(mParser.getInt(KEY_AM_REWARD_TOP_ACTIVITY_INSTANT,
-                        DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT)),
-                (long) (arcToCake(1) * mParser.getFloat(KEY_AM_REWARD_TOP_ACTIVITY_ONGOING,
-                        DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING)),
-                arcToCake(mParser.getInt(KEY_AM_REWARD_TOP_ACTIVITY_MAX,
-                        DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX))));
+                getConstantAsCake(mParser, properties,
+                        KEY_AM_REWARD_TOP_ACTIVITY_INSTANT,
+                        DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_AM_REWARD_TOP_ACTIVITY_ONGOING,
+                        DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_AM_REWARD_TOP_ACTIVITY_MAX,
+                        DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES)));
         mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
-                arcToCake(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
-                        DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT)),
-                arcToCake(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING,
-                        DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING)),
-                arcToCake(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
-                        DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX))));
+                getConstantAsCake(mParser, properties,
+                        KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
+                        DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING,
+                        DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
+                        DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES)));
         mRewards.put(REWARD_NOTIFICATION_INTERACTION,
                 new Reward(REWARD_NOTIFICATION_INTERACTION,
-                        arcToCake(mParser.getInt(
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT,
-                                DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT)),
-                        arcToCake(mParser.getInt(
+                                DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING,
-                                DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING)),
-                        arcToCake(mParser.getInt(
+                                DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX,
-                                DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX))));
+                                DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
         mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
-                arcToCake(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
-                        DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT)),
-                arcToCake(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING,
-                        DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING)),
-                arcToCake(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
-                        DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX))));
+                getConstantAsCake(mParser, properties,
+                        KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
+                        DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING,
+                        DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
+                        DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES)));
         mRewards.put(REWARD_OTHER_USER_INTERACTION,
                 new Reward(REWARD_OTHER_USER_INTERACTION,
-                        arcToCake(mParser.getInt(KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
-                                DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT)),
-                        arcToCake(mParser.getInt(
+                        getConstantAsCake(mParser, properties,
+                                KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
+                                DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING,
-                                DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING)),
-                        arcToCake(mParser.getInt(
+                                DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX,
-                                DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX))));
+                                DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
     }
 
     @Override
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/CompleteEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/CompleteEconomicPolicy.java
index 2109a85..c3eb5bf 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/CompleteEconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/CompleteEconomicPolicy.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.provider.DeviceConfig;
 import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 import android.util.SparseArray;
@@ -57,10 +58,10 @@
     }
 
     @Override
-    void setup() {
-        super.setup();
+    void setup(@NonNull DeviceConfig.Properties properties) {
+        super.setup(properties);
         for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
-            mEnabledEconomicPolicies.valueAt(i).setup();
+            mEnabledEconomicPolicies.valueAt(i).setup(properties);
         }
         updateMaxBalances();
     }
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
index 3a26aae..d401373 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
@@ -16,6 +16,8 @@
 
 package com.android.server.tare;
 
+import static android.app.tare.EconomyManager.parseCreditValue;
+
 import static com.android.server.tare.Modifier.COST_MODIFIER_CHARGING;
 import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
 import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
@@ -27,7 +29,9 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.provider.DeviceConfig;
 import android.util.IndentingPrintWriter;
+import android.util.KeyValueListParser;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -170,7 +174,7 @@
     }
 
     @CallSuper
-    void setup() {
+    void setup(@NonNull DeviceConfig.Properties properties) {
         for (int i = 0; i < NUM_COST_MODIFIERS; ++i) {
             final Modifier modifier = COST_MODIFIER_BY_INDEX[i];
             if (modifier != null) {
@@ -409,6 +413,22 @@
         return "UNKNOWN_REWARD:" + Integer.toHexString(eventId);
     }
 
+    protected long getConstantAsCake(@NonNull KeyValueListParser parser,
+            @Nullable DeviceConfig.Properties properties, String key, long defaultValCake) {
+        // Don't cross the streams! Mixing Settings/local user config changes with DeviceConfig
+        // config can cause issues since the scales may be different, so use one or the other.
+        if (parser.size() > 0) {
+            // User settings take precedence. Just stick with the Settings constants, even if there
+            // are invalid values. It's not worth the time to evaluate all the key/value pairs to
+            // make sure there are valid ones before deciding.
+            return parseCreditValue(parser.getString(key, null), defaultValCake);
+        }
+        if (properties != null) {
+            return parseCreditValue(properties.getString(key, null), defaultValCake);
+        }
+        return defaultValCake;
+    }
+
     protected static void dumpActiveModifiers(IndentingPrintWriter pw) {
         for (int i = 0; i < NUM_COST_MODIFIERS; ++i) {
             pw.print("Modifier ");
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
index ce4604f..2118eeb 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
@@ -731,7 +731,7 @@
             registerListeners();
             mCurrentBatteryLevel = getCurrentBatteryLevel();
             mHandler.post(this::setupHeavyWork);
-            mCompleteEconomicPolicy.setup();
+            mCompleteEconomicPolicy.setup(mConfigObserver.getAllDeviceConfigProperties());
         }
     }
 
@@ -1014,10 +1014,17 @@
                     Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS), false, this);
             mContentResolver.registerContentObserver(
                     Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS), false, this);
-            onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TARE));
+            onPropertiesChanged(getAllDeviceConfigProperties());
             updateEnabledStatus();
         }
 
+        @NonNull
+        DeviceConfig.Properties getAllDeviceConfigProperties() {
+            // Don't want to cache the Properties object locally in case it ends up being large,
+            // especially since it'll only be used once/infrequently (during setup or on a change).
+            return DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TARE);
+        }
+
         @Override
         public void onChange(boolean selfChange, Uri uri) {
             if (uri.equals(Settings.Global.getUriFor(Settings.Global.ENABLE_TARE))) {
@@ -1030,6 +1037,7 @@
 
         @Override
         public void onPropertiesChanged(DeviceConfig.Properties properties) {
+            boolean economicPolicyUpdated = false;
             synchronized (mLock) {
                 for (String name : properties.getKeyset()) {
                     if (name == null) {
@@ -1039,6 +1047,12 @@
                         case KEY_DC_ENABLE_TARE:
                             updateEnabledStatus();
                             break;
+                        default:
+                            if (!economicPolicyUpdated
+                                    && (name.startsWith("am") || name.startsWith("js"))) {
+                                updateEconomicPolicy();
+                                economicPolicyUpdated = true;
+                            }
                     }
                 }
             }
@@ -1072,7 +1086,7 @@
                 mCompleteEconomicPolicy.tearDown();
                 mCompleteEconomicPolicy = new CompleteEconomicPolicy(InternalResourceService.this);
                 if (mIsEnabled && mBootPhase >= PHASE_SYSTEM_SERVICES_READY) {
-                    mCompleteEconomicPolicy.setup();
+                    mCompleteEconomicPolicy.setup(getAllDeviceConfigProperties());
                     if (initialLimit != mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit()
                             || hardLimit
                             != mCompleteEconomicPolicy.getHardSatiatedConsumptionLimit()) {
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
index 99b93ce..948f0a7 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
@@ -16,48 +16,48 @@
 
 package com.android.server.tare;
 
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_HARD_CONSUMPTION_LIMIT;
-import static android.app.tare.EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT;
-import static android.app.tare.EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE;
-import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED;
-import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_HARD_CONSUMPTION_LIMIT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES;
 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE;
 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP;
 import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE;
@@ -106,12 +106,12 @@
 import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
 import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
 import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
-import static com.android.server.tare.TareUtils.arcToCake;
 import static com.android.server.tare.TareUtils.cakeToString;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ContentResolver;
+import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.util.IndentingPrintWriter;
 import android.util.KeyValueListParser;
@@ -159,14 +159,15 @@
     JobSchedulerEconomicPolicy(InternalResourceService irs) {
         super(irs);
         mInternalResourceService = irs;
-        loadConstants("");
+        loadConstants("", null);
     }
 
     @Override
-    void setup() {
-        super.setup();
+    void setup(@NonNull DeviceConfig.Properties properties) {
+        super.setup(properties);
         ContentResolver resolver = mInternalResourceService.getContext().getContentResolver();
-        loadConstants(Settings.Global.getString(resolver, TARE_JOB_SCHEDULER_CONSTANTS));
+        loadConstants(Settings.Global.getString(resolver, TARE_JOB_SCHEDULER_CONSTANTS),
+                properties);
     }
 
     @Override
@@ -211,7 +212,8 @@
         return mRewards.get(rewardId);
     }
 
-    private void loadConstants(String policyValuesString) {
+    private void loadConstants(String policyValuesString,
+            @Nullable DeviceConfig.Properties properties) {
         mActions.clear();
         mRewards.clear();
 
@@ -221,118 +223,153 @@
             Slog.e(TAG, "Global setting key incorrect: ", e);
         }
 
-        mMinSatiatedBalanceExempted = arcToCake(
-                mParser.getInt(KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
-                        DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED));
-        mMinSatiatedBalanceOther = arcToCake(
-                mParser.getInt(KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP,
-                        DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP));
-        mMaxSatiatedBalance = arcToCake(mParser.getInt(KEY_JS_MAX_SATIATED_BALANCE,
-                DEFAULT_JS_MAX_SATIATED_BALANCE));
-        mInitialSatiatedConsumptionLimit = arcToCake(mParser.getInt(
-                KEY_JS_INITIAL_CONSUMPTION_LIMIT, DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT));
+        mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
+                KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
+                DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES);
+        mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
+                KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP,
+                DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
+        mMaxSatiatedBalance = getConstantAsCake(mParser, properties,
+                KEY_JS_MAX_SATIATED_BALANCE,
+                DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES);
+        mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+                KEY_JS_INITIAL_CONSUMPTION_LIMIT,
+                DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES);
         mHardSatiatedConsumptionLimit = Math.max(mInitialSatiatedConsumptionLimit,
-                arcToCake(mParser.getInt(
-                        KEY_JS_HARD_CONSUMPTION_LIMIT, DEFAULT_JS_HARD_CONSUMPTION_LIMIT)));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_HARD_CONSUMPTION_LIMIT,
+                        DEFAULT_JS_HARD_CONSUMPTION_LIMIT_CAKES));
 
         mActions.put(ACTION_JOB_MAX_START, new Action(ACTION_JOB_MAX_START,
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_START_CTP,
-                        DEFAULT_JS_ACTION_JOB_MAX_START_CTP)),
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_MAX_START_CTP,
+                        DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
+                        DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_MAX_RUNNING, new Action(ACTION_JOB_MAX_RUNNING,
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
-                        DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP)),
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
+                        DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
+                        DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_HIGH_START, new Action(ACTION_JOB_HIGH_START,
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_START_CTP,
-                        DEFAULT_JS_ACTION_JOB_HIGH_START_CTP)),
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_HIGH_START_CTP,
+                        DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
+                        DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_HIGH_RUNNING, new Action(ACTION_JOB_HIGH_RUNNING,
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
-                        DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP)),
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
+                        DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
+                        DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_DEFAULT_START, new Action(ACTION_JOB_DEFAULT_START,
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
-                        DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP)),
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
+                        DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
+                        DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_DEFAULT_RUNNING, new Action(ACTION_JOB_DEFAULT_RUNNING,
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
-                        DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP)),
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
+                        DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
+                        DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_LOW_START, new Action(ACTION_JOB_LOW_START,
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_START_CTP,
-                        DEFAULT_JS_ACTION_JOB_LOW_START_CTP)),
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_LOW_START_CTP,
+                        DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
+                        DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_LOW_RUNNING, new Action(ACTION_JOB_LOW_RUNNING,
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
-                        DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP)),
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
+                        DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
+                        DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_MIN_START, new Action(ACTION_JOB_MIN_START,
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_START_CTP,
-                        DEFAULT_JS_ACTION_JOB_MIN_START_CTP)),
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_MIN_START_CTP,
+                        DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
+                        DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_MIN_RUNNING, new Action(ACTION_JOB_MIN_RUNNING,
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
-                        DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP)),
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
+                        DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
+                        DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_TIMEOUT, new Action(ACTION_JOB_TIMEOUT,
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
-                        DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP)),
-                arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
+                        DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
+                        DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES)));
 
         mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
-                arcToCake(mParser.getInt(KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
-                        DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT)),
-                (long) (arcToCake(1) * mParser.getFloat(KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
-                        DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING)),
-                arcToCake(mParser.getInt(KEY_JS_REWARD_TOP_ACTIVITY_MAX,
-                        DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
+                        DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
+                        DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_REWARD_TOP_ACTIVITY_MAX,
+                        DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES)));
         mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
-                arcToCake(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
-                        DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT)),
-                arcToCake(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
-                        DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING)),
-                arcToCake(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
-                        DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
+                        DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
+                        DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
+                        DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES)));
         mRewards.put(REWARD_NOTIFICATION_INTERACTION,
                 new Reward(REWARD_NOTIFICATION_INTERACTION,
-                        arcToCake(mParser.getInt(
+                        getConstantAsCake(mParser, properties,
                                 KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT,
-                                DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT)),
-                        arcToCake(mParser.getInt(
+                                DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING,
-                                DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING)),
-                        arcToCake(mParser.getInt(
+                                DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX,
-                                DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX))));
+                                DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
         mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
-                arcToCake(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
-                        DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT)),
-                arcToCake(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
-                        DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING)),
-                arcToCake(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
-                        DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX))));
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
+                        DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
+                        DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES),
+                getConstantAsCake(mParser, properties,
+                        KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
+                        DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES)));
         mRewards.put(REWARD_OTHER_USER_INTERACTION,
                 new Reward(REWARD_OTHER_USER_INTERACTION,
-                        arcToCake(mParser.getInt(KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
-                                DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT)),
-                        arcToCake(mParser.getInt(
+                        getConstantAsCake(mParser, properties,
+                                KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
+                                DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING,
-                                DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING)),
-                        arcToCake(mParser.getInt(
+                                DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES),
+                        getConstantAsCake(mParser, properties,
                                 KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX,
-                                DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX))));
+                                DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
     }
 
     @Override
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/README.md b/apex/jobscheduler/service/java/com/android/server/tare/README.md
index 72d5069..e338ed1 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/README.md
+++ b/apex/jobscheduler/service/java/com/android/server/tare/README.md
@@ -18,16 +18,17 @@
 In an ideal world, the system could be said to most efficiently allocate resources by maximizing its
 profits &mdash; by maximizing the aggregate sum of the difference between an action's price (that
 the app ends up paying) and the cost to produce by the system. This assumes that more important
-actions have a higher price than less important actions. With this assumption, maximizing profits
-implies that the system runs the most important work first and proceeds in decreasing order of
-importance. Of course, that also means the system will not run anything where an app would pay less
-for the action than the system's cost to produce that action. Some of this breaks down when we throw
-TOP apps into the mix &mdash; TOP apps pay 0 for all actions, even though the CTP may be greater
-than 0. This is to ensure ideal user experience for the app the user is actively interacting with.
-Similar caveats exist for system-critical processes (such as the OS itself) and apps running
-foreground services (since those could be critical to user experience, as is the case for media and
-navigation apps). Excluding those caveats/special situations, maximizing profits of actions
-performed by apps in the background should be the target.
+actions have a higher price than less important actions and all actors have perfect information and
+convey that information accurately. With these assumptions, maximizing profits implies that the
+system runs the most important work first and proceeds in decreasing order of importance. Of course,
+that also means the system will not run anything where an app would pay less for the action than the
+system's cost to produce that action. Some of this breaks down when we throw TOP apps into the mix
+&mdash; TOP apps pay 0 for all actions, even though the CTP may be greater than 0. This is to ensure
+ideal user experience for the app the user is actively interacting with. Similar caveats exist for
+system-critical processes (such as the OS itself) and apps running foreground services (since those
+could be critical to user experience, as is the case for media and navigation apps). Excluding those
+caveats/special situations, maximizing profits of actions performed by apps in the background should
+be the target.
 
 To achieve the goal laid out by TARE, we use Android Resource Credits (ARCs for short) as the
 internal/representative currency of the system.
@@ -101,11 +102,37 @@
 allowed apps to accrue credits as appropriate while still limiting the total number of credits
 consumed.
 
+# Potential Future Changes
+
+These are some ideas for further changes. There's no guarantee that they'll be implemented.
+
+* Include additional components and policies for them. TARE may benefit from adding policies for
+  components such as broadcast dispatching, network traffic, location requests, and sensor usage.
+* Have a separate "account" for critical/special actions. In other words, have two accounts for each
+  app, where one acts like a special savings account and is only allowed to be used for special
+  actions such as expedited job execution. The second account would have a lower maximum than the
+  main account, but would help to make sure that normal actions don't interfere too much with more
+  critical actions.
+* Transferring credits from one app to another. For apps that rely on others for some pieces of
+  work, it may be beneficial to allow the requesting app to transfer, donate, or somehow make
+  available some of its own credits to the app doing the work in order to make sure the working app
+  has enough credits available to do the work.
+* Formulate values based on device hardware. For example, adjust the consumption limit based on the
+  battery size, or the price and/or CTP of actions based on hardware efficiency.
+* Price discovery via an auction system. Instead of just setting a fixed price that may be modified
+  by device and app states, let an app say how much it's willing to pay for a specific action and
+  then have a small auction when the system needs to decide which app to perform the action for
+  first or how much to charge the app.
+
 # Definitions
 
 * ARC: Android Resource Credits are the "currency" units used as an abstraction layer over the real
   battery drain. They allow the system to standardize costs and prices across various devices.
 * Cake: A lie; also the smallest unit of an ARC (1 cake = one-billionth of an ARC = 1 nano-ARC).
   When the apps request to do something, we shall let them eat cake.
-* NARC: The smallest unit of an ARC. A narc is 1 nano-ARC.
+* Cost to produce (CTP): An economic term that refers to the total cost incurred by a business to
+  produce a specific quantity of a product or offer a service. In TARE's context, CTP is meant to be
+  the estimated cost t ohe system to accomplish a certain action. These "actions" are basically APIs
+  that apps use to get something done. So the idea is to define the base cost for an app to use a
+  specific API.
 * Satiated: used to refer to when the device is fully charged (at 100% battery level)
\ No newline at end of file
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java b/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
index 87db863..6b6984f 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.server.tare;
 
+import static android.app.tare.EconomyManager.CAKE_IN_ARC;
+
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.util.IndentingPrintWriter;
@@ -26,8 +28,6 @@
 import java.time.Clock;
 
 class TareUtils {
-    private static final long CAKE_IN_ARC = 1_000_000_000L;
-
     @SuppressLint("SimpleDateFormat")
     private static final SimpleDateFormat sDumpDateFormat =
             new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
@@ -35,10 +35,6 @@
     @VisibleForTesting
     static Clock sSystemClock = Clock.systemUTC();
 
-    static long arcToCake(int arcs) {
-        return arcs * CAKE_IN_ARC;
-    }
-
     static void dumpTime(IndentingPrintWriter pw, long time) {
         pw.print(sDumpDateFormat.format(time));
     }
@@ -56,7 +52,7 @@
         if (cakes == 0) {
             return "0 ARCs";
         }
-        final long sub = Math.abs(cakes) % CAKE_IN_ARC;
+        final long sub = cakes % CAKE_IN_ARC;
         final long arcs = cakeToArc(cakes);
         if (arcs == 0) {
             return sub == 1
@@ -65,11 +61,11 @@
         }
         StringBuilder sb = new StringBuilder();
         sb.append(arcs);
-        if (sub > 0) {
-            sb.append(".").append(sub / (CAKE_IN_ARC / 1000));
+        if (sub != 0) {
+            sb.append(".").append(String.format("%03d", Math.abs(sub) / (CAKE_IN_ARC / 1000)));
         }
         sb.append(" ARC");
-        if (arcs != 1 || sub > 0) {
+        if (arcs != 1 || sub != 0) {
             sb.append("s");
         }
         return sb.toString();
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index fb68c6d..50c8e93 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -1459,6 +1459,8 @@
 
     int fadedFramesCount = 0;
     int lastDisplayedProgress = 0;
+    int colorTransitionStart = animation.colorTransitionStart;
+    int colorTransitionEnd = animation.colorTransitionEnd;
     for (size_t i=0 ; i<pcount ; i++) {
         const Animation::Part& part(animation.parts[i]);
         const size_t fcount = part.frames.size();
@@ -1471,15 +1473,27 @@
             continue; //to next part
         }
 
-        if (animation.dynamicColoringEnabled && part.useDynamicColoring && !mDynamicColorsApplied) {
-            SLOGD("Trying to load dynamic color sysprops.");
-            initDynamicColors();
-        }
-
         // process the part not only while the count allows but also if already fading
         for (int r=0 ; !part.count || r<part.count || fadedFramesCount > 0 ; r++) {
             if (shouldStopPlayingPart(part, fadedFramesCount, lastDisplayedProgress)) break;
 
+            // It's possible that the sysprops were not loaded yet at this boot phase.
+            // If that's the case, then we should keep trying until they are available.
+            if (animation.dynamicColoringEnabled && !mDynamicColorsApplied
+                && (part.useDynamicColoring || part.postDynamicColoring)) {
+                SLOGD("Trying to load dynamic color sysprops.");
+                initDynamicColors();
+                if (mDynamicColorsApplied) {
+                    // Sysprops were loaded. Next step is to adjust the animation if we loaded
+                    // the colors after the animation should have started.
+                    const int transitionLength = colorTransitionEnd - colorTransitionStart;
+                    if (part.postDynamicColoring) {
+                        colorTransitionStart = 0;
+                        colorTransitionEnd = fmin(transitionLength, fcount - 1);
+                    }
+                }
+            }
+
             mCallbacks->playPart(i, part, r);
 
             glClearColor(
@@ -1509,9 +1523,8 @@
                 // - 1 for parts that come after.
                 float colorProgress = part.useDynamicColoring
                     ? fmin(fmax(
-                        ((float)j - animation.colorTransitionStart) /
-                            fmax(animation.colorTransitionEnd -
-                                animation.colorTransitionStart, 1.0f), 0.0f), 1.0f)
+                        ((float)j - colorTransitionStart) /
+                            fmax(colorTransitionEnd - colorTransitionStart, 1.0f), 0.0f), 1.0f)
                     : (part.postDynamicColoring ? 1 : 0);
 
                 processDisplayEvents();
diff --git a/core/api/module-lib-lint-baseline.txt b/core/api/module-lib-lint-baseline.txt
index 0c1ebb3..27436ce 100644
--- a/core/api/module-lib-lint-baseline.txt
+++ b/core/api/module-lib-lint-baseline.txt
@@ -1,4 +1,6 @@
 // Baseline format: 1.0
+SamShouldBeLast: android.app.Activity#convertToTranslucent(android.app.Activity.TranslucentConversionListener, android.app.ActivityOptions):
+    SAM-compatible parameters (such as parameter 1, "callback", in android.app.Activity.convertToTranslucent) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int):
     SAM-compatible parameters (such as parameter 1, "listener", in android.app.ActivityManager.addOnUidImportanceListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.PendingIntent#send(android.content.Context, int, android.content.Intent, android.app.PendingIntent.OnFinished, android.os.Handler):
@@ -9,6 +11,24 @@
     SAM-compatible parameters (such as parameter 4, "onFinished", in android.app.PendingIntent.send) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.PendingIntent#send(int, android.app.PendingIntent.OnFinished, android.os.Handler):
     SAM-compatible parameters (such as parameter 2, "onFinished", in android.app.PendingIntent.send) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.content.pm.ApplicationInfo#dump(android.util.Printer, String):
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.ApplicationInfo.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.content.pm.PackageItemInfo#dumpBack(android.util.Printer, String):
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.PackageItemInfo.dumpBack) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.content.pm.PackageItemInfo#dumpFront(android.util.Printer, String):
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.PackageItemInfo.dumpFront) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler):
+    SAM-compatible parameters (such as parameter 1, "listener", in android.location.LocationManager.addNmeaListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, android.location.LocationListener, android.os.Looper):
+    SAM-compatible parameters (such as parameter 4, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper):
+    SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper):
+    SAM-compatible parameters (such as parameter 4, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(String, android.location.LocationListener, android.os.Looper):
+    SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper):
+    SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioManager#abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes):
     SAM-compatible parameters (such as parameter 1, "l", in android.media.AudioManager.abandonAudioFocus) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioManager#requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int):
diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index 1b45e88..025e862 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -1,36 +1,20 @@
 // Baseline format: 1.0
 ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
-
-ExecutorRegistration: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler):
-    Registration methods should have overload that accepts delivery Executor: `setOnRtpRxNoticeListener`
+    Method should return Collection<CharSequence> (or subclass) instead of raw array; was `java.lang.CharSequence[]`
 
 
 GenericException: android.app.prediction.AppPredictor#finalize():
-    
+    Methods must not throw generic exceptions (`java.lang.Throwable`)
 GenericException: android.hardware.location.ContextHubClient#finalize():
-    
+    Methods must not throw generic exceptions (`java.lang.Throwable`)
 GenericException: android.service.autofill.augmented.FillWindow#finalize():
-    
-
-
-IntentBuilderName: android.app.search.SearchAction#getIntent():
-    
-IntentBuilderName: android.app.smartspace.SmartspaceAction#getIntent():
-    Methods creating an Intent should be named `create<Foo>Intent()`, was `getIntent`
+    Methods must not throw generic exceptions (`java.lang.Throwable`)
 
 
 KotlinKeyword: android.app.Notification#when:
-    
+    Avoid field names that are Kotlin hard keywords ("when"); see https://android.github.io/kotlin-guides/interop.html#no-hard-keywords
 
 
-MissingGetterMatchingBuilder: android.os.NewUserRequest.Builder#setAdmin():
-    android.os.NewUserRequest does not declare a `getAdmin()` method matching method android.os.NewUserRequest.Builder.setAdmin()
-MissingGetterMatchingBuilder: android.os.NewUserRequest.Builder#setEphemeral():
-    android.os.NewUserRequest does not declare a `getEphemeral()` method matching method android.os.NewUserRequest.Builder.setEphemeral()
-MissingGetterMatchingBuilder: android.security.keystore.KeyGenParameterSpec.Builder#setUid(int):
-    android.security.keystore.KeyGenParameterSpec does not declare a `getUid()` method matching method android.security.keystore.KeyGenParameterSpec.Builder.setUid(int)
-MissingGetterMatchingBuilder: android.service.autofill.Dataset.Builder#setFieldInlinePresentation(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, java.util.regex.Pattern, android.service.autofill.InlinePresentation):
-    android.service.autofill.Dataset does not declare a `getFieldInlinePresentation()` method matching method android.service.autofill.Dataset.Builder.setFieldInlinePresentation(android.view.autofill.AutofillId,android.view.autofill.AutofillValue,java.util.regex.Pattern,android.service.autofill.InlinePresentation)
 MissingGetterMatchingBuilder: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallViaAudioProcessing(boolean):
     android.telecom.CallScreeningService.CallResponse does not declare a `shouldScreenCallViaAudioProcessing()` method matching method android.telecom.CallScreeningService.CallResponse.Builder.setShouldScreenCallViaAudioProcessing(boolean)
 MissingGetterMatchingBuilder: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
@@ -38,175 +22,135 @@
 
 
 MissingNullability: android.media.soundtrigger.SoundTriggerDetectionService#onUnbind(android.content.Intent) parameter #0:
-    
+    Missing nullability on parameter `intent` in method `onUnbind`
 MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #0:
-    
+    Missing nullability on parameter `inputId` in method `onEvent`
 MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #1:
-    
+    Missing nullability on parameter `eventType` in method `onEvent`
 MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #2:
-    
+    Missing nullability on parameter `eventArgs` in method `onEvent`
 MissingNullability: android.printservice.recommendation.RecommendationService#attachBaseContext(android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `base` in method `attachBaseContext`
 MissingNullability: android.provider.ContactsContract.MetadataSync#CONTENT_URI:
-    
+    Missing nullability on field `CONTENT_URI` in class `class android.provider.ContactsContract.MetadataSync`
 MissingNullability: android.provider.ContactsContract.MetadataSync#METADATA_AUTHORITY_URI:
-    
+    Missing nullability on field `METADATA_AUTHORITY_URI` in class `class android.provider.ContactsContract.MetadataSync`
 MissingNullability: android.provider.ContactsContract.MetadataSyncState#CONTENT_URI:
-    
+    Missing nullability on field `CONTENT_URI` in class `class android.provider.ContactsContract.MetadataSyncState`
 MissingNullability: android.provider.SearchIndexablesProvider#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #0:
-    
+    Missing nullability on parameter `context` in method `attachInfo`
 MissingNullability: android.provider.SearchIndexablesProvider#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #1:
-    
+    Missing nullability on parameter `info` in method `attachInfo`
 MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#onUnbind(android.content.Intent) parameter #0:
-    
+    Missing nullability on parameter `intent` in method `onUnbind`
 MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
-    
+    Missing nullability on parameter `fd` in method `dump`
 MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
-    
+    Missing nullability on parameter `pw` in method `dump`
 MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
-    
+    Missing nullability on parameter `args` in method `dump`
 MissingNullability: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `base` in method `attachBaseContext`
 MissingNullability: android.telephony.NetworkService#onUnbind(android.content.Intent) parameter #0:
-    
-MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringDaily(java.time.ZonedDateTime) parameter #0:
-    
-MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringMonthly(java.time.ZonedDateTime) parameter #0:
-    
-MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringWeekly(java.time.ZonedDateTime) parameter #0:
-    
+    Missing nullability on parameter `intent` in method `onUnbind`
 MissingNullability: android.telephony.data.DataService#onUnbind(android.content.Intent) parameter #0:
-    
+    Missing nullability on parameter `intent` in method `onUnbind`
 MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
-    
+    Missing nullability on method `setServiceId` return
 MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String) parameter #0:
-    
-
-
-NoSettingsProvider: android.provider.Settings.Secure#FAST_PAIR_SCAN_ENABLED:
-    New setting keys are not allowed (Field: FAST_PAIR_SCAN_ENABLED); use getters/setters in relevant manager class
-
-
-OnNameExpected: android.service.smartspace.SmartspaceService#notifySmartspaceEvent(android.app.smartspace.SmartspaceSessionId, android.app.smartspace.SmartspaceTargetEvent):
-    Methods implemented by developers should follow the on<Something> style, was `notifySmartspaceEvent`
+    Missing nullability on parameter `serviceId` in method `setServiceId`
 
 
 ProtectedMember: android.printservice.recommendation.RecommendationService#attachBaseContext(android.content.Context):
-    
+    Protected methods not allowed; must be public: method android.printservice.recommendation.RecommendationService.attachBaseContext(android.content.Context)}
 ProtectedMember: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
-    
+    Protected methods not allowed; must be public: method android.service.contentcapture.ContentCaptureService.dump(java.io.FileDescriptor,java.io.PrintWriter,String[])}
 ProtectedMember: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context):
-    
-
-
-RethrowRemoteException: android.app.WallpaperManager#getWallpaperDimAmount():
-    Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
-RethrowRemoteException: android.app.WallpaperManager#getWallpaperDimmingAmount():
-    Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
-RethrowRemoteException: android.app.WallpaperManager#setWallpaperDimAmount(float):
-    Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
-RethrowRemoteException: android.app.WallpaperManager#setWallpaperDimmingAmount(float):
-    Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
+    Protected methods not allowed; must be public: method android.service.notification.NotificationAssistantService.attachBaseContext(android.content.Context)}
 
 
 SamShouldBeLast: android.accounts.AccountManager#addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 6, "callback", in android.accounts.AccountManager.addAccount) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.accounts.AccountManager.addOnAccountsUpdatedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, String[]):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.accounts.AccountManager.addOnAccountsUpdatedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#confirmCredentials(android.accounts.Account, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 4, "callback", in android.accounts.AccountManager.confirmCredentials) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#editProperties(String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.editProperties) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.finishSession) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#getAccountsByTypeAndFeatures(String, String[], android.accounts.AccountManagerCallback<android.accounts.Account[]>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.getAccountsByTypeAndFeatures) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#getAuthToken(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 5, "callback", in android.accounts.AccountManager.getAuthToken) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#getAuthToken(android.accounts.Account, String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 5, "callback", in android.accounts.AccountManager.getAuthToken) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#getAuthToken(android.accounts.Account, String, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 4, "callback", in android.accounts.AccountManager.getAuthToken) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#getAuthTokenByFeatures(String, String, String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 7, "callback", in android.accounts.AccountManager.getAuthTokenByFeatures) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#hasFeatures(android.accounts.Account, String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.hasFeatures) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#isCredentialsUpdateSuggested(android.accounts.Account, String, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.isCredentialsUpdateSuggested) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 2, "callback", in android.accounts.AccountManager.removeAccount) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#removeAccount(android.accounts.Account, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.removeAccount) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#renameAccount(android.accounts.Account, String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.accounts.AccountManager.renameAccount) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#startAddAccountSession(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 6, "callback", in android.accounts.AccountManager.startAddAccountSession) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#startUpdateCredentialsSession(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 5, "callback", in android.accounts.AccountManager.startUpdateCredentialsSession) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.accounts.AccountManager#updateCredentials(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 5, "callback", in android.accounts.AccountManager.updateCredentials) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.AlarmManager#set(int, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 4, "listener", in android.app.AlarmManager.set) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.AlarmManager#setExact(int, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 4, "listener", in android.app.AlarmManager.setExact) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.AlarmManager#setWindow(int, long, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 5, "listener", in android.app.AlarmManager.setWindow) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.WallpaperInfo#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.app.WallpaperInfo.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.app.WallpaperManager#addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener, android.os.Handler):
-    
-SamShouldBeLast: android.app.admin.DevicePolicyManager#installSystemUpdate(android.content.ComponentName, android.net.Uri, java.util.concurrent.Executor, android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.app.WallpaperManager.addOnColorsChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.content.IntentFilter#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "du", in android.content.IntentFilter.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.content.pm.ApplicationInfo#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.ApplicationInfo.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.content.pm.PackageItemInfo#dumpBack(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.PackageItemInfo.dumpBack) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.content.pm.PackageItemInfo#dumpFront(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.PackageItemInfo.dumpFront) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.content.pm.ResolveInfo#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.ResolveInfo.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.Location#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.location.Location.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.LocationManager#addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler):
-    
-SamShouldBeLast: android.location.LocationManager#registerGnssMeasurementsCallback(java.util.concurrent.Executor, android.location.GnssMeasurementsEvent.Callback):
-    
-SamShouldBeLast: android.location.LocationManager#registerGnssNavigationMessageCallback(java.util.concurrent.Executor, android.location.GnssNavigationMessage.Callback):
-    
-SamShouldBeLast: android.location.LocationManager#registerGnssStatusCallback(java.util.concurrent.Executor, android.location.GnssStatus.Callback):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.location.LocationManager.addNmeaListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, android.location.LocationListener, android.os.Looper):
-    
-SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, java.util.concurrent.Executor, android.location.LocationListener):
-    
-SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, java.util.concurrent.Executor, android.location.LocationListener):
-    
+    SAM-compatible parameters (such as parameter 4, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper):
-    
-SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, java.util.concurrent.Executor, android.location.LocationListener):
-    
+    SAM-compatible parameters (such as parameter 4, "listener", in android.location.LocationManager.requestLocationUpdates) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(String, android.location.LocationListener, android.os.Looper):
-    
+    SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper):
-    
+    SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioFocusRequest.Builder#setOnAudioFocusChangeListener(android.media.AudioManager.OnAudioFocusChangeListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioFocusRequest.Builder.setOnAudioFocusChangeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioManager#requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int):
-    
+    SAM-compatible parameters (such as parameter 1, "l", in android.media.AudioManager.requestAudioFocus) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioRecord#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
-    
-SamShouldBeLast: android.media.AudioRecord#registerAudioRecordingCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioRecordingCallback):
-    
-SamShouldBeLast: android.media.AudioRecordingMonitor#registerAudioRecordingCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioRecordingCallback):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioRecord.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioRouting#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioRouting.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.AudioTrack#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioTrack.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.media.MediaCodec#setOnFrameRenderedListener(android.media.MediaCodec.OnFrameRenderedListener, android.os.Handler):
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaCodec.setOnFrameRenderedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.MediaPlayer#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
     SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaPlayer.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.MediaPlayer#setOnDrmInfoListener(android.media.MediaPlayer.OnDrmInfoListener, android.os.Handler):
@@ -215,82 +159,65 @@
     SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaPlayer.setOnDrmPreparedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.MediaPlayer#setOnMediaTimeDiscontinuityListener(android.media.MediaPlayer.OnMediaTimeDiscontinuityListener, android.os.Handler):
     SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaPlayer.setOnMediaTimeDiscontinuityListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
-SamShouldBeLast: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler):
-    SAM-compatible parameters (such as parameter 2, "listener", in android.media.MediaPlayer.setOnRtpRxNoticeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.MediaPlayer#setOnSubtitleDataListener(android.media.MediaPlayer.OnSubtitleDataListener, android.os.Handler):
     SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaPlayer.setOnSubtitleDataListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.MediaRecorder#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
-    
-SamShouldBeLast: android.media.MediaRecorder#registerAudioRecordingCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioRecordingCallback):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaRecorder.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.session.MediaSessionManager#addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName):
-    
+    SAM-compatible parameters (such as parameter 1, "sessionListener", in android.media.session.MediaSessionManager.addOnActiveSessionsChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.session.MediaSessionManager#addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "sessionListener", in android.media.session.MediaSessionManager.addOnActiveSessionsChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.session.MediaSessionManager#addOnSession2TokensChangedListener(android.media.session.MediaSessionManager.OnSession2TokensChangedListener, android.os.Handler):
-    
-SamShouldBeLast: android.media.session.MediaSessionManager#registerCallback(java.util.concurrent.Executor, android.media.session.MediaSessionManager.Callback):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.media.session.MediaSessionManager.addOnSession2TokensChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.nfc.NfcAdapter#enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle):
-    
+    SAM-compatible parameters (such as parameter 2, "callback", in android.nfc.NfcAdapter.enableReaderMode) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.nfc.NfcAdapter#ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "tagRemovedListener", in android.nfc.NfcAdapter.ignore) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.nfc.NfcAdapter#setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity):
-    
+    SAM-compatible parameters (such as parameter 1, "callback", in android.nfc.NfcAdapter.setBeamPushUrisCallback) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.nfc.NfcAdapter#setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...):
-    
+    SAM-compatible parameters (such as parameter 1, "callback", in android.nfc.NfcAdapter.setNdefPushMessageCallback) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.nfc.NfcAdapter#setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...):
-    
+    SAM-compatible parameters (such as parameter 1, "callback", in android.nfc.NfcAdapter.setOnNdefPushCompleteCallback) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Binder#attachInterface(android.os.IInterface, String):
-    
+    SAM-compatible parameters (such as parameter 1, "owner", in android.os.Binder.attachInterface) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Binder#linkToDeath(android.os.IBinder.DeathRecipient, int):
-    
+    SAM-compatible parameters (such as parameter 1, "recipient", in android.os.Binder.linkToDeath) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Binder#unlinkToDeath(android.os.IBinder.DeathRecipient, int):
-    
+    SAM-compatible parameters (such as parameter 1, "recipient", in android.os.Binder.unlinkToDeath) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.os.Handler.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#postAtTime(Runnable, Object, long):
-    
+    SAM-compatible parameters (such as parameter 1, "r", in android.os.Handler.postAtTime) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#postAtTime(Runnable, long):
-    
+    SAM-compatible parameters (such as parameter 1, "r", in android.os.Handler.postAtTime) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#postDelayed(Runnable, Object, long):
-    
+    SAM-compatible parameters (such as parameter 1, "r", in android.os.Handler.postDelayed) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#postDelayed(Runnable, long):
-    
+    SAM-compatible parameters (such as parameter 1, "r", in android.os.Handler.postDelayed) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.Handler#removeCallbacks(Runnable, Object):
-    
+    SAM-compatible parameters (such as parameter 1, "r", in android.os.Handler.removeCallbacks) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.IBinder#linkToDeath(android.os.IBinder.DeathRecipient, int):
-    
+    SAM-compatible parameters (such as parameter 1, "recipient", in android.os.IBinder.linkToDeath) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.IBinder#unlinkToDeath(android.os.IBinder.DeathRecipient, int):
-    
+    SAM-compatible parameters (such as parameter 1, "recipient", in android.os.IBinder.unlinkToDeath) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.RecoverySystem#verifyPackage(java.io.File, android.os.RecoverySystem.ProgressListener, java.io.File):
-    
+    SAM-compatible parameters (such as parameter 2, "listener", in android.os.RecoverySystem.verifyPackage) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, String[], java.security.Principal[], String, int, String):
     SAM-compatible parameters (such as parameter 2, "response", in android.security.KeyChain.choosePrivateKeyAlias) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, String[], java.security.Principal[], android.net.Uri, String):
     SAM-compatible parameters (such as parameter 2, "response", in android.security.KeyChain.choosePrivateKeyAlias) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.View#postDelayed(Runnable, long):
-    
+    SAM-compatible parameters (such as parameter 1, "action", in android.view.View.postDelayed) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.View#postOnAnimationDelayed(Runnable, long):
-    
+    SAM-compatible parameters (such as parameter 1, "action", in android.view.View.postOnAnimationDelayed) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.View#scheduleDrawable(android.graphics.drawable.Drawable, Runnable, long):
-    
+    SAM-compatible parameters (such as parameter 2, "what", in android.view.View.scheduleDrawable) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.Window#addOnFrameMetricsAvailableListener(android.view.Window.OnFrameMetricsAvailableListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.view.Window.addOnFrameMetricsAvailableListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.accessibility.AccessibilityManager#addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.view.accessibility.AccessibilityManager.addAccessibilityStateChangeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.accessibility.AccessibilityManager#addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 1, "listener", in android.view.accessibility.AccessibilityManager.addTouchExplorationStateChangeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.webkit.WebChromeClient#onShowFileChooser(android.webkit.WebView, android.webkit.ValueCallback<android.net.Uri[]>, android.webkit.WebChromeClient.FileChooserParams):
-    
-
-
-ServiceName: android.content.Context#CLOUDSEARCH_SERVICE:
-
-
-UserHandleName: android.app.search.SearchAction.Builder#setUserHandle(android.os.UserHandle):
-    Method taking UserHandle should be named `doFooAsUser` or `queryFooForUser`, was `setUserHandle`
-UserHandleName: android.app.search.SearchTarget.Builder#setUserHandle(android.os.UserHandle):
-    
-UserHandleName: android.app.smartspace.SmartspaceAction.Builder#setUserHandle(android.os.UserHandle):
-    Method taking UserHandle should be named `doFooAsUser` or `queryFooForUser`, was `setUserHandle`
+    SAM-compatible parameters (such as parameter 2, "filePathCallback", in android.webkit.WebChromeClient.onShowFileChooser) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 31a0818..67599b4 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -168,11 +168,11 @@
   }
 
   public static interface ActivityOptions.OnAnimationFinishedListener {
-    method public void onAnimationFinished();
+    method public void onAnimationFinished(long);
   }
 
   public static interface ActivityOptions.OnAnimationStartedListener {
-    method public void onAnimationStarted();
+    method public void onAnimationStarted(long);
   }
 
   public class ActivityTaskManager {
@@ -464,6 +464,7 @@
     method @NonNull public android.graphics.Rect getMaxBounds();
     method public int getRotation();
     method public int getWindowingMode();
+    method public static boolean isFloating(int);
     method public void setActivityType(int);
     method public void setAppBounds(android.graphics.Rect);
     method public void setBounds(android.graphics.Rect);
diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
index 01604e6..0a906be 100644
--- a/core/api/test-lint-baseline.txt
+++ b/core/api/test-lint-baseline.txt
@@ -1,920 +1,270 @@
 // Baseline format: 1.0
 AcronymName: android.app.NotificationChannel#isImportanceLockedByOEM():
-    
+    Acronyms should not be capitalized in method names: was `isImportanceLockedByOEM`, should this be `isImportanceLockedByOem`?
 AcronymName: android.app.NotificationChannel#setImportanceLockedByOEM(boolean):
-    
+    Acronyms should not be capitalized in method names: was `setImportanceLockedByOEM`, should this be `setImportanceLockedByOem`?
 
 
-ActionValue: android.location.Location#EXTRA_NO_GPS_LOCATION:
-    
-ActionValue: android.net.TetheringManager#ACTION_TETHER_STATE_CHANGED:
-    
-ActionValue: android.net.TetheringManager#EXTRA_ACTIVE_TETHER:
-    
-ActionValue: android.net.TetheringManager#EXTRA_AVAILABLE_TETHER:
-    
-ActionValue: android.net.TetheringManager#EXTRA_ERRORED_TETHER:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_ADDITIONAL_CALL_INFO:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CALL_RAT_TYPE:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CHILD_NUMBER:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CNA:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CNAP:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CODEC:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_DIALSTRING:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_DISPLAY_TEXT:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_EMERGENCY_CALL:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_IS_CALL_PULL:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_OI:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_OIR:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_REMOTE_URI:
-    
-ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_USSD:
-    
-ActionValue: android.telephony.ims.ImsReasonInfo#EXTRA_MSG_SERVICE_NOT_AUTHORIZED:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_CLEANUP:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_DOWNLOAD_RESULT_INTERNAL:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_FILE_DESCRIPTOR_REQUEST:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_FD_COUNT:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_FINAL_URI:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_FREE_URI_LIST:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_PAUSED_LIST:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_PAUSED_URI_LIST:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_SERVICE_ID:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_TEMP_FILES_IN_USE:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_TEMP_FILE_ROOT:
-    
-ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_TEMP_LIST:
-    
-
-
-AllUpper: android.media.audiopolicy.AudioProductStrategy#sDefaultAttributes:
-    Constant field names must be named with only upper case characters: `android.media.audiopolicy.AudioProductStrategy#sDefaultAttributes`, should be `S_DEFAULT_ATTRIBUTES`?
-
-
-ArrayReturn: android.app.UiAutomation#executeShellCommandRw(String):
-    
-ArrayReturn: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#KeyphraseSoundModel(java.util.UUID, java.util.UUID, byte[], android.hardware.soundtrigger.SoundTrigger.Keyphrase[]) parameter #3:
-    
-ArrayReturn: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#KeyphraseSoundModel(java.util.UUID, java.util.UUID, byte[], android.hardware.soundtrigger.SoundTrigger.Keyphrase[], int) parameter #3:
-    
-ArrayReturn: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#getKeyphrases():
-    
-ArrayReturn: android.location.GnssMeasurementsEvent#GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]) parameter #1:
-    
 ArrayReturn: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #10:
-    
+    Method parameter should be Collection<Descriptor> (or subclass) instead of raw array; was `android.media.audiofx.AudioEffect.Descriptor[]`
 ArrayReturn: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #11:
-    
-ArrayReturn: android.metrics.LogMaker#LogMaker(Object[]) parameter #0:
-    
-ArrayReturn: android.metrics.LogMaker#deserialize(Object[]) parameter #0:
-    
-ArrayReturn: android.metrics.LogMaker#serialize():
-    
-ArrayReturn: android.net.TestNetworkManager#createTunInterface(android.net.LinkAddress[]) parameter #0:
-    
-ArrayReturn: android.os.HwBlob#wrapArray(boolean[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(byte[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(double[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(float[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(int[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(long[]):
-    
-ArrayReturn: android.os.HwBlob#wrapArray(short[]):
-    
-ArrayReturn: android.os.NativeHandle#NativeHandle(java.io.FileDescriptor[], int[], boolean) parameter #0:
-    
-ArrayReturn: android.os.NativeHandle#getFileDescriptors():
-    
-ArrayReturn: android.security.keystore.AttestationUtils#attestDeviceIds(android.content.Context, int[], byte[]):
-    
-ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
-    
-ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]) parameter #1:
-    
-ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
-    
-ArrayReturn: android.telephony.ims.stub.ImsRegistrationImplBase#onSubscriberAssociatedUriChanged(android.net.Uri[]) parameter #0:
-    
+    Method parameter should be Collection<Descriptor> (or subclass) instead of raw array; was `android.media.audiofx.AudioEffect.Descriptor[]`
 ArrayReturn: android.view.Display#getSupportedWideColorGamut():
-    
+    Method should return Collection<ColorSpace> (or subclass) instead of raw array; was `android.graphics.ColorSpace[]`
 ArrayReturn: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #0:
-    
-ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
-    
+    Method parameter should be Collection<View> (or subclass) instead of raw array; was `android.view.View[]`
 ArrayReturn: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillOptions(CharSequence[]) parameter #0:
-    
-ArrayReturn: android.view.inspector.InspectableProperty#enumMapping():
-    
-ArrayReturn: android.view.inspector.InspectableProperty#flagMapping():
-    
+    Method parameter should be Collection<CharSequence> (or subclass) instead of raw array; was `java.lang.CharSequence[]`
 
 
-AutoBoxing: android.os.HwBlob#wrapArray(byte[]):
-    
-AutoBoxing: android.os.HwBlob#wrapArray(double[]):
-    
-AutoBoxing: android.os.HwBlob#wrapArray(float[]):
-    
-AutoBoxing: android.os.HwBlob#wrapArray(int[]):
-    
-AutoBoxing: android.os.HwBlob#wrapArray(long[]):
-    
-AutoBoxing: android.os.HwBlob#wrapArray(short[]):
-    
 AutoBoxing: android.os.VintfObject#getTargetFrameworkCompatibilityMatrixVersion():
-    
+    Must avoid boxed primitives (`java.lang.Long`)
 
 
-BannedThrow: android.app.ActivityTaskManager#removeStacksInWindowingModes(int[]):
-    
-BannedThrow: android.app.ActivityTaskManager#removeStacksWithActivityTypes(int[]):
-    
-BannedThrow: android.app.ActivityTaskManager#setTaskWindowingMode(int, int, boolean):
-    
-BannedThrow: android.app.ActivityTaskManager#setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean):
-    
-BannedThrow: android.media.audiofx.AudioEffect#getParameter(byte[], byte[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#getParameter(int, byte[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#getParameter(int, int[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#getParameter(int, short[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#getParameter(int[], short[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(byte[], byte[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(int, byte[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(int, int):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(int, short):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(int[], byte[]):
-    
-BannedThrow: android.media.audiofx.AudioEffect#setParameter(int[], int[]):
-    
-BannedThrow: android.media.audiopolicy.AudioMix.Builder#Builder(android.media.audiopolicy.AudioMixingRule):
-    
-BannedThrow: android.media.audiopolicy.AudioMix.Builder#build():
-    
-BannedThrow: android.media.audiopolicy.AudioMix.Builder#setDevice(android.media.AudioDeviceInfo):
-    
-BannedThrow: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat):
-    
-BannedThrow: android.media.audiopolicy.AudioMix.Builder#setRouteFlags(int):
-    
-BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object):
-    
-BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int):
-    
-BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object):
-    
-BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int):
-    
-BannedThrow: android.media.audiopolicy.AudioPolicy#createAudioRecordSink(android.media.audiopolicy.AudioMix):
-    
-BannedThrow: android.media.audiopolicy.AudioPolicy#createAudioTrackSource(android.media.audiopolicy.AudioMix):
-    
-BannedThrow: android.media.audiopolicy.AudioPolicy#setFocusDuckingBehavior(int):
-    
-BannedThrow: android.media.audiopolicy.AudioPolicy.Builder#addMix(android.media.audiopolicy.AudioMix):
-    
-BannedThrow: android.media.audiopolicy.AudioPolicy.Builder#setLooper(android.os.Looper):
-    
-BannedThrow: android.os.HwBinder#getService(String, String):
-    
-BannedThrow: android.os.HwBinder#getService(String, String, boolean):
-    
-BannedThrow: android.os.Process#getThreadScheduler(int):
-    
-
-
-BuilderSetStyle: android.media.audiopolicy.AudioMixingRule.Builder#allowPrivilegedPlaybackCapture(boolean):
-    
-BuilderSetStyle: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object):
-    
-BuilderSetStyle: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int):
-    
-BuilderSetStyle: android.net.NetworkCapabilities.Builder#removeCapability(int):
-    
-BuilderSetStyle: android.net.NetworkCapabilities.Builder#removeTransportType(int):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateDnsslLifetime(long):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updatePrefixPreferredLifetime(long):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updatePrefixValidLifetime(long):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateRdnssLifetime(long):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateRouteInfoLifetime(long):
-    
-BuilderSetStyle: android.net.metrics.RaEvent.Builder#updateRouterLifetime(long):
-    
 BuilderSetStyle: android.os.StrictMode.ThreadPolicy.Builder#detectExplicitGc():
-    
-BuilderSetStyle: android.os.StrictMode.VmPolicy.Builder#detectIncorrectContextUse():
-    
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.os.StrictMode.ThreadPolicy.Builder.detectExplicitGc()
 BuilderSetStyle: android.os.StrictMode.VmPolicy.Builder#permitIncorrectContextUse():
-    
-
-
-CallbackInterface: android.app.prediction.AppPredictor.Callback:
-    
-CallbackInterface: android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback:
-    
-CallbackInterface: android.widget.Magnifier.Callback:
-    
-
-
-CallbackMethodName: android.os.RemoteCallback:
-    
+    Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.os.StrictMode.VmPolicy.Builder.permitIncorrectContextUse()
 
 
 ConcreteCollection: android.content.AutofillOptions#disabledActivities:
-    
+    Field type is concrete collection (`android.util.ArrayMap`); must be higher-level interface
 ConcreteCollection: android.content.AutofillOptions#whitelistedActivitiesForAugmentedAutofill:
-    
+    Field type is concrete collection (`android.util.ArraySet`); must be higher-level interface
 ConcreteCollection: android.content.ContentCaptureOptions#ContentCaptureOptions(int, int, int, int, int, android.util.ArraySet<android.content.ComponentName>) parameter #5:
-    
+    Parameter type is concrete collection (`android.util.ArraySet`); must be higher-level interface
 ConcreteCollection: android.content.ContentCaptureOptions#whitelistedComponents:
-    
+    Field type is concrete collection (`android.util.ArraySet`); must be higher-level interface
 ConcreteCollection: android.database.sqlite.SQLiteDebug.PagerStats#dbStats:
-    
-ConcreteCollection: android.os.HwParcel#readBoolVector():
-    
-ConcreteCollection: android.os.HwParcel#readDoubleVector():
-    
-ConcreteCollection: android.os.HwParcel#readFloatVector():
-    
-ConcreteCollection: android.os.HwParcel#readInt16Vector():
-    
-ConcreteCollection: android.os.HwParcel#readInt32Vector():
-    
-ConcreteCollection: android.os.HwParcel#readInt64Vector():
-    
-ConcreteCollection: android.os.HwParcel#readInt8Vector():
-    
-ConcreteCollection: android.os.HwParcel#readNativeHandleVector():
-    
-ConcreteCollection: android.os.HwParcel#readStringVector():
-    
-ConcreteCollection: android.os.HwParcel#writeBoolVector(java.util.ArrayList<java.lang.Boolean>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeDoubleVector(java.util.ArrayList<java.lang.Double>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeFloatVector(java.util.ArrayList<java.lang.Float>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeInt16Vector(java.util.ArrayList<java.lang.Short>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeInt32Vector(java.util.ArrayList<java.lang.Integer>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeInt64Vector(java.util.ArrayList<java.lang.Long>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeInt8Vector(java.util.ArrayList<java.lang.Byte>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeNativeHandleVector(java.util.ArrayList<android.os.NativeHandle>) parameter #0:
-    
-ConcreteCollection: android.os.HwParcel#writeStringVector(java.util.ArrayList<java.lang.String>) parameter #0:
-    
+    Field type is concrete collection (`java.util.ArrayList`); must be higher-level interface
 ConcreteCollection: android.service.autofill.CompositeUserData#getFieldClassificationAlgorithms():
-    
+    Return type is concrete collection (`android.util.ArrayMap`); must be higher-level interface
 ConcreteCollection: android.service.autofill.CompositeUserData#getFieldClassificationArgs():
-    
+    Return type is concrete collection (`android.util.ArrayMap`); must be higher-level interface
 ConcreteCollection: android.service.autofill.InternalTransformation#batchApply(android.service.autofill.ValueFinder, android.widget.RemoteViews, java.util.ArrayList<android.util.Pair<java.lang.Integer,android.service.autofill.InternalTransformation>>) parameter #2:
-    
+    Parameter type is concrete collection (`java.util.ArrayList`); must be higher-level interface
 ConcreteCollection: android.service.autofill.UserData#getFieldClassificationAlgorithms():
-    
-ConcreteCollection: android.telephony.ims.ImsConferenceState#mParticipants:
-    
+    Return type is concrete collection (`android.util.ArrayMap`); must be higher-level interface
 
 
 ContextFirst: android.os.VibrationEffect#get(android.net.Uri, android.content.Context) parameter #1:
-    
-
-
-ContextNameSuffix: android.telephony.mbms.vendor.MbmsGroupCallServiceBase:
-    
+    Context is distinct, so it must be the first argument (method `get`)
 
 
 EndsWithImpl: android.view.contentcapture.ViewNode.ViewStructureImpl:
-    
+    Don't expose your implementation details: `ViewStructureImpl` ends with `Impl`
 
 
 Enum: android.view.inspector.InspectableProperty.ValueType:
-    
+    Enums are discouraged in Android APIs
 
 
-EqualsAndHashCode: android.app.prediction.AppPredictionContext#equals(Object):
-    
-EqualsAndHashCode: android.app.prediction.AppTarget#equals(Object):
-    
-EqualsAndHashCode: android.app.prediction.AppTargetEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.apf.ApfCapabilities#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.ApfProgramEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.ApfStats#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.DhcpClientEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.IpManagerEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.IpReachabilityEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.NetworkEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.RaEvent#equals(Object):
-    
-EqualsAndHashCode: android.net.metrics.ValidationProbeEvent#equals(Object):
-    
-EqualsAndHashCode: android.os.IncidentManager.PendingReport#equals(Object):
-    
 EqualsAndHashCode: android.os.StrictMode.ViolationInfo#hashCode():
-    
+    Must override both equals and hashCode; missing one in android.os.StrictMode.ViolationInfo
 
 
-ExecutorRegistration: android.content.pm.PackageManager#addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener):
-    
-ExecutorRegistration: android.hardware.camera2.CameraDevice#createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler):
-    
 ExecutorRegistration: android.media.audiofx.AudioEffect#setParameterListener(android.media.audiofx.AudioEffect.OnParameterChangeListener):
-    
-ExecutorRegistration: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener):
-    
-ExecutorRegistration: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener):
-    
-ExecutorRegistration: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyVolumeCallback(android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback):
-    
-ExecutorRegistration: android.os.IncidentManager#cancelAuthorization(android.os.IncidentManager.AuthListener):
-    
-ExecutorRegistration: android.os.IncidentManager#requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener):
-    
-ExecutorRegistration: android.os.RemoteCallback#RemoteCallback(android.os.RemoteCallback.OnResultListener, android.os.Handler):
-    
+    Registration methods should have overload that accepts delivery Executor: `setParameterListener`
 ExecutorRegistration: android.permission.PermissionControllerManager#countPermissionApps(java.util.List<java.lang.String>, int, android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, android.os.Handler):
-    
+    Registration methods should have overload that accepts delivery Executor: `countPermissionApps`
 ExecutorRegistration: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler):
-    
+    Registration methods should have overload that accepts delivery Executor: `getAppPermissions`
 ExecutorRegistration: android.service.watchdog.ExplicitHealthCheckService#setCallback(android.os.RemoteCallback):
-    
-ExecutorRegistration: android.telephony.ims.stub.ImsCallSessionImplBase#setListener(android.telephony.ims.ImsCallSessionListener):
-    
-ExecutorRegistration: android.telephony.ims.stub.ImsUtImplBase#setListener(android.telephony.ims.ImsUtListener):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#startGroupCall(int, long, java.util.List<java.lang.Integer>, java.util.List<java.lang.Integer>, android.telephony.mbms.GroupCallCallback):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int):
-    
-ExecutorRegistration: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback):
-    
+    Registration methods should have overload that accepts delivery Executor: `setCallback`
 ExecutorRegistration: android.window.WindowOrganizer#applySyncTransaction(android.window.WindowContainerTransaction, android.window.WindowContainerTransactionCallback):
-    
+    Registration methods should have overload that accepts delivery Executor: `applySyncTransaction`
 
 
 ForbiddenSuperClass: android.app.AppDetailsActivity:
-    
+    AppDetailsActivity should not extend `Activity`. Activity subclasses are impossible to compose. Expose a composable API instead.
 
 
-GenericException: android.app.prediction.AppPredictor#finalize():
-    
 GenericException: android.service.autofill.CharSequenceTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
+    Methods must not throw generic exceptions (`java.lang.Exception`)
 GenericException: android.service.autofill.DateTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
+    Methods must not throw generic exceptions (`java.lang.Exception`)
 GenericException: android.service.autofill.ImageTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
-GenericException: android.service.autofill.augmented.FillWindow#finalize():
-    
+    Methods must not throw generic exceptions (`java.lang.Exception`)
 
 
-GetterOnBuilder: android.hardware.display.BrightnessConfiguration.Builder#getMaxCorrectionsByCategory():
-    
-GetterOnBuilder: android.hardware.display.BrightnessConfiguration.Builder#getMaxCorrectionsByPackageName():
-    
-
-
-GetterSetterNames: android.app.NotificationChannel#isBlockableSystem():
-    
-GetterSetterNames: android.app.NotificationChannel#isImportanceLockedByCriticalDeviceFunction():
-    
-GetterSetterNames: android.app.NotificationChannel#isImportanceLockedByOEM():
-    
 GetterSetterNames: android.location.GnssClock#setBiasNanos(double):
-    
+    Symmetric method for `hasBiasNanos` must be named `setHasBiasNanos`; was `setBiasNanos`
 GetterSetterNames: android.location.GnssClock#setBiasUncertaintyNanos(double):
-    
+    Symmetric method for `hasBiasUncertaintyNanos` must be named `setHasBiasUncertaintyNanos`; was `setBiasUncertaintyNanos`
 GetterSetterNames: android.location.GnssClock#setDriftNanosPerSecond(double):
-    
+    Symmetric method for `hasDriftNanosPerSecond` must be named `setHasDriftNanosPerSecond`; was `setDriftNanosPerSecond`
 GetterSetterNames: android.location.GnssClock#setDriftUncertaintyNanosPerSecond(double):
-    
+    Symmetric method for `hasDriftUncertaintyNanosPerSecond` must be named `setHasDriftUncertaintyNanosPerSecond`; was `setDriftUncertaintyNanosPerSecond`
 GetterSetterNames: android.location.GnssClock#setElapsedRealtimeNanos(long):
-    
+    Symmetric method for `hasElapsedRealtimeNanos` must be named `setHasElapsedRealtimeNanos`; was `setElapsedRealtimeNanos`
 GetterSetterNames: android.location.GnssClock#setElapsedRealtimeUncertaintyNanos(double):
-    
+    Symmetric method for `hasElapsedRealtimeUncertaintyNanos` must be named `setHasElapsedRealtimeUncertaintyNanos`; was `setElapsedRealtimeUncertaintyNanos`
 GetterSetterNames: android.location.GnssClock#setFullBiasNanos(long):
-    
+    Symmetric method for `hasFullBiasNanos` must be named `setHasFullBiasNanos`; was `setFullBiasNanos`
 GetterSetterNames: android.location.GnssClock#setLeapSecond(int):
-    
+    Symmetric method for `hasLeapSecond` must be named `setHasLeapSecond`; was `setLeapSecond`
 GetterSetterNames: android.location.GnssClock#setReferenceCarrierFrequencyHzForIsb(double):
-    
+    Symmetric method for `hasReferenceCarrierFrequencyHzForIsb` must be named `setHasReferenceCarrierFrequencyHzForIsb`; was `setReferenceCarrierFrequencyHzForIsb`
 GetterSetterNames: android.location.GnssClock#setReferenceCodeTypeForIsb(String):
-    
+    Symmetric method for `hasReferenceCodeTypeForIsb` must be named `setHasReferenceCodeTypeForIsb`; was `setReferenceCodeTypeForIsb`
 GetterSetterNames: android.location.GnssClock#setReferenceConstellationTypeForIsb(int):
-    
+    Symmetric method for `hasReferenceConstellationTypeForIsb` must be named `setHasReferenceConstellationTypeForIsb`; was `setReferenceConstellationTypeForIsb`
 GetterSetterNames: android.location.GnssClock#setTimeUncertaintyNanos(double):
-    
+    Symmetric method for `hasTimeUncertaintyNanos` must be named `setHasTimeUncertaintyNanos`; was `setTimeUncertaintyNanos`
 GetterSetterNames: android.location.GnssMeasurement#setBasebandCn0DbHz(double):
-    
+    Symmetric method for `hasBasebandCn0DbHz` must be named `setHasBasebandCn0DbHz`; was `setBasebandCn0DbHz`
 GetterSetterNames: android.location.GnssMeasurement#setCarrierFrequencyHz(float):
-    
+    Symmetric method for `hasCarrierFrequencyHz` must be named `setHasCarrierFrequencyHz`; was `setCarrierFrequencyHz`
 GetterSetterNames: android.location.GnssMeasurement#setCodeType(String):
-    
+    Symmetric method for `hasCodeType` must be named `setHasCodeType`; was `setCodeType`
 GetterSetterNames: android.location.GnssMeasurement#setCorrelationVectors(java.util.Collection<android.location.CorrelationVector>):
-    
+    Symmetric method for `hasCorrelationVectors` must be named `setHasCorrelationVectors`; was `setCorrelationVectors`
 GetterSetterNames: android.location.GnssMeasurement#setFullInterSignalBiasNanos(double):
-    
+    Symmetric method for `hasFullInterSignalBiasNanos` must be named `setHasFullInterSignalBiasNanos`; was `setFullInterSignalBiasNanos`
 GetterSetterNames: android.location.GnssMeasurement#setFullInterSignalBiasUncertaintyNanos(double):
-    
+    Symmetric method for `hasFullInterSignalBiasUncertaintyNanos` must be named `setHasFullInterSignalBiasUncertaintyNanos`; was `setFullInterSignalBiasUncertaintyNanos`
 GetterSetterNames: android.location.GnssMeasurement#setSatelliteInterSignalBiasNanos(double):
-    
+    Symmetric method for `hasSatelliteInterSignalBiasNanos` must be named `setHasSatelliteInterSignalBiasNanos`; was `setSatelliteInterSignalBiasNanos`
 GetterSetterNames: android.location.GnssMeasurement#setSatelliteInterSignalBiasUncertaintyNanos(double):
-    
+    Symmetric method for `hasSatelliteInterSignalBiasUncertaintyNanos` must be named `setHasSatelliteInterSignalBiasUncertaintyNanos`; was `setSatelliteInterSignalBiasUncertaintyNanos`
 GetterSetterNames: android.location.GnssMeasurement#setSatellitePvt(android.location.SatellitePvt):
-    
+    Symmetric method for `hasSatellitePvt` must be named `setHasSatellitePvt`; was `setSatellitePvt`
 GetterSetterNames: android.location.GnssMeasurement#setSnrInDb(double):
-    
-GetterSetterNames: android.location.LocationRequest#isLocationSettingsIgnored():
-    
-GetterSetterNames: android.location.LocationRequest#isLowPowerMode():
-    
+    Symmetric method for `hasSnrInDb` must be named `setHasSnrInDb`; was `setSnrInDb`
 GetterSetterNames: android.net.NetworkPolicyManager#getRestrictBackground():
     Symmetric method for `setRestrictBackground` must be named `isRestrictBackground`; was `getRestrictBackground`
-GetterSetterNames: android.os.IncidentReportArgs#isAll():
-    
-GetterSetterNames: android.service.notification.NotificationStats#setDirectReplied():
-    
-GetterSetterNames: android.service.notification.NotificationStats#setExpanded():
-    
-GetterSetterNames: android.service.notification.NotificationStats#setSeen():
-    
-GetterSetterNames: android.service.notification.NotificationStats#setSnoozed():
-    
-GetterSetterNames: android.service.notification.NotificationStats#setViewedSettings():
-    
-GetterSetterNames: android.view.View#isAutofilled():
-    
-GetterSetterNames: android.view.View#isDefaultFocusHighlightEnabled():
-    
 
 
-IllegalStateException: android.media.audiopolicy.AudioMix.Builder#build():
-    
-
-
-IntentBuilderName: android.app.backup.BackupManager#getConfigurationIntent(String):
-    
-IntentBuilderName: android.app.backup.BackupManager#getDataManagementIntent(String):
-    
 IntentBuilderName: android.hardware.soundtrigger.KeyphraseEnrollmentInfo#getManageKeyphraseIntent(int, String, java.util.Locale):
-    
+    Methods creating an Intent should be named `create<Foo>Intent()`, was `getManageKeyphraseIntent`
 
 
 IntentName: android.provider.Settings.Secure#VOICE_INTERACTION_SERVICE:
-    
+    Intent action constant name must be ACTION_FOO: VOICE_INTERACTION_SERVICE
 IntentName: android.provider.Telephony.Sms.Intents#SMS_CARRIER_PROVISION_ACTION:
-    
-IntentName: android.service.notification.Adjustment#KEY_CONTEXTUAL_ACTIONS:
-    
+    Intent action constant name must be ACTION_FOO: SMS_CARRIER_PROVISION_ACTION
 
 
-InterfaceConstant: android.service.autofill.AutofillFieldClassificationService#SERVICE_INTERFACE:
-    
-InterfaceConstant: android.service.autofill.augmented.AugmentedAutofillService#SERVICE_INTERFACE:
-    
-InterfaceConstant: android.service.contentcapture.ContentCaptureService#SERVICE_INTERFACE:
-    
-InterfaceConstant: android.service.notification.NotificationAssistantService#SERVICE_INTERFACE:
-    
-InterfaceConstant: android.telecom.PhoneAccountSuggestionService#SERVICE_INTERFACE:
-    
-
-
-InternalField: android.media.audiopolicy.AudioProductStrategy#sDefaultAttributes:
-    Internal field sDefaultAttributes must not be exposed
-InternalField: android.telephony.ims.ImsConferenceState#mParticipants:
-    
-
-
-KotlinOperator: android.os.WorkSource#get(int):
-    
+KotlinOperator: android.os.PackageTagsList#contains(android.os.PackageTagsList):
+    Method can be invoked as a "in" operator from Kotlin: `contains` (this is usually desirable; just make sure it makes sense for this type of object)
 KotlinOperator: android.util.SparseArrayMap#get(int, K):
-    
-KotlinOperator: android.util.SparseArrayMap#get(int, String):
-    
+    Method can be invoked with an indexing operator from Kotlin: `get` (this is usually desirable; just make sure it makes sense for this type of object)
 
 
-ListenerInterface: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener:
-    
-ListenerInterface: android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener:
-    
-ListenerInterface: android.os.IncidentManager.AuthListener:
-    
-ListenerInterface: android.telephony.ims.ImsCallSessionListener:
-    
-ListenerInterface: android.telephony.ims.ImsUtListener:
-    
-
-
-ListenerLast: android.hardware.camera2.CameraDevice#createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) parameter #4:
-    
-ListenerLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper) parameter #2:
-    
 ListenerLast: android.permission.PermissionControllerManager#countPermissionApps(java.util.List<java.lang.String>, int, android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, android.os.Handler) parameter #3:
-    
+    Listeners should always be at end of argument list (method `countPermissionApps`)
 ListenerLast: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler) parameter #2:
-    
-ListenerLast: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) parameter #1:
-    
-ListenerLast: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) parameter #1:
-    
+    Listeners should always be at end of argument list (method `getAppPermissions`)
 
 
 ManagerConstructor: android.content.pm.ShortcutManager#ShortcutManager(android.content.Context):
-    
-
-
-ManagerLookup: android.telephony.ims.ImsMmTelManager#createForSubscriptionId(int):
-    
-ManagerLookup: android.telephony.ims.ProvisioningManager#createForSubscriptionId(int):
-    
-
-
-MethodNameTense: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToEnable():
-    
-
-
-MethodNameUnits: android.telephony.ims.ImsCallForwardInfo#getTimeSeconds():
-    
+    Managers must always be obtained from Context; no direct constructors
 
 
 MinMaxConstant: android.os.UserHandle#MIN_SECONDARY_USER_ID:
-    
+    If min/max could change in future, make them dynamic methods: android.os.UserHandle#MIN_SECONDARY_USER_ID
 MinMaxConstant: android.view.autofill.AutofillManager#MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS:
-    
+    If min/max could change in future, make them dynamic methods: android.view.autofill.AutofillManager#MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS
 
 
-MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setFlags(int):
-    
-MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setOpNames(java.util.List<java.lang.String>):
-    
-MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setPackageName(String):
-    
-MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setUid(int):
-    
-MissingGetterMatchingBuilder: android.content.integrity.RuleSet.Builder#addRules(java.util.List<android.content.integrity.Rule>):
-    
-MissingGetterMatchingBuilder: android.hardware.display.BrightnessConfiguration.Builder#addCorrectionByCategory(int, android.hardware.display.BrightnessCorrection):
-    
-MissingGetterMatchingBuilder: android.hardware.display.BrightnessConfiguration.Builder#addCorrectionByPackageName(String, android.hardware.display.BrightnessCorrection):
-    
-MissingGetterMatchingBuilder: android.hardware.display.BrightnessConfiguration.Builder#setDescription(String):
-    
-MissingGetterMatchingBuilder: android.hardware.lights.LightsRequest.Builder#setLight(android.hardware.lights.Light, android.hardware.lights.LightState):
-    
 MissingGetterMatchingBuilder: android.media.VolumeShaper.Configuration.Builder#setOptionFlags(int):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMix.Builder#setDevice(android.media.AudioDeviceInfo):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMix.Builder#setRouteFlags(int):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#addMix(android.media.audiopolicy.AudioMix):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyVolumeCallback(android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setIsAudioFocusPolicy(boolean):
-    
+    android.media.VolumeShaper.Configuration does not declare a `getOptionFlags()` method matching method android.media.VolumeShaper.Configuration.Builder.setOptionFlags(int)
 MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setIsTestFocusPolicy(boolean):
-    
-MissingGetterMatchingBuilder: android.media.audiopolicy.AudioPolicy.Builder#setLooper(android.os.Looper):
-    
-MissingGetterMatchingBuilder: android.net.CaptivePortalData.Builder#setBytesRemaining(long):
-    
-MissingGetterMatchingBuilder: android.net.CaptivePortalData.Builder#setExpiryTime(long):
-    
-MissingGetterMatchingBuilder: android.net.CaptivePortalData.Builder#setRefreshTime(long):
-    
-MissingGetterMatchingBuilder: android.net.NetworkCapabilities.Builder#addCapability(int):
-    
-MissingGetterMatchingBuilder: android.net.NetworkCapabilities.Builder#setRequestorPackageName(String):
-    
-MissingGetterMatchingBuilder: android.net.NetworkCapabilities.Builder#setRequestorUid(int):
-    
-MissingGetterMatchingBuilder: android.net.TetheringManager.TetheringRequest.Builder#setShouldShowEntitlementUi(boolean):
-    
-MissingGetterMatchingBuilder: android.net.TetheringManager.TetheringRequest.Builder#setStaticIpv4Addresses(android.net.LinkAddress, android.net.LinkAddress):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setActualLifetime(long):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setCurrentRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setFilteredRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setFlags(boolean, boolean):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setLifetime(long):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfProgramEvent.Builder#setProgramLength(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setDroppedRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setDurationMs(long):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setMatchingRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setMaxProgramSize(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setParseErrors(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setProgramUpdates(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setProgramUpdatesAll(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setProgramUpdatesAllowingMulticast(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setReceivedRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ApfStats.Builder#setZeroLifetimeRas(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.DhcpClientEvent.Builder#setDurationMs(int):
-    
-MissingGetterMatchingBuilder: android.net.metrics.DhcpClientEvent.Builder#setMsg(String):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ValidationProbeEvent.Builder#setDurationMs(long):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ValidationProbeEvent.Builder#setProbeType(int, boolean):
-    
-MissingGetterMatchingBuilder: android.net.metrics.ValidationProbeEvent.Builder#setReturnCode(int):
-    
+    android.media.audiopolicy.AudioPolicy does not declare a `isIsTestFocusPolicy()` method matching method android.media.audiopolicy.AudioPolicy.Builder.setIsTestFocusPolicy(boolean)
 MissingGetterMatchingBuilder: android.security.keystore.KeyGenParameterSpec.Builder#setUniqueIdIncluded(boolean):
-    
-MissingGetterMatchingBuilder: android.service.autofill.Dataset.Builder#setFieldInlinePresentation(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, java.util.regex.Pattern, android.service.autofill.InlinePresentation):
-    
-MissingGetterMatchingBuilder: android.service.autofill.augmented.FillResponse.Builder#setClientState(android.os.Bundle):
-    
-MissingGetterMatchingBuilder: android.service.autofill.augmented.FillResponse.Builder#setFillWindow(android.service.autofill.augmented.FillWindow):
-    
-MissingGetterMatchingBuilder: android.service.autofill.augmented.FillResponse.Builder#setInlineSuggestions(java.util.List<android.service.autofill.Dataset>):
-    
-MissingGetterMatchingBuilder: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallViaAudioProcessing(boolean):
-    
+    android.security.keystore.KeyGenParameterSpec does not declare a `isUniqueIdIncluded()` method matching method android.security.keystore.KeyGenParameterSpec.Builder.setUniqueIdIncluded(boolean)
 MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setIsAdhocConferenceCall(boolean):
-    
+    android.telecom.ConnectionRequest does not declare a `isIsAdhocConferenceCall()` method matching method android.telecom.ConnectionRequest.Builder.setIsAdhocConferenceCall(boolean)
 MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setRttPipeFromInCall(android.os.ParcelFileDescriptor):
-    
+    android.telecom.ConnectionRequest does not declare a `getRttPipeFromInCall()` method matching method android.telecom.ConnectionRequest.Builder.setRttPipeFromInCall(android.os.ParcelFileDescriptor)
 MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setRttPipeToInCall(android.os.ParcelFileDescriptor):
-    
+    android.telecom.ConnectionRequest does not declare a `getRttPipeToInCall()` method matching method android.telecom.ConnectionRequest.Builder.setRttPipeToInCall(android.os.ParcelFileDescriptor)
 MissingGetterMatchingBuilder: android.telecom.ConnectionRequest.Builder#setShouldShowIncomingCallUi(boolean):
-    
-MissingGetterMatchingBuilder: android.telecom.PhoneAccount.Builder#setGroupId(String):
-    
-MissingGetterMatchingBuilder: android.telephony.NetworkRegistrationInfo.Builder#setEmergencyOnly(boolean):
-    
-MissingGetterMatchingBuilder: android.telephony.ims.ImsSsData.Builder#setCallForwardingInfo(java.util.List<android.telephony.ims.ImsCallForwardInfo>):
-    
-MissingGetterMatchingBuilder: android.telephony.ims.stub.ImsFeatureConfiguration.Builder#addFeature(int, int):
-    
-MissingGetterMatchingBuilder: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
-    
+    android.telecom.ConnectionRequest does not declare a `shouldShowIncomingCallUi()` method matching method android.telecom.ConnectionRequest.Builder.setShouldShowIncomingCallUi(boolean)
 MissingGetterMatchingBuilder: android.view.Display.Mode.Builder#setResolution(int, int):
     android.view.Display.Mode does not declare a `getResolution()` method matching method android.view.Display.Mode.Builder.setResolution(int,int)
 
 
 MissingNullability: android.app.Activity#onMovedToDisplay(int, android.content.res.Configuration) parameter #1:
-    
-MissingNullability: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int) parameter #0:
-    
+    Missing nullability on parameter `config` in method `onMovedToDisplay`
 MissingNullability: android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning(android.content.ComponentName) parameter #0:
-    
-MissingNullability: android.app.ActivityManager#forceStopPackage(String) parameter #0:
-    
-MissingNullability: android.app.ActivityManager#getPackageImportance(String) parameter #0:
-    
+    Missing nullability on parameter `activity` in method `alwaysShowUnsupportedCompileSdkWarning`
 MissingNullability: android.app.ActivityManager#holdLock(android.os.IBinder, int) parameter #0:
-    
-MissingNullability: android.app.ActivityManager#removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener) parameter #0:
-    
+    Missing nullability on parameter `token` in method `holdLock`
 MissingNullability: android.app.ActivityManager#scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int) parameter #0:
-    
+    Missing nullability on parameter `packages` in method `scheduleApplicationInfoChanged`
 MissingNullability: android.app.ActivityManager.TaskDescription#getIconFilename():
-    
+    Missing nullability on method `getIconFilename` return
 MissingNullability: android.app.ActivityTaskManager#clearLaunchParamsForPackages(java.util.List<java.lang.String>) parameter #0:
-    
-MissingNullability: android.app.ActivityTaskManager#listAllStacks():
-    
-MissingNullability: android.app.ActivityTaskManager#moveTopActivityToPinnedStack(int, android.graphics.Rect) parameter #1:
-    
-MissingNullability: android.app.ActivityTaskManager#removeStacksInWindowingModes(int[]) parameter #0:
-    
-MissingNullability: android.app.ActivityTaskManager#removeStacksWithActivityTypes(int[]) parameter #0:
-    
-MissingNullability: android.app.ActivityTaskManager#resizeDockedStack(android.graphics.Rect, android.graphics.Rect) parameter #0:
-    
-MissingNullability: android.app.ActivityTaskManager#resizeDockedStack(android.graphics.Rect, android.graphics.Rect) parameter #1:
-    
-MissingNullability: android.app.ActivityTaskManager#resizePinnedStack(int, android.graphics.Rect, boolean) parameter #1:
-    
+    Missing nullability on parameter `packageNames` in method `clearLaunchParamsForPackages`
 MissingNullability: android.app.ActivityTaskManager#resizeTask(int, android.graphics.Rect) parameter #1:
-    
-MissingNullability: android.app.ActivityTaskManager#setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean) parameter #4:
-    
+    Missing nullability on parameter `bounds` in method `resizeTask`
 MissingNullability: android.app.ActivityTaskManager#supportsMultiWindow(android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `context` in method `supportsMultiWindow`
 MissingNullability: android.app.ActivityTaskManager#supportsSplitScreenMultiWindow(android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `context` in method `supportsSplitScreenMultiWindow`
 MissingNullability: android.app.AppDetailsActivity#onCreate(android.os.Bundle) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager#getOpStrs():
-    
+    Missing nullability on parameter `savedInstanceState` in method `onCreate`
 MissingNullability: android.app.AppOpsManager#isOperationActive(int, int, String) parameter #2:
-    
+    Missing nullability on parameter `packageName` in method `isOperationActive`
 MissingNullability: android.app.AppOpsManager#opToPermission(int):
-    
+    Missing nullability on method `opToPermission` return
 MissingNullability: android.app.AppOpsManager#permissionToOpCode(String) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager#setMode(String, int, String, int) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager#setMode(String, int, String, int) parameter #2:
-    
+    Missing nullability on parameter `permission` in method `permissionToOpCode`
 MissingNullability: android.app.AppOpsManager#setMode(int, int, String, int) parameter #2:
-    
-MissingNullability: android.app.AppOpsManager#setUidMode(String, int, int) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager.HistoricalOp#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager.HistoricalOps#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager.HistoricalUidOps#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.app.AppOpsManager.OpEntry#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `packageName` in method `setMode`
 MissingNullability: android.app.NotificationManager#allowAssistantAdjustment(String) parameter #0:
-    
+    Missing nullability on parameter `capability` in method `allowAssistantAdjustment`
 MissingNullability: android.app.NotificationManager#disallowAssistantAdjustment(String) parameter #0:
-    
+    Missing nullability on parameter `capability` in method `disallowAssistantAdjustment`
 MissingNullability: android.app.NotificationManager#getEffectsSuppressor():
-    
-MissingNullability: android.app.NotificationManager#matchesCallFilter(android.os.Bundle) parameter #0:
-    
-MissingNullability: android.app.PictureInPictureParams#getActions():
-    
-MissingNullability: android.app.PictureInPictureParams#getSourceRectHint():
-    
+    Missing nullability on method `getEffectsSuppressor` return
 MissingNullability: android.app.TimePickerDialog#getTimePicker():
-    
-MissingNullability: android.app.UiAutomation#executeShellCommandRw(String):
-    
-MissingNullability: android.app.UiAutomation#executeShellCommandRw(String) parameter #0:
-    
-MissingNullability: android.app.UiAutomation#grantRuntimePermission(String, String, android.os.UserHandle) parameter #0:
-    
-MissingNullability: android.app.UiAutomation#grantRuntimePermission(String, String, android.os.UserHandle) parameter #1:
-    
-MissingNullability: android.app.UiAutomation#grantRuntimePermission(String, String, android.os.UserHandle) parameter #2:
-    
-MissingNullability: android.app.UiAutomation#revokeRuntimePermission(String, String, android.os.UserHandle) parameter #0:
-    
-MissingNullability: android.app.UiAutomation#revokeRuntimePermission(String, String, android.os.UserHandle) parameter #1:
-    
-MissingNullability: android.app.UiAutomation#revokeRuntimePermission(String, String, android.os.UserHandle) parameter #2:
-    
-MissingNullability: android.app.WallpaperManager#setWallpaperComponent(android.content.ComponentName) parameter #0:
-    
+    Missing nullability on method `getTimePicker` return
 MissingNullability: android.app.WindowConfiguration#compareTo(android.app.WindowConfiguration) parameter #0:
-    
+    Missing nullability on parameter `that` in method `compareTo`
 MissingNullability: android.app.WindowConfiguration#getAppBounds():
-    
+    Missing nullability on method `getAppBounds` return
 MissingNullability: android.app.WindowConfiguration#getBounds():
-    
+    Missing nullability on method `getBounds` return
 MissingNullability: android.app.WindowConfiguration#setAppBounds(android.graphics.Rect) parameter #0:
-    
+    Missing nullability on parameter `rect` in method `setAppBounds`
 MissingNullability: android.app.WindowConfiguration#setBounds(android.graphics.Rect) parameter #0:
-    
+    Missing nullability on parameter `rect` in method `setBounds`
 MissingNullability: android.app.WindowConfiguration#setTo(android.app.WindowConfiguration) parameter #0:
-    
+    Missing nullability on parameter `other` in method `setTo`
 MissingNullability: android.app.WindowConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `dest` in method `writeToParcel`
 MissingNullability: android.app.admin.DevicePolicyManager#getOwnerInstalledCaCerts(android.os.UserHandle):
-    
+    Missing nullability on method `getOwnerInstalledCaCerts` return
 MissingNullability: android.app.admin.SecurityLog.SecurityEvent#SecurityEvent(long, byte[]) parameter #1:
-    
-MissingNullability: android.app.backup.BackupManager#getConfigurationIntent(String):
-    
-MissingNullability: android.app.backup.BackupManager#getConfigurationIntent(String) parameter #0:
-    
-MissingNullability: android.app.backup.BackupManager#getDataManagementIntent(String):
-    
-MissingNullability: android.app.backup.BackupManager#getDataManagementIntent(String) parameter #0:
-    
-MissingNullability: android.app.backup.BackupManager#getDestinationString(String):
-    
-MissingNullability: android.app.backup.BackupManager#getDestinationString(String) parameter #0:
-    
-MissingNullability: android.app.prediction.AppPredictionSessionId#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `data` in method `SecurityEvent`
 MissingNullability: android.app.prediction.AppPredictor#getSessionId():
-    
-MissingNullability: android.app.prediction.AppTarget#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.app.prediction.AppTargetEvent#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.app.prediction.AppTargetId#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on method `getSessionId` return
 MissingNullability: android.content.AutofillOptions#forWhitelistingItself():
-    
+    Missing nullability on method `forWhitelistingItself` return
 MissingNullability: android.content.AutofillOptions#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `parcel` in method `writeToParcel`
 MissingNullability: android.content.ContentCaptureOptions#forWhitelistingItself():
-    
+    Missing nullability on method `forWhitelistingItself` return
 MissingNullability: android.content.ContentCaptureOptions#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `parcel` in method `writeToParcel`
 MissingNullability: android.content.ContentResolver#getSyncAdapterPackagesForAuthorityAsUser(String, int):
-    
+    Missing nullability on method `getSyncAdapterPackagesForAuthorityAsUser` return
 MissingNullability: android.content.ContentResolver#getSyncAdapterPackagesForAuthorityAsUser(String, int) parameter #0:
-    
-MissingNullability: android.content.Context#getDisplay():
-    
-MissingNullability: android.content.Context#getUser():
-    
-MissingNullability: android.content.ContextWrapper#getDisplay():
-    
-MissingNullability: android.content.ContextWrapper#setContentCaptureOptions(android.content.ContentCaptureOptions) parameter #0:
-    
+    Missing nullability on parameter `authority` in method `getSyncAdapterPackagesForAuthorityAsUser`
 MissingNullability: android.content.pm.ActivityInfo#isTranslucentOrFloating(android.content.res.TypedArray) parameter #0:
-    
+    Missing nullability on parameter `attributes` in method `isTranslucentOrFloating`
 MissingNullability: android.content.pm.LauncherApps#LauncherApps(android.content.Context) parameter #0:
-    
-MissingNullability: android.content.pm.PackageInstaller.SessionParams#setGrantedRuntimePermissions(String[]) parameter #0:
-    
+    Missing nullability on parameter `context` in method `LauncherApps`
 MissingNullability: android.content.pm.PackageManager#getHoldLockToken():
-    Missing nullability on method `BINDER` return
+    Missing nullability on method `getHoldLockToken` return
 MissingNullability: android.content.pm.PackageManager#getNamesForUids(int[]) parameter #0:
-    
+    Missing nullability on parameter `uids` in method `getNamesForUids`
 MissingNullability: android.content.pm.PackageManager#holdLock(android.os.IBinder, int) parameter #0:
-    
+    Missing nullability on parameter `token` in method `holdLock`
 MissingNullability: android.content.pm.ShortcutManager#ShortcutManager(android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `context` in method `ShortcutManager`
 MissingNullability: android.content.pm.UserInfo#UserInfo(android.content.pm.UserInfo) parameter #0:
     Missing nullability on parameter `orig` in method `UserInfo`
 MissingNullability: android.content.pm.UserInfo#UserInfo(int, String, String, int) parameter #1:
@@ -942,1469 +292,477 @@
 MissingNullability: android.content.pm.UserInfo#writeToParcel(android.os.Parcel, int) parameter #0:
     Missing nullability on parameter `dest` in method `writeToParcel`
 MissingNullability: android.content.res.AssetManager#getOverlayablesToString(String) parameter #0:
-    
+    Missing nullability on parameter `packageName` in method `getOverlayablesToString`
 MissingNullability: android.content.res.Configuration#windowConfiguration:
-    
-MissingNullability: android.content.rollback.PackageRollbackInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.content.rollback.RollbackInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on field `windowConfiguration` in class `class android.content.res.Configuration`
 MissingNullability: android.database.sqlite.SQLiteDebug#dump(android.util.Printer, String[]) parameter #0:
-    
+    Missing nullability on parameter `printer` in method `dump`
 MissingNullability: android.database.sqlite.SQLiteDebug#dump(android.util.Printer, String[]) parameter #1:
-    
+    Missing nullability on parameter `args` in method `dump`
 MissingNullability: android.database.sqlite.SQLiteDebug#getDatabaseInfo():
-    
+    Missing nullability on method `getDatabaseInfo` return
 MissingNullability: android.database.sqlite.SQLiteDebug.DbStats#DbStats(String, long, long, int, int, int, int) parameter #0:
-    
+    Missing nullability on parameter `dbName` in method `DbStats`
 MissingNullability: android.database.sqlite.SQLiteDebug.DbStats#cache:
-    
+    Missing nullability on field `cache` in class `class android.database.sqlite.SQLiteDebug.DbStats`
 MissingNullability: android.database.sqlite.SQLiteDebug.DbStats#dbName:
-    
+    Missing nullability on field `dbName` in class `class android.database.sqlite.SQLiteDebug.DbStats`
 MissingNullability: android.database.sqlite.SQLiteDebug.PagerStats#dbStats:
-    
+    Missing nullability on field `dbStats` in class `class android.database.sqlite.SQLiteDebug.PagerStats`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #0:
-    
+    Missing nullability on parameter `db` in method `SQLiteDirectCursorDriver`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #1:
-    
+    Missing nullability on parameter `sql` in method `SQLiteDirectCursorDriver`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #2:
-    
+    Missing nullability on parameter `editTable` in method `SQLiteDirectCursorDriver`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #3:
-    
+    Missing nullability on parameter `cancellationSignal` in method `SQLiteDirectCursorDriver`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#cursorRequeried(android.database.Cursor) parameter #0:
-    
+    Missing nullability on parameter `cursor` in method `cursorRequeried`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]):
-    
+    Missing nullability on method `query` return
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]) parameter #0:
-    
+    Missing nullability on parameter `factory` in method `query`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]) parameter #1:
-    
+    Missing nullability on parameter `selectionArgs` in method `query`
 MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#setBindArguments(String[]) parameter #0:
-    
+    Missing nullability on parameter `bindArgs` in method `setBindArguments`
 MissingNullability: android.database.sqlite.SQLiteGlobal#getDefaultJournalMode():
-    
+    Missing nullability on method `getDefaultJournalMode` return
 MissingNullability: android.database.sqlite.SQLiteGlobal#getDefaultSyncMode():
-    
+    Missing nullability on method `getDefaultSyncMode` return
 MissingNullability: android.database.sqlite.SQLiteGlobal#getWALSyncMode():
-    
+    Missing nullability on method `getWALSyncMode` return
 MissingNullability: android.graphics.ImageDecoder#createSource(android.content.res.Resources, java.io.InputStream, int) parameter #0:
-    
-MissingNullability: android.graphics.ImageDecoder#createSource(android.content.res.Resources, java.io.InputStream, int) parameter #1:
-    
+    Missing nullability on parameter `res` in method `createSource`
 MissingNullability: android.graphics.drawable.AdaptiveIconDrawable#getSafeZone():
-    
+    Missing nullability on method `getSafeZone` return
 MissingNullability: android.graphics.drawable.ColorDrawable#getXfermode():
-    
-MissingNullability: android.hardware.camera2.CameraDevice#createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) parameter #0:
-    
+    Missing nullability on method `getXfermode` return
 MissingNullability: android.hardware.camera2.CameraManager#getCameraIdListNoLazy():
-    
-MissingNullability: android.hardware.display.AmbientBrightnessDayStats#getBucketBoundaries():
-    
-MissingNullability: android.hardware.display.AmbientBrightnessDayStats#getLocalDate():
-    
-MissingNullability: android.hardware.display.AmbientBrightnessDayStats#getStats():
-    
-MissingNullability: android.hardware.display.AmbientBrightnessDayStats#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on method `getCameraIdListNoLazy` return
 MissingNullability: android.hardware.display.AmbientDisplayConfiguration#AmbientDisplayConfiguration(android.content.Context) parameter #0:
-    
-MissingNullability: android.hardware.display.BrightnessChangeEvent#luxTimestamps:
-    
-MissingNullability: android.hardware.display.BrightnessChangeEvent#luxValues:
-    
-MissingNullability: android.hardware.display.BrightnessChangeEvent#packageName:
-    
-MissingNullability: android.hardware.display.BrightnessChangeEvent#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.hardware.display.BrightnessConfiguration#getCurve():
-    
-MissingNullability: android.hardware.display.BrightnessConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.hardware.display.BrightnessConfiguration.Builder#Builder(float[], float[]) parameter #0:
-    
-MissingNullability: android.hardware.display.BrightnessConfiguration.Builder#Builder(float[], float[]) parameter #1:
-    
-MissingNullability: android.hardware.display.BrightnessCorrection#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.hardware.display.DisplayManager#getAmbientBrightnessStats():
-    
-MissingNullability: android.hardware.display.DisplayManager#getBrightnessConfiguration():
-    
-MissingNullability: android.hardware.display.DisplayManager#getBrightnessEvents():
-    
-MissingNullability: android.hardware.display.DisplayManager#getStableDisplaySize():
-    
-MissingNullability: android.hardware.display.DisplayManager#setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration) parameter #0:
-    
+    Missing nullability on parameter `context` in method `AmbientDisplayConfiguration`
 MissingNullability: android.location.GnssClock#set(android.location.GnssClock) parameter #0:
-    
+    Missing nullability on parameter `clock` in method `set`
 MissingNullability: android.location.GnssMeasurement#set(android.location.GnssMeasurement) parameter #0:
-    
-MissingNullability: android.location.GnssMeasurementsEvent#GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]) parameter #0:
-    
-MissingNullability: android.location.GnssMeasurementsEvent#GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]) parameter #1:
-    
+    Missing nullability on parameter `measurement` in method `set`
 MissingNullability: android.location.GnssNavigationMessage#set(android.location.GnssNavigationMessage) parameter #0:
-    
+    Missing nullability on parameter `navigationMessage` in method `set`
 MissingNullability: android.location.GnssNavigationMessage#setData(byte[]) parameter #0:
-    
-MissingNullability: android.location.LocationManager#getTestProviderCurrentRequests(String) parameter #0:
-    
-MissingNullability: android.location.LocationRequest#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.media.AudioAttributes#SDK_USAGES:
-    Missing nullability on field `SDK_USAGES` in class `class android.media.AudioAttributes`
+    Missing nullability on parameter `value` in method `setData`
 MissingNullability: android.media.AudioAttributes#getSdkUsages():
     Missing nullability on method `getSdkUsages` return
-MissingNullability: android.media.AudioFocusInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
 MissingNullability: android.media.AudioManager#getPublicStreamTypes():
     Missing nullability on method `getPublicStreamTypes` return
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String) parameter #3:
-    
+    Missing nullability on parameter `clientFormat` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String) parameter #4:
-    
+    Missing nullability on parameter `devFormat` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String) parameter #6:
-    
+    Missing nullability on parameter `packageName` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #10:
-    
+    Missing nullability on parameter `clientEffects` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #11:
-    
+    Missing nullability on parameter `deviceEffects` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #3:
-    
+    Missing nullability on parameter `clientFormat` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #4:
-    
+    Missing nullability on parameter `devFormat` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #6:
-    
-MissingNullability: android.media.AudioSystem#streamToString(int):
-    Missing nullability on method `streamToString` return
+    Missing nullability on parameter `packageName` in method `AudioRecordingConfiguration`
 MissingNullability: android.media.PlaybackParams#setAudioStretchMode(int):
-    
+    Missing nullability on method `setAudioStretchMode` return
 MissingNullability: android.media.audiofx.AudioEffect#EFFECT_TYPE_NULL:
-    
+    Missing nullability on field `EFFECT_TYPE_NULL` in class `class android.media.audiofx.AudioEffect`
 MissingNullability: android.media.audiofx.AudioEffect#byteArrayToInt(byte[]) parameter #0:
-    
+    Missing nullability on parameter `valueBuf` in method `byteArrayToInt`
 MissingNullability: android.media.audiofx.AudioEffect#byteArrayToShort(byte[]) parameter #0:
-    
+    Missing nullability on parameter `valueBuf` in method `byteArrayToShort`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(byte[], byte[]) parameter #0:
-    
+    Missing nullability on parameter `param` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(byte[], byte[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(int, byte[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(int, int[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(int, short[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(int[], short[]) parameter #0:
-    
+    Missing nullability on parameter `param` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#getParameter(int[], short[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `getParameter`
 MissingNullability: android.media.audiofx.AudioEffect#intToByteArray(int):
-    
+    Missing nullability on method `intToByteArray` return
 MissingNullability: android.media.audiofx.AudioEffect#isEffectTypeAvailable(java.util.UUID) parameter #0:
-    
+    Missing nullability on parameter `type` in method `isEffectTypeAvailable`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(byte[], byte[]) parameter #0:
-    
+    Missing nullability on parameter `param` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(byte[], byte[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(int, byte[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], byte[]) parameter #0:
-    
+    Missing nullability on parameter `param` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], byte[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], int[]) parameter #0:
-    
+    Missing nullability on parameter `param` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], int[]) parameter #1:
-    
+    Missing nullability on parameter `value` in method `setParameter`
 MissingNullability: android.media.audiofx.AudioEffect#setParameterListener(android.media.audiofx.AudioEffect.OnParameterChangeListener) parameter #0:
-    
+    Missing nullability on parameter `listener` in method `setParameterListener`
 MissingNullability: android.media.audiofx.AudioEffect#shortToByteArray(short):
-    
+    Missing nullability on method `shortToByteArray` return
 MissingNullability: android.media.audiofx.AudioEffect.Descriptor#Descriptor(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `in` in method `Descriptor`
 MissingNullability: android.media.audiofx.AudioEffect.Descriptor#writeToParcel(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `dest` in method `writeToParcel`
 MissingNullability: android.media.audiofx.AudioEffect.OnParameterChangeListener#onParameterChange(android.media.audiofx.AudioEffect, int, byte[], byte[]) parameter #0:
-    
+    Missing nullability on parameter `effect` in method `onParameterChange`
 MissingNullability: android.media.audiofx.AudioEffect.OnParameterChangeListener#onParameterChange(android.media.audiofx.AudioEffect, int, byte[], byte[]) parameter #2:
-    
+    Missing nullability on parameter `param` in method `onParameterChange`
 MissingNullability: android.media.audiofx.AudioEffect.OnParameterChangeListener#onParameterChange(android.media.audiofx.AudioEffect, int, byte[], byte[]) parameter #3:
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#Builder(android.media.audiopolicy.AudioMixingRule) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#build():
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#setDevice(android.media.AudioDeviceInfo):
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat):
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioMix.Builder#setRouteFlags(int):
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object):
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object) parameter #1:
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int):
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#build():
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object):
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object) parameter #1:
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int):
-    
-MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioRecordSink(android.media.audiopolicy.AudioMix):
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioRecordSink(android.media.audiopolicy.AudioMix) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioTrackSource(android.media.audiopolicy.AudioMix):
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioTrackSource(android.media.audiopolicy.AudioMix) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#setRegistration(String) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy#toLogFriendlyString():
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusAbandon(android.media.AudioFocusInfo) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusGrant(android.media.AudioFocusInfo, int) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusLoss(android.media.AudioFocusInfo, boolean) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusRequest(android.media.AudioFocusInfo, int) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener#onMixStateUpdate(android.media.audiopolicy.AudioMix) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.Builder#Builder(android.content.Context) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener) parameter #0:
-    
-MissingNullability: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#LogMaker(Object[]) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#addTaggedData(int, Object):
-    
-MissingNullability: android.metrics.LogMaker#addTaggedData(int, Object) parameter #1:
-    
-MissingNullability: android.metrics.LogMaker#clearCategory():
-    
-MissingNullability: android.metrics.LogMaker#clearPackageName():
-    
-MissingNullability: android.metrics.LogMaker#clearSubtype():
-    
-MissingNullability: android.metrics.LogMaker#clearTaggedData(int):
-    
-MissingNullability: android.metrics.LogMaker#clearType():
-    
-MissingNullability: android.metrics.LogMaker#deserialize(Object[]) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#getCounterName():
-    
-MissingNullability: android.metrics.LogMaker#getPackageName():
-    
-MissingNullability: android.metrics.LogMaker#getTaggedData(int):
-    
-MissingNullability: android.metrics.LogMaker#isSubsetOf(android.metrics.LogMaker) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#isValidValue(Object) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#serialize():
-    
-MissingNullability: android.metrics.LogMaker#setCategory(int):
-    
-MissingNullability: android.metrics.LogMaker#setPackageName(String):
-    
-MissingNullability: android.metrics.LogMaker#setPackageName(String) parameter #0:
-    
-MissingNullability: android.metrics.LogMaker#setSubtype(int):
-    
-MissingNullability: android.metrics.LogMaker#setType(int):
-    
-MissingNullability: android.metrics.MetricsReader#next():
-    
-MissingNullability: android.net.NetworkCapabilities#getCapabilities():
-    
-MissingNullability: android.net.StaticIpConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.net.TestNetworkInterface#CREATOR:
-    
-MissingNullability: android.net.TestNetworkInterface#TestNetworkInterface(android.os.ParcelFileDescriptor, String) parameter #0:
-    
-MissingNullability: android.net.TestNetworkInterface#TestNetworkInterface(android.os.ParcelFileDescriptor, String) parameter #1:
-    
-MissingNullability: android.net.TestNetworkInterface#getFileDescriptor():
-    
-MissingNullability: android.net.TestNetworkInterface#getInterfaceName():
-    
-MissingNullability: android.net.TestNetworkInterface#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.net.TestNetworkManager#createTapInterface():
-    
-MissingNullability: android.net.TestNetworkManager#createTunInterface(android.net.LinkAddress[]):
-    
-MissingNullability: android.net.apf.ApfCapabilities#CREATOR:
-    
-MissingNullability: android.net.apf.ApfCapabilities#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.net.metrics.DhcpClientEvent.Builder#setMsg(String) parameter #0:
-    
+    Missing nullability on parameter `value` in method `onParameterChange`
 MissingNullability: android.os.Build#is64BitAbi(String) parameter #0:
-    
+    Missing nullability on parameter `abi` in method `is64BitAbi`
 MissingNullability: android.os.Build.VERSION#ACTIVE_CODENAMES:
-    
+    Missing nullability on field `ACTIVE_CODENAMES` in class `class android.os.Build.VERSION`
 MissingNullability: android.os.Environment#buildPath(java.io.File, java.lang.String...):
-    
+    Missing nullability on method `buildPath` return
 MissingNullability: android.os.Environment#buildPath(java.io.File, java.lang.String...) parameter #0:
-    
+    Missing nullability on parameter `base` in method `buildPath`
 MissingNullability: android.os.Environment#buildPath(java.io.File, java.lang.String...) parameter #1:
-    
+    Missing nullability on parameter `segments` in method `buildPath`
 MissingNullability: android.os.FileUtils#contains(java.io.File, java.io.File) parameter #0:
-    
+    Missing nullability on parameter `dir` in method `contains`
 MissingNullability: android.os.FileUtils#contains(java.io.File, java.io.File) parameter #1:
-    
-MissingNullability: android.os.HwBinder#getService(String, String):
-    
-MissingNullability: android.os.HwBinder#getService(String, String) parameter #0:
-    
-MissingNullability: android.os.HwBinder#getService(String, String) parameter #1:
-    
-MissingNullability: android.os.HwBinder#getService(String, String, boolean):
-    
-MissingNullability: android.os.HwBinder#getService(String, String, boolean) parameter #0:
-    
-MissingNullability: android.os.HwBinder#getService(String, String, boolean) parameter #1:
-    
-MissingNullability: android.os.HwBinder#onTransact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #1:
-    
-MissingNullability: android.os.HwBinder#onTransact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #2:
-    
-MissingNullability: android.os.HwBinder#registerService(String) parameter #0:
-    
-MissingNullability: android.os.HwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #1:
-    
-MissingNullability: android.os.HwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #2:
-    
-MissingNullability: android.os.HwBlob#copyToBoolArray(long, boolean[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToDoubleArray(long, double[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToFloatArray(long, float[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToInt16Array(long, short[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToInt32Array(long, int[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToInt64Array(long, long[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#copyToInt8Array(long, byte[], int) parameter #1:
-    
-MissingNullability: android.os.HwBlob#getString(long):
-    
-MissingNullability: android.os.HwBlob#putBlob(long, android.os.HwBlob) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putBoolArray(long, boolean[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putDoubleArray(long, double[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putFloatArray(long, float[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putInt16Array(long, short[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putInt32Array(long, int[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putInt64Array(long, long[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putInt8Array(long, byte[]) parameter #1:
-    
-MissingNullability: android.os.HwBlob#putString(long, String) parameter #1:
-    
-MissingNullability: android.os.HwBlob#wrapArray(boolean[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(byte[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(double[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(float[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(int[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(long[]):
-    
-MissingNullability: android.os.HwBlob#wrapArray(short[]):
-    
-MissingNullability: android.os.HwParcel#enforceInterface(String) parameter #0:
-    
-MissingNullability: android.os.HwParcel#readBoolVector():
-    
-MissingNullability: android.os.HwParcel#readBuffer(long):
-    
-MissingNullability: android.os.HwParcel#readDoubleVector():
-    
-MissingNullability: android.os.HwParcel#readEmbeddedBuffer(long, long, long, boolean):
-    
-MissingNullability: android.os.HwParcel#readFloatVector():
-    
-MissingNullability: android.os.HwParcel#readInt16Vector():
-    
-MissingNullability: android.os.HwParcel#readInt32Vector():
-    
-MissingNullability: android.os.HwParcel#readInt64Vector():
-    
-MissingNullability: android.os.HwParcel#readInt8Vector():
-    
-MissingNullability: android.os.HwParcel#readString():
-    
-MissingNullability: android.os.HwParcel#readStringVector():
-    
-MissingNullability: android.os.HwParcel#readStrongBinder():
-    
-MissingNullability: android.os.HwParcel#writeBoolVector(java.util.ArrayList<java.lang.Boolean>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeBuffer(android.os.HwBlob) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeDoubleVector(java.util.ArrayList<java.lang.Double>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeFloatVector(java.util.ArrayList<java.lang.Float>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeInt16Vector(java.util.ArrayList<java.lang.Short>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeInt32Vector(java.util.ArrayList<java.lang.Integer>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeInt64Vector(java.util.ArrayList<java.lang.Long>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeInt8Vector(java.util.ArrayList<java.lang.Byte>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeInterfaceToken(String) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeString(String) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeStringVector(java.util.ArrayList<java.lang.String>) parameter #0:
-    
-MissingNullability: android.os.HwParcel#writeStrongBinder(android.os.IHwBinder) parameter #0:
-    
-MissingNullability: android.os.IHwBinder#linkToDeath(android.os.IHwBinder.DeathRecipient, long) parameter #0:
-    
-MissingNullability: android.os.IHwBinder#queryLocalInterface(String):
-    
-MissingNullability: android.os.IHwBinder#queryLocalInterface(String) parameter #0:
-    
-MissingNullability: android.os.IHwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #1:
-    
-MissingNullability: android.os.IHwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #2:
-    
-MissingNullability: android.os.IHwBinder#unlinkToDeath(android.os.IHwBinder.DeathRecipient) parameter #0:
-    
-MissingNullability: android.os.IHwInterface#asBinder():
-    
-MissingNullability: android.os.IncidentManager#approveReport(android.net.Uri) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#cancelAuthorization(android.os.IncidentManager.AuthListener) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#deleteIncidentReports(android.net.Uri) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#denyReport(android.net.Uri) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#getIncidentReport(android.net.Uri) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#getIncidentReportList(String) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#getPendingReports():
-    
-MissingNullability: android.os.IncidentManager#reportIncident(android.os.IncidentReportArgs) parameter #0:
-    
-MissingNullability: android.os.IncidentManager#requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener) parameter #1:
-    
-MissingNullability: android.os.IncidentManager#requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener) parameter #3:
-    
-MissingNullability: android.os.IncidentManager.IncidentReport#IncidentReport(android.os.Parcel) parameter #0:
-    
-MissingNullability: android.os.IncidentManager.IncidentReport#getInputStream():
-    
-MissingNullability: android.os.IncidentManager.IncidentReport#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.os.IncidentReportArgs#IncidentReportArgs(android.os.Parcel) parameter #0:
-    
-MissingNullability: android.os.IncidentReportArgs#addHeader(byte[]) parameter #0:
-    
-MissingNullability: android.os.IncidentReportArgs#readFromParcel(android.os.Parcel) parameter #0:
-    
-MissingNullability: android.os.IncidentReportArgs#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `file` in method `contains`
 MissingNullability: android.os.ParcelFileDescriptor#getFile(java.io.FileDescriptor):
-    
+    Missing nullability on method `getFile` return
 MissingNullability: android.os.ParcelFileDescriptor#getFile(java.io.FileDescriptor) parameter #0:
-    
-MissingNullability: android.os.RemoteCallback#RemoteCallback(android.os.RemoteCallback.OnResultListener) parameter #0:
-    
-MissingNullability: android.os.RemoteCallback#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `fd` in method `getFile`
 MissingNullability: android.os.StrictMode#setViolationLogger(android.os.StrictMode.ViolationLogger) parameter #0:
-    
+    Missing nullability on parameter `listener` in method `setViolationLogger`
 MissingNullability: android.os.StrictMode.ViolationInfo#ViolationInfo(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `in` in method `ViolationInfo`
 MissingNullability: android.os.StrictMode.ViolationInfo#ViolationInfo(android.os.Parcel, boolean) parameter #0:
-    
+    Missing nullability on parameter `in` in method `ViolationInfo`
 MissingNullability: android.os.StrictMode.ViolationInfo#broadcastIntentAction:
-    
+    Missing nullability on field `broadcastIntentAction` in class `class android.os.StrictMode.ViolationInfo`
 MissingNullability: android.os.StrictMode.ViolationInfo#dump(android.util.Printer, String) parameter #0:
-    
+    Missing nullability on parameter `pw` in method `dump`
 MissingNullability: android.os.StrictMode.ViolationInfo#dump(android.util.Printer, String) parameter #1:
-    
+    Missing nullability on parameter `prefix` in method `dump`
 MissingNullability: android.os.StrictMode.ViolationInfo#getStackTrace():
-    
+    Missing nullability on method `getStackTrace` return
 MissingNullability: android.os.StrictMode.ViolationInfo#getViolationClass():
-    
+    Missing nullability on method `getViolationClass` return
 MissingNullability: android.os.StrictMode.ViolationInfo#getViolationDetails():
-    
+    Missing nullability on method `getViolationDetails` return
 MissingNullability: android.os.StrictMode.ViolationInfo#tags:
-    
+    Missing nullability on field `tags` in class `class android.os.StrictMode.ViolationInfo`
 MissingNullability: android.os.StrictMode.ViolationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `dest` in method `writeToParcel`
 MissingNullability: android.os.StrictMode.ViolationLogger#log(android.os.StrictMode.ViolationInfo) parameter #0:
-    
-MissingNullability: android.os.UserHandle#of(int):
-    
+    Missing nullability on parameter `info` in method `log`
 MissingNullability: android.os.VibrationEffect#RINGTONES:
-    
+    Missing nullability on field `RINGTONES` in class `class android.os.VibrationEffect`
 MissingNullability: android.os.VibrationEffect#get(android.net.Uri, android.content.Context) parameter #0:
-    
+    Missing nullability on parameter `uri` in method `get`
 MissingNullability: android.os.VibrationEffect#get(android.net.Uri, android.content.Context) parameter #1:
-    
+    Missing nullability on parameter `context` in method `get`
 MissingNullability: android.os.VibrationEffect#get(int):
-    
+    Missing nullability on method `get` return
 MissingNullability: android.os.VibrationEffect#get(int, boolean):
-    
+    Missing nullability on method `get` return
 MissingNullability: android.os.VintfObject#getHalNamesAndVersions():
-    
+    Missing nullability on method `getHalNamesAndVersions` return
 MissingNullability: android.os.VintfObject#getSepolicyVersion():
-    
+    Missing nullability on method `getSepolicyVersion` return
 MissingNullability: android.os.VintfObject#getTargetFrameworkCompatibilityMatrixVersion():
-    
+    Missing nullability on method `getTargetFrameworkCompatibilityMatrixVersion` return
 MissingNullability: android.os.VintfObject#getVndkSnapshots():
-    
+    Missing nullability on method `getVndkSnapshots` return
 MissingNullability: android.os.VintfObject#report():
-    
+    Missing nullability on method `report` return
 MissingNullability: android.os.VintfRuntimeInfo#getCpuInfo():
-    
+    Missing nullability on method `getCpuInfo` return
 MissingNullability: android.os.VintfRuntimeInfo#getHardwareId():
-    
+    Missing nullability on method `getHardwareId` return
 MissingNullability: android.os.VintfRuntimeInfo#getKernelVersion():
-    
+    Missing nullability on method `getKernelVersion` return
 MissingNullability: android.os.VintfRuntimeInfo#getNodeName():
-    
+    Missing nullability on method `getNodeName` return
 MissingNullability: android.os.VintfRuntimeInfo#getOsName():
-    
+    Missing nullability on method `getOsName` return
 MissingNullability: android.os.VintfRuntimeInfo#getOsRelease():
-    
+    Missing nullability on method `getOsRelease` return
 MissingNullability: android.os.VintfRuntimeInfo#getOsVersion():
-    
+    Missing nullability on method `getOsVersion` return
 MissingNullability: android.os.WorkSource#add(int, String) parameter #1:
-    
-MissingNullability: android.os.WorkSource#addReturningNewbs(android.os.WorkSource) parameter #0:
-    
-MissingNullability: android.os.WorkSource#getName(int):
-    
-MissingNullability: android.os.WorkSource#setReturningDiffs(android.os.WorkSource) parameter #0:
-    
+    Missing nullability on parameter `name` in method `add`
 MissingNullability: android.os.health.HealthKeys.Constants#Constants(Class) parameter #0:
-    
+    Missing nullability on parameter `clazz` in method `Constants`
 MissingNullability: android.os.health.HealthKeys.Constants#getDataType():
-    
+    Missing nullability on method `getDataType` return
 MissingNullability: android.os.health.HealthKeys.Constants#getKeys(int):
-    
+    Missing nullability on method `getKeys` return
 MissingNullability: android.os.health.HealthStats#HealthStats(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `in` in method `HealthStats`
 MissingNullability: android.os.health.HealthStatsParceler#HealthStatsParceler(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `in` in method `HealthStatsParceler`
 MissingNullability: android.os.health.HealthStatsParceler#HealthStatsParceler(android.os.health.HealthStatsWriter) parameter #0:
-    
+    Missing nullability on parameter `writer` in method `HealthStatsParceler`
 MissingNullability: android.os.health.HealthStatsParceler#getHealthStats():
-    
+    Missing nullability on method `getHealthStats` return
 MissingNullability: android.os.health.HealthStatsParceler#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `out` in method `writeToParcel`
 MissingNullability: android.os.health.HealthStatsWriter#HealthStatsWriter(android.os.health.HealthKeys.Constants) parameter #0:
-    
+    Missing nullability on parameter `constants` in method `HealthStatsWriter`
 MissingNullability: android.os.health.HealthStatsWriter#addMeasurements(int, String, long) parameter #1:
-    
+    Missing nullability on parameter `name` in method `addMeasurements`
 MissingNullability: android.os.health.HealthStatsWriter#addStats(int, String, android.os.health.HealthStatsWriter) parameter #1:
-    
+    Missing nullability on parameter `name` in method `addStats`
 MissingNullability: android.os.health.HealthStatsWriter#addStats(int, String, android.os.health.HealthStatsWriter) parameter #2:
-    
+    Missing nullability on parameter `value` in method `addStats`
 MissingNullability: android.os.health.HealthStatsWriter#addTimers(int, String, android.os.health.TimerStat) parameter #1:
-    
+    Missing nullability on parameter `name` in method `addTimers`
 MissingNullability: android.os.health.HealthStatsWriter#addTimers(int, String, android.os.health.TimerStat) parameter #2:
-    
+    Missing nullability on parameter `value` in method `addTimers`
 MissingNullability: android.os.health.HealthStatsWriter#flattenToParcel(android.os.Parcel) parameter #0:
-    
+    Missing nullability on parameter `out` in method `flattenToParcel`
 MissingNullability: android.os.storage.StorageVolume#getPath():
-    
-MissingNullability: android.permission.RuntimePermissionPresentationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on method `getPath` return
 MissingNullability: android.provider.CalendarContract.Calendars#SYNC_WRITABLE_COLUMNS:
-    
+    Missing nullability on field `SYNC_WRITABLE_COLUMNS` in class `class android.provider.CalendarContract.Calendars`
 MissingNullability: android.provider.CalendarContract.Events#SYNC_WRITABLE_COLUMNS:
-    
-MissingNullability: android.provider.ContactsContract.CommonDataKinds.Phone#ENTERPRISE_CONTENT_URI:
-    
+    Missing nullability on field `SYNC_WRITABLE_COLUMNS` in class `class android.provider.CalendarContract.Events`
 MissingNullability: android.provider.ContactsContract.RawContactsEntity#CORP_CONTENT_URI:
-    
-MissingNullability: android.provider.DeviceConfig#getProperty(String, String):
-    
-MissingNullability: android.provider.DeviceConfig#getString(String, String, String):
-    
-MissingNullability: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle) parameter #0:
-    
-MissingNullability: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle) parameter #1:
-    
-MissingNullability: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle) parameter #2:
-    
-MissingNullability: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle) parameter #0:
-    
-MissingNullability: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle) parameter #1:
-    
-MissingNullability: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle) parameter #2:
-    
-MissingNullability: android.provider.MediaStore#scanFile(android.content.Context, java.io.File):
-    
-MissingNullability: android.provider.MediaStore#scanFile(android.content.Context, java.io.File) parameter #0:
-    
-MissingNullability: android.provider.MediaStore#scanFile(android.content.Context, java.io.File) parameter #1:
-    
-MissingNullability: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File):
-    
-MissingNullability: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File) parameter #0:
-    
-MissingNullability: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File) parameter #1:
-    
-MissingNullability: android.provider.MediaStore#scanVolume(android.content.Context, java.io.File) parameter #0:
-    
-MissingNullability: android.provider.MediaStore#scanVolume(android.content.Context, java.io.File) parameter #1:
-    
-MissingNullability: android.provider.MediaStore#waitForIdle(android.content.Context) parameter #0:
-    
-MissingNullability: android.security.KeyStoreException#KeyStoreException(int, String) parameter #1:
-    
-MissingNullability: android.security.keystore.AttestationUtils#attestDeviceIds(android.content.Context, int[], byte[]) parameter #0:
-    
+    Missing nullability on field `CORP_CONTENT_URI` in class `class android.provider.ContactsContract.RawContactsEntity`
 MissingNullability: android.security.keystore.KeyProtection.Builder#setBoundToSpecificSecureUserId(long):
-    
-MissingNullability: android.service.autofill.AutofillFieldClassificationService#onBind(android.content.Intent):
-    
-MissingNullability: android.service.autofill.AutofillFieldClassificationService#onBind(android.content.Intent) parameter #0:
-    
+    Missing nullability on method `setBoundToSpecificSecureUserId` return
 MissingNullability: android.service.autofill.CompositeUserData#getCategoryIds():
-    
+    Missing nullability on method `getCategoryIds` return
 MissingNullability: android.service.autofill.CompositeUserData#getDefaultFieldClassificationArgs():
-    
+    Missing nullability on method `getDefaultFieldClassificationArgs` return
 MissingNullability: android.service.autofill.CompositeUserData#getFieldClassificationAlgorithms():
-    
+    Missing nullability on method `getFieldClassificationAlgorithms` return
 MissingNullability: android.service.autofill.CompositeUserData#getFieldClassificationArgs():
-    
+    Missing nullability on method `getFieldClassificationArgs` return
 MissingNullability: android.service.autofill.CompositeUserData#getValues():
-    
+    Missing nullability on method `getValues` return
 MissingNullability: android.service.autofill.CompositeUserData#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `parcel` in method `writeToParcel`
 MissingNullability: android.service.autofill.UserData#getFieldClassificationAlgorithms():
-    
-MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
-    
-MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
-    
-MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
-    
-MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#onUnbind(android.content.Intent) parameter #0:
-    
-MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
-    
-MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
-    
-MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
-    
-MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #0:
-    
-MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #1:
-    
-MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #2:
-    
-MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #3:
-    
-MissingNullability: android.service.notification.Adjustment#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context) parameter #0:
-    
-MissingNullability: android.service.notification.NotificationStats#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(String, CharSequence, CharSequence) parameter #0:
-    
-MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(String, CharSequence, CharSequence) parameter #1:
-    
-MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(String, CharSequence, CharSequence) parameter #2:
-    
-MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(android.os.Parcel) parameter #0:
-    
-MissingNullability: android.service.notification.SnoozeCriterion#getConfirmation():
-    
-MissingNullability: android.service.notification.SnoozeCriterion#getExplanation():
-    
-MissingNullability: android.service.notification.SnoozeCriterion#getId():
-    
-MissingNullability: android.service.notification.SnoozeCriterion#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on method `getFieldClassificationAlgorithms` return
 MissingNullability: android.telecom.Call.Details#getTelecomCallId():
-    
-MissingNullability: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallFurther(boolean):
-    
-MissingNullability: android.telecom.Conference#getPrimaryConnection():
-    
-MissingNullability: android.telecom.PhoneAccountSuggestionService#onBind(android.content.Intent):
-    
-MissingNullability: android.telecom.PhoneAccountSuggestionService#onBind(android.content.Intent) parameter #0:
-    
-MissingNullability: android.telephony.CallQuality#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.DataSpecificRegistrationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.LteVopsSupportInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.NetworkRegistrationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on method `getTelecomCallId` return
 MissingNullability: android.telephony.ServiceState#addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo) parameter #0:
-    
+    Missing nullability on parameter `nri` in method `addNetworkRegistrationInfo`
 MissingNullability: android.telephony.ServiceState#setCellBandwidths(int[]) parameter #0:
-    
+    Missing nullability on parameter `bandwidths` in method `setCellBandwidths`
 MissingNullability: android.telephony.SmsManager#checkSmsShortCodeDestination(String, String) parameter #0:
-    
+    Missing nullability on parameter `destAddress` in method `checkSmsShortCodeDestination`
 MissingNullability: android.telephony.SmsManager#checkSmsShortCodeDestination(String, String) parameter #1:
-    
-MissingNullability: android.telephony.TelephonyManager#checkCarrierPrivilegesForPackage(String) parameter #0:
-    
-MissingNullability: android.telephony.TelephonyManager#getCarrierPackageNamesForIntent(android.content.Intent):
-    
-MissingNullability: android.telephony.TelephonyManager#getCarrierPackageNamesForIntent(android.content.Intent) parameter #0:
-    
+    Missing nullability on parameter `countryIso` in method `checkSmsShortCodeDestination`
 MissingNullability: android.telephony.TelephonyManager#getLine1AlphaTag():
-    
+    Missing nullability on method `getLine1AlphaTag` return
 MissingNullability: android.telephony.TelephonyManager#getRadioHalVersion():
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #0:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #1:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #2:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #3:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #4:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #5:
-    
-MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #6:
-    
+    Missing nullability on method `getRadioHalVersion` return
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #0:
-    
+    Missing nullability on parameter `mccmnc` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #1:
-    
+    Missing nullability on parameter `imsi` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #2:
-    
+    Missing nullability on parameter `iccid` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #3:
-    
+    Missing nullability on parameter `gid1` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #4:
-    
+    Missing nullability on parameter `gid2` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #5:
-    
+    Missing nullability on parameter `plmn` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #6:
-    
+    Missing nullability on parameter `spn` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #7:
-    
+    Missing nullability on parameter `carrierPriviledgeRules` in method `setCarrierTestOverride`
 MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #8:
-    
-MissingNullability: android.telephony.ims.ImsCallForwardInfo#getNumber():
-    
-MissingNullability: android.telephony.ims.ImsCallForwardInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile) parameter #2:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile) parameter #3:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String):
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String):
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraBoolean(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraBoolean(String, boolean) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraInt(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraInt(String, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtras():
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getMediaProfile():
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtra(String, String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtra(String, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtraBoolean(String, boolean) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtraInt(String, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#updateCallExtras(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#updateCallType(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#updateMediaProfile(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallProfile#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo) parameter #2:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo) parameter #2:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHeld(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHoldFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHoldReceived(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInitiated(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumeFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumeReceived(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumed(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRttMessageReceived(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionTerminated(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdateReceived(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdated(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUssdMessageReceived(int, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsConferenceState#getConnectionStateForStatus(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsConferenceState#mParticipants:
-    
-MissingNullability: android.telephony.ims.ImsConferenceState#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsExternalCallState#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsReasonInfo#ImsReasonInfo(int, int, String) parameter #2:
-    
-MissingNullability: android.telephony.ims.ImsReasonInfo#getExtraMessage():
-    
-MissingNullability: android.telephony.ims.ImsReasonInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsService#createMmTelFeature(int):
-    
-MissingNullability: android.telephony.ims.ImsService#createRcsFeature(int):
-    
-MissingNullability: android.telephony.ims.ImsService#getConfig(int):
-    
-MissingNullability: android.telephony.ims.ImsService#getRegistration(int):
-    
-MissingNullability: android.telephony.ims.ImsService#onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsService#querySupportedImsFeatures():
-    
-MissingNullability: android.telephony.ims.ImsSsData#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsSsInfo#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsStreamMediaProfile#copyFrom(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsStreamMediaProfile#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsSuppServiceNotification#ImsSuppServiceNotification(int, int, int, int, String, String[]) parameter #4:
-    
-MissingNullability: android.telephony.ims.ImsSuppServiceNotification#ImsSuppServiceNotification(int, int, int, int, String, String[]) parameter #5:
-    
-MissingNullability: android.telephony.ims.ImsSuppServiceNotification#history:
-    
-MissingNullability: android.telephony.ims.ImsSuppServiceNotification#number:
-    
-MissingNullability: android.telephony.ims.ImsSuppServiceNotification#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onSupplementaryServiceIndication(android.telephony.ims.ImsSsData) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationQueried(int, android.os.Bundle) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyResponse(android.telecom.VideoProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetCamera(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetCamera(String, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetDisplaySurface(android.view.Surface) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetPauseImage(android.net.Uri) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetPreviewSurface(android.view.Surface) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyRequest(android.telecom.VideoProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #2:
-    
-MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToDisable():
-    
-MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToEnable():
-    
-MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.feature.ImsFeature#changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy) parameter #0:
-    
-MissingNullability: android.telephony.ims.feature.ImsFeature#changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy) parameter #1:
-    
-MissingNullability: android.telephony.ims.feature.MmTelFeature#queryCapabilityStatus():
-    
-MissingNullability: android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#accept(int, android.telephony.ims.ImsStreamMediaProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#deflect(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#extendToConference(String[]) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getCallId():
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getCallProfile():
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getImsVideoCallProvider():
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getLocalCallProfile():
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getProperty(String):
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getProperty(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getRemoteCallProfile():
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#hold(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#inviteParticipants(String[]) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#removeParticipants(String[]) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#resume(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendDtmf(char, android.os.Message) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendRttMessage(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendRttModifyRequest(android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendUssd(String) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#setListener(android.telephony.ims.ImsCallSessionListener) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#start(String, android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#start(String, android.telephony.ims.ImsCallProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#startConference(String[], android.telephony.ims.ImsCallProfile) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#startConference(String[], android.telephony.ims.ImsCallProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#update(int, android.telephony.ims.ImsStreamMediaProfile) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase.State#toString(int):
-    
-MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#getConfigString(int):
-    
-MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#notifyProvisionedValueChanged(int, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#setConfig(int, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration#getServiceFeatures():
-    
-MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration.Builder#addFeature(int, int):
-    
-MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration.Builder#build():
-    
-MissingNullability: android.telephony.ims.stub.ImsMultiEndpointImplBase#onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onDeregistered(android.telephony.ims.ImsReasonInfo) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onSubscriberAssociatedUriChanged(android.net.Uri[]) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#getSmsFormat():
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsReceived(int, String, byte[]) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsReceived(int, String, byte[]) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, String, byte[]) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, String, byte[]) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, int, String, byte[]) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, int, String, byte[]) parameter #3:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #3:
-    
-MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #5:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#queryCallForward(int, String) parameter #1:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#setListener(android.telephony.ims.ImsUtListener) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#transact(android.os.Bundle) parameter #0:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallBarring(int, int, String[]) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallBarringForServiceClass(int, int, String[], int) parameter #2:
-    
-MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallForward(int, int, String, int, int) parameter #2:
-    
-MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
-    
-MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String) parameter #0:
-    
-MissingNullability: android.telephony.mbms.FileInfo#FileInfo(android.net.Uri, String) parameter #0:
-    
-MissingNullability: android.telephony.mbms.FileInfo#FileInfo(android.net.Uri, String) parameter #1:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #0:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #1:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #2:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #3:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #4:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #5:
-    
-MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #6:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #0:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #1:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #2:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #3:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #4:
-    
-MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #5:
-    
-MissingNullability: android.telephony.mbms.UriPathPair#getContentUri():
-    
-MissingNullability: android.telephony.mbms.UriPathPair#getFilePathUri():
-    
-MissingNullability: android.telephony.mbms.UriPathPair#writeToParcel(android.os.Parcel, int) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#asBinder():
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#cancelDownload(android.telephony.mbms.DownloadRequest) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#download(android.telephony.mbms.DownloadRequest) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #2:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestUpdateFileServices(int, java.util.List<java.lang.String>) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#setTempFileRootDirectory(int, String) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#onBind(android.content.Intent):
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#onBind(android.content.Intent) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#asBinder():
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#getPlaybackUri(int, String) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #2:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#requestUpdateStreamingServices(int, java.util.List<java.lang.String>) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) parameter #2:
-    
-MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#stopStreaming(int, String) parameter #1:
-    
-MissingNullability: android.telephony.mbms.vendor.VendorUtils#getAppReceiverFromPackageName(android.content.Context, String):
-    
-MissingNullability: android.telephony.mbms.vendor.VendorUtils#getAppReceiverFromPackageName(android.content.Context, String) parameter #0:
-    
-MissingNullability: android.telephony.mbms.vendor.VendorUtils#getAppReceiverFromPackageName(android.content.Context, String) parameter #1:
-    
+    Missing nullability on parameter `apn` in method `setCarrierTestOverride`
 MissingNullability: android.text.Selection.MemoryTextWatcher#afterTextChanged(android.text.Editable) parameter #0:
-    
+    Missing nullability on parameter `s` in method `afterTextChanged`
 MissingNullability: android.text.Selection.MemoryTextWatcher#beforeTextChanged(CharSequence, int, int, int) parameter #0:
-    
+    Missing nullability on parameter `s` in method `beforeTextChanged`
 MissingNullability: android.text.Selection.MemoryTextWatcher#onTextChanged(CharSequence, int, int, int) parameter #0:
-    
+    Missing nullability on parameter `s` in method `onTextChanged`
 MissingNullability: android.transition.TransitionManager#getTransition(android.transition.Scene):
-    
+    Missing nullability on method `getTransition` return
 MissingNullability: android.transition.TransitionManager#getTransition(android.transition.Scene) parameter #0:
-    
+    Missing nullability on parameter `scene` in method `getTransition`
 MissingNullability: android.util.FeatureFlagUtils#getAllFeatureFlags():
-    
+    Missing nullability on method `getAllFeatureFlags` return
 MissingNullability: android.util.FeatureFlagUtils#isEnabled(android.content.Context, String) parameter #0:
-    
+    Missing nullability on parameter `context` in method `isEnabled`
 MissingNullability: android.util.FeatureFlagUtils#isEnabled(android.content.Context, String) parameter #1:
-    
+    Missing nullability on parameter `feature` in method `isEnabled`
 MissingNullability: android.util.FeatureFlagUtils#setEnabled(android.content.Context, String, boolean) parameter #0:
-    
+    Missing nullability on parameter `context` in method `setEnabled`
 MissingNullability: android.util.FeatureFlagUtils#setEnabled(android.content.Context, String, boolean) parameter #1:
-    
+    Missing nullability on parameter `feature` in method `setEnabled`
 MissingNullability: android.util.TimeUtils#formatDuration(long):
-    
+    Missing nullability on method `formatDuration` return
 MissingNullability: android.util.proto.EncodedBuffer#dumpBuffers(String) parameter #0:
-    
+    Missing nullability on parameter `tag` in method `dumpBuffers`
 MissingNullability: android.util.proto.EncodedBuffer#dumpByteString(String, String, byte[]) parameter #0:
-    
+    Missing nullability on parameter `tag` in method `dumpByteString`
 MissingNullability: android.util.proto.EncodedBuffer#dumpByteString(String, String, byte[]) parameter #1:
-    
+    Missing nullability on parameter `prefix` in method `dumpByteString`
 MissingNullability: android.util.proto.EncodedBuffer#dumpByteString(String, String, byte[]) parameter #2:
-    
+    Missing nullability on parameter `buf` in method `dumpByteString`
 MissingNullability: android.util.proto.EncodedBuffer#getBytes(int):
-    
+    Missing nullability on method `getBytes` return
 MissingNullability: android.util.proto.EncodedBuffer#getDebugString():
-    
+    Missing nullability on method `getDebugString` return
 MissingNullability: android.util.proto.EncodedBuffer#writeRawBuffer(byte[]) parameter #0:
-    
+    Missing nullability on parameter `val` in method `writeRawBuffer`
 MissingNullability: android.util.proto.EncodedBuffer#writeRawBuffer(byte[], int, int) parameter #0:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.FileDescriptor) parameter #0:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.OutputStream) parameter #0:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#dump(String) parameter #0:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#getBytes():
-    
-MissingNullability: android.util.proto.ProtoOutputStream#write(long, String) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#write(long, byte[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeBytes(long, byte[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeObject(long, byte[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedBool(long, boolean[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedDouble(long, double[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedEnum(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedFixed32(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedFixed64(long, long[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedFloat(long, float[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedInt32(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedInt64(long, long[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedSFixed32(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedSFixed64(long, long[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedSInt32(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedSInt64(long, long[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedUInt32(long, int[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writePackedUInt64(long, long[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeRepeatedBytes(long, byte[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeRepeatedObject(long, byte[]) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeRepeatedString(long, String) parameter #1:
-    
-MissingNullability: android.util.proto.ProtoOutputStream#writeString(long, String) parameter #1:
-    
+    Missing nullability on parameter `val` in method `writeRawBuffer`
 MissingNullability: android.util.proto.ProtoParseException#ProtoParseException(String) parameter #0:
-    
-MissingNullability: android.util.proto.ProtoStream#FIELD_TYPE_NAMES:
-    
-MissingNullability: android.util.proto.ProtoStream#getFieldCountString(long):
-    
-MissingNullability: android.util.proto.ProtoStream#getFieldIdString(long):
-    
-MissingNullability: android.util.proto.ProtoStream#getFieldTypeString(long):
-    
-MissingNullability: android.util.proto.ProtoStream#getWireTypeString(int):
-    
-MissingNullability: android.util.proto.ProtoStream#token2String(long):
-    
+    Missing nullability on parameter `msg` in method `ProtoParseException`
 MissingNullability: android.util.proto.WireTypeMismatchException#WireTypeMismatchException(String) parameter #0:
-    
+    Missing nullability on parameter `msg` in method `WireTypeMismatchException`
 MissingNullability: android.view.Choreographer#postCallback(int, Runnable, Object) parameter #1:
-    
+    Missing nullability on parameter `action` in method `postCallback`
 MissingNullability: android.view.Choreographer#postCallback(int, Runnable, Object) parameter #2:
-    
+    Missing nullability on parameter `token` in method `postCallback`
 MissingNullability: android.view.Choreographer#postCallbackDelayed(int, Runnable, Object, long) parameter #1:
-    
+    Missing nullability on parameter `action` in method `postCallbackDelayed`
 MissingNullability: android.view.Choreographer#postCallbackDelayed(int, Runnable, Object, long) parameter #2:
-    
+    Missing nullability on parameter `token` in method `postCallbackDelayed`
 MissingNullability: android.view.Choreographer#removeCallbacks(int, Runnable, Object) parameter #1:
-    
+    Missing nullability on parameter `action` in method `removeCallbacks`
 MissingNullability: android.view.Choreographer#removeCallbacks(int, Runnable, Object) parameter #2:
-    
+    Missing nullability on parameter `token` in method `removeCallbacks`
 MissingNullability: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #0:
-    
+    Missing nullability on parameter `views` in method `sort`
 MissingNullability: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #3:
-    
+    Missing nullability on parameter `root` in method `sort`
 MissingNullability: android.view.KeyEvent#actionToString(int):
-    
-MissingNullability: android.view.SurfaceControlViewHost#SurfaceControlViewHost(android.content.Context, android.view.Display, android.view.SurfaceControl) parameter #0:
-    
-MissingNullability: android.view.SurfaceControlViewHost#SurfaceControlViewHost(android.content.Context, android.view.Display, android.view.SurfaceControl) parameter #1:
-    
-MissingNullability: android.view.SurfaceControlViewHost#SurfaceControlViewHost(android.content.Context, android.view.Display, android.view.SurfaceControl) parameter #2:
-    
-MissingNullability: android.view.SurfaceControlViewHost#addView(android.view.View, android.view.WindowManager.LayoutParams) parameter #0:
-    
-MissingNullability: android.view.SurfaceControlViewHost#addView(android.view.View, android.view.WindowManager.LayoutParams) parameter #1:
-    
+    Missing nullability on method `actionToString` return
 MissingNullability: android.view.SurfaceControlViewHost#relayout(android.view.WindowManager.LayoutParams) parameter #0:
-    
+    Missing nullability on parameter `attrs` in method `relayout`
 MissingNullability: android.view.View#getTooltipView():
-    
+    Missing nullability on method `getTooltipView` return
 MissingNullability: android.view.View#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #0:
-    
+    Missing nullability on parameter `background` in method `isDefaultFocusHighlightNeeded`
 MissingNullability: android.view.View#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #1:
-    
+    Missing nullability on parameter `foreground` in method `isDefaultFocusHighlightNeeded`
 MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.concurrent.Callable<java.io.OutputStream>) parameter #0:
-    
+    Missing nullability on parameter `tree` in method `startRenderingCommandsCapture`
 MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.concurrent.Callable<java.io.OutputStream>) parameter #1:
-    
+    Missing nullability on parameter `executor` in method `startRenderingCommandsCapture`
 MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.concurrent.Callable<java.io.OutputStream>) parameter #2:
-    
-MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>) parameter #0:
-    
-MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>) parameter #1:
-    
-MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>) parameter #2:
-    
+    Missing nullability on parameter `callback` in method `startRenderingCommandsCapture`
 MissingNullability: android.view.WindowManager#holdLock(android.os.IBinder, int) parameter #0:
-    
+    Missing nullability on parameter `token` in method `holdLock`
 MissingNullability: android.view.WindowManager.LayoutParams#accessibilityTitle:
-    
-MissingNullability: android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener#onAccessibilityServicesStateChanged(android.view.accessibility.AccessibilityManager) parameter #0:
-    
-MissingNullability: android.view.accessibility.AccessibilityNodeInfo#setNumInstancesInUseCounter(java.util.concurrent.atomic.AtomicInteger) parameter #0:
-    
+    Missing nullability on field `accessibilityTitle` in class `class android.view.WindowManager.LayoutParams`
 MissingNullability: android.view.accessibility.AccessibilityNodeInfo#writeToParcelNoRecycle(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `parcel` in method `writeToParcelNoRecycle`
 MissingNullability: android.view.accessibility.AccessibilityWindowInfo#setNumInstancesInUseCounter(java.util.concurrent.atomic.AtomicInteger) parameter #0:
-    
-MissingNullability: android.view.contentcapture.ContentCaptureEvent#writeToParcel(android.os.Parcel, int) parameter #0:
-    
+    Missing nullability on parameter `counter` in method `setNumInstancesInUseCounter`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#asyncNewChild(int):
-    
+    Missing nullability on method `asyncNewChild` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getAutofillId():
-    
+    Missing nullability on method `getAutofillId` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getExtras():
-    
+    Missing nullability on method `getExtras` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getHint():
-    
+    Missing nullability on method `getHint` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getNode():
-    
+    Missing nullability on method `getNode` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getTempRect():
-    
+    Missing nullability on method `getTempRect` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getText():
-    
+    Missing nullability on method `getText` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#newChild(int):
-    
+    Missing nullability on method `newChild` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#newHtmlInfoBuilder(String):
-    
+    Missing nullability on method `newHtmlInfoBuilder` return
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#newHtmlInfoBuilder(String) parameter #0:
-    
+    Missing nullability on parameter `tagName` in method `newHtmlInfoBuilder`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillHints(String[]) parameter #0:
-    
+    Missing nullability on parameter `hints` in method `setAutofillHints`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillId(android.view.autofill.AutofillId) parameter #0:
-    
+    Missing nullability on parameter `id` in method `setAutofillId`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillId(android.view.autofill.AutofillId, int) parameter #0:
-    
+    Missing nullability on parameter `parentId` in method `setAutofillId`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillOptions(CharSequence[]) parameter #0:
-    
+    Missing nullability on parameter `options` in method `setAutofillOptions`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillValue(android.view.autofill.AutofillValue) parameter #0:
-    
+    Missing nullability on parameter `value` in method `setAutofillValue`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setClassName(String) parameter #0:
-    
+    Missing nullability on parameter `className` in method `setClassName`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setContentDescription(CharSequence) parameter #0:
-    
+    Missing nullability on parameter `contentDescription` in method `setContentDescription`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setHint(CharSequence) parameter #0:
-    
+    Missing nullability on parameter `hint` in method `setHint`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setHintIdEntry(String) parameter #0:
-    
+    Missing nullability on parameter `entryName` in method `setHintIdEntry`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setHtmlInfo(android.view.ViewStructure.HtmlInfo) parameter #0:
-    
+    Missing nullability on parameter `htmlInfo` in method `setHtmlInfo`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setId(int, String, String, String) parameter #1:
-    
+    Missing nullability on parameter `packageName` in method `setId`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setId(int, String, String, String) parameter #2:
-    
+    Missing nullability on parameter `typeName` in method `setId`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setId(int, String, String, String) parameter #3:
-    
+    Missing nullability on parameter `entryName` in method `setId`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setLocaleList(android.os.LocaleList) parameter #0:
-    
+    Missing nullability on parameter `localeList` in method `setLocaleList`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setText(CharSequence) parameter #0:
-    
+    Missing nullability on parameter `text` in method `setText`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setText(CharSequence, int, int) parameter #0:
-    
+    Missing nullability on parameter `text` in method `setText`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setTextLines(int[], int[]) parameter #0:
-    
+    Missing nullability on parameter `charOffsets` in method `setTextLines`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setTextLines(int[], int[]) parameter #1:
-    
+    Missing nullability on parameter `baselines` in method `setTextLines`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setTransformation(android.graphics.Matrix) parameter #0:
-    
+    Missing nullability on parameter `matrix` in method `setTransformation`
 MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setWebDomain(String) parameter #0:
-    
+    Missing nullability on parameter `domain` in method `setWebDomain`
 MissingNullability: android.widget.CalendarView#getBoundsForDate(long, android.graphics.Rect) parameter #1:
-    
+    Missing nullability on parameter `outBounds` in method `getBoundsForDate`
 MissingNullability: android.widget.ImageView#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #0:
-    
+    Missing nullability on parameter `background` in method `isDefaultFocusHighlightNeeded`
 MissingNullability: android.widget.ImageView#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #1:
-    
+    Missing nullability on parameter `foreground` in method `isDefaultFocusHighlightNeeded`
 MissingNullability: android.widget.Magnifier#getMagnifierDefaultSize():
-    
+    Missing nullability on method `getMagnifierDefaultSize` return
 MissingNullability: android.widget.Magnifier#setOnOperationCompleteCallback(android.widget.Magnifier.Callback) parameter #0:
-    
+    Missing nullability on parameter `callback` in method `setOnOperationCompleteCallback`
 MissingNullability: android.widget.NumberPicker#getDisplayedValueForCurrentSelection():
-    
+    Missing nullability on method `getDisplayedValueForCurrentSelection` return
 MissingNullability: android.widget.PopupMenu#getMenuListView():
-    
+    Missing nullability on method `getMenuListView` return
 MissingNullability: android.widget.TimePicker#getAmView():
-    
+    Missing nullability on method `getAmView` return
 MissingNullability: android.widget.TimePicker#getHourView():
-    
+    Missing nullability on method `getHourView` return
 MissingNullability: android.widget.TimePicker#getMinuteView():
-    
+    Missing nullability on method `getMinuteView` return
 MissingNullability: android.widget.TimePicker#getPmView():
-    
+    Missing nullability on method `getPmView` return
 
 
 MutableBareField: android.content.AutofillOptions#appDisabledExpiration:
-    
+    Bare field appDisabledExpiration must be marked final, or moved behind accessors if mutable
 MutableBareField: android.content.AutofillOptions#augmentedAutofillEnabled:
-    
+    Bare field augmentedAutofillEnabled must be marked final, or moved behind accessors if mutable
 MutableBareField: android.content.AutofillOptions#disabledActivities:
-    
+    Bare field disabledActivities must be marked final, or moved behind accessors if mutable
 MutableBareField: android.content.AutofillOptions#whitelistedActivitiesForAugmentedAutofill:
-    
+    Bare field whitelistedActivitiesForAugmentedAutofill must be marked final, or moved behind accessors if mutable
 MutableBareField: android.content.pm.UserInfo#convertedFromPreCreated:
     Bare field convertedFromPreCreated must be marked final, or moved behind accessors if mutable
 MutableBareField: android.content.pm.UserInfo#creationTime:
@@ -2438,588 +796,230 @@
 MutableBareField: android.content.pm.UserInfo#userType:
     Bare field userType must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#cache:
-    
+    Bare field cache must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#dbName:
-    
+    Bare field dbName must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#dbSize:
-    
+    Bare field dbSize must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#lookaside:
-    
+    Bare field lookaside must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#pageSize:
-    
+    Bare field pageSize must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.PagerStats#dbStats:
-    
+    Bare field dbStats must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.PagerStats#largestMemAlloc:
-    
+    Bare field largestMemAlloc must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.PagerStats#memoryUsed:
-    
+    Bare field memoryUsed must be marked final, or moved behind accessors if mutable
 MutableBareField: android.database.sqlite.SQLiteDebug.PagerStats#pageCacheOverflow:
-    
+    Bare field pageCacheOverflow must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#broadcastIntentAction:
-    
+    Bare field broadcastIntentAction must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#durationMillis:
-    
+    Bare field durationMillis must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#numAnimationsRunning:
-    
+    Bare field numAnimationsRunning must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#numInstances:
-    
+    Bare field numInstances must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#tags:
-    
+    Bare field tags must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#violationNumThisLoop:
-    
+    Bare field violationNumThisLoop must be marked final, or moved behind accessors if mutable
 MutableBareField: android.os.StrictMode.ViolationInfo#violationUptimeMillis:
-    
+    Bare field violationUptimeMillis must be marked final, or moved behind accessors if mutable
 
 
 NoByteOrShort: android.media.audiofx.AudioEffect#byteArrayToShort(byte[]):
-    
+    Should avoid odd sized primitives; use `int` instead of `short` in method android.media.audiofx.AudioEffect.byteArrayToShort(byte[])
 NoByteOrShort: android.media.audiofx.AudioEffect#setParameter(int, short) parameter #1:
-    
+    Should avoid odd sized primitives; use `int` instead of `short` in parameter value in android.media.audiofx.AudioEffect.setParameter(int param, short value)
 NoByteOrShort: android.media.audiofx.AudioEffect#shortToByteArray(short) parameter #0:
-    
-NoByteOrShort: android.os.HwBlob#getInt16(long):
-    
-NoByteOrShort: android.os.HwBlob#getInt8(long):
-    
-NoByteOrShort: android.os.HwBlob#putInt16(long, short) parameter #1:
-    
-NoByteOrShort: android.os.HwBlob#putInt8(long, byte) parameter #1:
-    
-NoByteOrShort: android.os.HwParcel#readInt16():
-    
-NoByteOrShort: android.os.HwParcel#readInt8():
-    
-NoByteOrShort: android.os.HwParcel#writeInt16(short) parameter #0:
-    
-NoByteOrShort: android.os.HwParcel#writeInt8(byte) parameter #0:
-    
+    Should avoid odd sized primitives; use `int` instead of `short` in parameter value in android.media.audiofx.AudioEffect.shortToByteArray(short value)
 NoByteOrShort: android.util.proto.EncodedBuffer#readRawByte():
-    
+    Should avoid odd sized primitives; use `int` instead of `byte` in method android.util.proto.EncodedBuffer.readRawByte()
 NoByteOrShort: android.util.proto.EncodedBuffer#writeRawByte(byte) parameter #0:
-    
-
-
-NoClone: android.net.util.SocketUtils#bindSocketToInterface(java.io.FileDescriptor, String) parameter #0:
-    
-NoClone: android.net.util.SocketUtils#closeSocket(java.io.FileDescriptor) parameter #0:
-    
-NoClone: android.os.NativeHandle#NativeHandle(java.io.FileDescriptor, boolean) parameter #0:
-    
-NoClone: android.os.NativeHandle#getFileDescriptor():
-    
-NoClone: android.os.ParcelFileDescriptor#getFile(java.io.FileDescriptor) parameter #0:
-    
-NoClone: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
-    
-NoClone: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
-    
-NoClone: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.FileDescriptor) parameter #0:
-    
+    Should avoid odd sized primitives; use `int` instead of `byte` in parameter val in android.util.proto.EncodedBuffer.writeRawByte(byte val)
 
 
 NoSettingsProvider: android.provider.Settings.Global#APP_OPS_CONSTANTS:
-    
-NoSettingsProvider: android.provider.Settings.Global#AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES:
-    
+    New setting keys are not allowed (Field: APP_OPS_CONSTANTS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#AUTOMATIC_POWER_SAVE_MODE:
-    
+    New setting keys are not allowed (Field: AUTOMATIC_POWER_SAVE_MODE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#BATTERY_SAVER_CONSTANTS:
-    
+    New setting keys are not allowed (Field: BATTERY_SAVER_CONSTANTS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD:
-    
+    New setting keys are not allowed (Field: DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#DYNAMIC_POWER_SAVINGS_ENABLED:
-    
+    New setting keys are not allowed (Field: DYNAMIC_POWER_SAVINGS_ENABLED); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_BLACKLIST_EXEMPTIONS:
-    
+    New setting keys are not allowed (Field: HIDDEN_API_BLACKLIST_EXEMPTIONS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_POLICY:
-    
+    New setting keys are not allowed (Field: HIDDEN_API_POLICY); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#HIDE_ERROR_DIALOGS:
-    
-NoSettingsProvider: android.provider.Settings.Global#LOCATION_GLOBAL_KILL_SWITCH:
-    
-NoSettingsProvider: android.provider.Settings.Global#LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST:
-    
+    New setting keys are not allowed (Field: HIDE_ERROR_DIALOGS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#LOW_POWER_MODE:
-    
+    New setting keys are not allowed (Field: LOW_POWER_MODE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#LOW_POWER_MODE_STICKY:
-    
-NoSettingsProvider: android.provider.Settings.Global#NOTIFICATION_BUBBLES:
-    
+    New setting keys are not allowed (Field: LOW_POWER_MODE_STICKY); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#OVERLAY_DISPLAY_DEVICES:
-    
-NoSettingsProvider: android.provider.Settings.Global#TETHER_OFFLOAD_DISABLED:
-    
-NoSettingsProvider: android.provider.Settings.Global#USE_OPEN_WIFI_PACKAGE:
-    
+    New setting keys are not allowed (Field: OVERLAY_DISPLAY_DEVICES); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED:
-    
+    New setting keys are not allowed (Field: ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_CAPABILITY:
-    
+    New setting keys are not allowed (Field: ACCESSIBILITY_MAGNIFICATION_CAPABILITY); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE:
-    
-NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_ALL:
-    
-NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN:
-    
-NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW:
-    
+    New setting keys are not allowed (Field: ACCESSIBILITY_MAGNIFICATION_MODE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_SHORTCUT_TARGET_SERVICE:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_FEATURE_FIELD_CLASSIFICATION:
-    
+    New setting keys are not allowed (Field: ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_SERVICE:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_VALUE_LENGTH:
-    
-NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MIN_VALUE_LENGTH:
-    
+    New setting keys are not allowed (Field: AUTOFILL_SERVICE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#CONTENT_CAPTURE_ENABLED:
-    
+    New setting keys are not allowed (Field: CONTENT_CAPTURE_ENABLED); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#DISABLED_PRINT_SERVICES:
-    
-NoSettingsProvider: android.provider.Settings.Secure#DOZE_ALWAYS_ON:
-    
+    New setting keys are not allowed (Field: DISABLED_PRINT_SERVICES); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#ENABLED_VR_LISTENERS:
-    
+    New setting keys are not allowed (Field: ENABLED_VR_LISTENERS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#IMMERSIVE_MODE_CONFIRMATIONS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#LOCATION_ACCESS_CHECK_DELAY_MILLIS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#LOCATION_ACCESS_CHECK_INTERVAL_MILLIS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#LOCK_SCREEN_SHOW_NOTIFICATIONS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#NFC_PAYMENT_DEFAULT_COMPONENT:
-    
+    New setting keys are not allowed (Field: IMMERSIVE_MODE_CONFIRMATIONS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#NOTIFICATION_BADGING:
-    
+    New setting keys are not allowed (Field: NOTIFICATION_BADGING); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#POWER_MENU_LOCKED_SHOW_CONTENT:
-    
+    New setting keys are not allowed (Field: POWER_MENU_LOCKED_SHOW_CONTENT); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#SYNC_PARENT_SOUNDS:
-    
-NoSettingsProvider: android.provider.Settings.Secure#USER_SETUP_COMPLETE:
-    
+    New setting keys are not allowed (Field: SYNC_PARENT_SOUNDS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#VOICE_INTERACTION_SERVICE:
-    
+    New setting keys are not allowed (Field: VOICE_INTERACTION_SERVICE); use getters/setters in relevant manager class
 
 
-NotCloseable: android.app.prediction.AppPredictor:
-    
-NotCloseable: android.net.EthernetManager.TetheredInterfaceRequest:
-    
-NotCloseable: android.os.HwParcel:
-    
-NotCloseable: android.telephony.ims.stub.ImsUtImplBase:
-    
-
-
-NullableCollection: android.os.UserManager#createProfileForUser(String, String, int, int, String[]) parameter #4:
-    Type of parameter disallowedPackages in android.os.UserManager.createProfileForUser(String name, String userType, int flags, int userId, String[] disallowedPackages) is a nullable collection (`java.lang.String[]`); must be non-null
-
-
-OnNameExpected: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.PrintWriter, String[]):
-    
-OnNameExpected: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
-    
 OnNameExpected: android.service.notification.ConditionProviderService#isBound():
-    
-OnNameExpected: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context):
-    
-OnNameExpected: android.service.quicksettings.TileService#isQuickSettingsSupported():
-    
+    If implemented by developer, should follow the on<Something> style; otherwise consider marking final
 OnNameExpected: android.service.watchdog.ExplicitHealthCheckService#setCallback(android.os.RemoteCallback):
-    
-OnNameExpected: android.telephony.ims.ImsService#createMmTelFeature(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#createRcsFeature(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#disableIms(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#enableIms(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#getConfig(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#getRegistration(int):
-    
-OnNameExpected: android.telephony.ims.ImsService#querySupportedImsFeatures():
-    
-OnNameExpected: android.telephony.ims.ImsService#readyForFeatureCreation():
-    
-OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#dispose(int):
-    
-OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int):
-    
-OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#startGroupCall(int, long, java.util.List<java.lang.Integer>, java.util.List<java.lang.Integer>, android.telephony.mbms.GroupCallCallback):
-    
-OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#stopGroupCall(int, long):
-    
-OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#updateGroupCall(int, long, java.util.List<java.lang.Integer>, java.util.List<java.lang.Integer>):
-    
-
-
-OptionalBuilderConstructorArgument: android.app.prediction.AppTargetEvent.Builder#Builder(android.app.prediction.AppTarget, int) parameter #0:
-    
-OptionalBuilderConstructorArgument: android.net.CaptivePortalData.Builder#Builder(android.net.CaptivePortalData) parameter #0:
-    
-OptionalBuilderConstructorArgument: android.os.VibrationAttributes.Builder#Builder(android.media.AudioAttributes, android.os.VibrationEffect) parameter #1:
-    
+    If implemented by developer, should follow the on<Something> style; otherwise consider marking final
 
 
 PackageLayering: android.util.FeatureFlagUtils:
-    
+    Method parameter type `android.content.Context` violates package layering: nothing in `package android.util` should depend on `package android.content`
 
 
-ParcelConstructor: android.os.IncidentManager.IncidentReport#IncidentReport(android.os.Parcel):
-    
-ParcelConstructor: android.os.IncidentReportArgs#IncidentReportArgs(android.os.Parcel):
-    
 ParcelConstructor: android.os.StrictMode.ViolationInfo#ViolationInfo(android.os.Parcel):
-    
+    Parcelable inflation is exposed through CREATOR, not raw constructors, in android.os.StrictMode.ViolationInfo
 ParcelConstructor: android.os.health.HealthStatsParceler#HealthStatsParceler(android.os.Parcel):
-    
-ParcelConstructor: android.service.notification.SnoozeCriterion#SnoozeCriterion(android.os.Parcel):
-    
+    Parcelable inflation is exposed through CREATOR, not raw constructors, in android.os.health.HealthStatsParceler
 
 
 ParcelCreator: android.app.WindowConfiguration:
-    
-ParcelCreator: android.net.metrics.ApfProgramEvent:
-    
-ParcelCreator: android.net.metrics.ApfStats:
-    
-ParcelCreator: android.net.metrics.DhcpClientEvent:
-    
-ParcelCreator: android.net.metrics.DhcpErrorEvent:
-    
-ParcelCreator: android.net.metrics.IpConnectivityLog.Event:
-    
-ParcelCreator: android.net.metrics.IpManagerEvent:
-    
-ParcelCreator: android.net.metrics.IpReachabilityEvent:
-    
-ParcelCreator: android.net.metrics.NetworkEvent:
-    
-ParcelCreator: android.net.metrics.RaEvent:
-    
-ParcelCreator: android.net.metrics.ValidationProbeEvent:
-    
+    Parcelable requires a `CREATOR` field; missing in android.app.WindowConfiguration
 ParcelCreator: android.service.autofill.InternalOnClickAction:
-    
+    Parcelable requires a `CREATOR` field; missing in android.service.autofill.InternalOnClickAction
 ParcelCreator: android.service.autofill.InternalSanitizer:
-    
+    Parcelable requires a `CREATOR` field; missing in android.service.autofill.InternalSanitizer
 ParcelCreator: android.service.autofill.InternalTransformation:
-    
+    Parcelable requires a `CREATOR` field; missing in android.service.autofill.InternalTransformation
 ParcelCreator: android.service.autofill.InternalValidator:
-    
+    Parcelable requires a `CREATOR` field; missing in android.service.autofill.InternalValidator
 
 
 ParcelNotFinal: android.app.WindowConfiguration:
-    
+    Parcelable classes must be final: android.app.WindowConfiguration is not final
 ParcelNotFinal: android.content.pm.UserInfo:
     Parcelable classes must be final: android.content.pm.UserInfo is not final
-ParcelNotFinal: android.net.metrics.IpConnectivityLog.Event:
-    
-ParcelNotFinal: android.os.IncidentManager.IncidentReport:
-    
 ParcelNotFinal: android.os.health.HealthStatsParceler:
-    
+    Parcelable classes must be final: android.os.health.HealthStatsParceler is not final
 ParcelNotFinal: android.service.autofill.InternalOnClickAction:
-    
+    Parcelable classes must be final: android.service.autofill.InternalOnClickAction is not final
 ParcelNotFinal: android.service.autofill.InternalSanitizer:
-    
+    Parcelable classes must be final: android.service.autofill.InternalSanitizer is not final
 ParcelNotFinal: android.service.autofill.InternalTransformation:
-    
+    Parcelable classes must be final: android.service.autofill.InternalTransformation is not final
 ParcelNotFinal: android.service.autofill.InternalValidator:
-    
+    Parcelable classes must be final: android.service.autofill.InternalValidator is not final
 
 
 ProtectedMember: android.app.AppDetailsActivity#onCreate(android.os.Bundle):
-    
-ProtectedMember: android.os.VibrationEffect#scale(int, float, int):
-    
-ProtectedMember: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
-    
-ProtectedMember: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.PrintWriter, String[]):
-    
-ProtectedMember: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
-    
-ProtectedMember: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context):
-    
-ProtectedMember: android.util.proto.ProtoStream#FIELD_TYPE_NAMES:
-    
+    Protected methods not allowed; must be public: method android.app.AppDetailsActivity.onCreate(android.os.Bundle)}
 ProtectedMember: android.view.View#resetResolvedDrawables():
-    
+    Protected methods not allowed; must be public: method android.view.View.resetResolvedDrawables()}
 ProtectedMember: android.view.ViewGroup#resetResolvedDrawables():
-    
-
-
-RawAidl: android.telephony.mbms.vendor.MbmsDownloadServiceBase:
-    
-RawAidl: android.telephony.mbms.vendor.MbmsStreamingServiceBase:
-    
+    Protected methods not allowed; must be public: method android.view.ViewGroup.resetResolvedDrawables()}
 
 
 RethrowRemoteException: android.app.ActivityManager#resumeAppSwitches():
-    
-RethrowRemoteException: android.os.HwBinder#getService(String, String):
-    
-RethrowRemoteException: android.os.HwBinder#getService(String, String, boolean):
-    
-RethrowRemoteException: android.os.HwBinder#onTransact(int, android.os.HwParcel, android.os.HwParcel, int):
-    
-RethrowRemoteException: android.os.HwBinder#registerService(String):
-    
-RethrowRemoteException: android.os.HwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int):
-    
-RethrowRemoteException: android.os.IHwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int):
-    
-RethrowRemoteException: android.telephony.ims.ImsService#onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#cancelDownload(android.telephony.mbms.DownloadRequest):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#dispose(int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#download(android.telephony.mbms.DownloadRequest):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#listPendingDownloads(int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestUpdateFileServices(int, java.util.List<java.lang.String>):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#resetDownloadKnowledge(android.telephony.mbms.DownloadRequest):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#setTempFileRootDirectory(int, String):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#dispose(int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#dispose(int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#getPlaybackUri(int, String):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#requestUpdateStreamingServices(int, java.util.List<java.lang.String>):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback):
-    
-RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#stopStreaming(int, String):
-    
+    Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
 
 
-SamShouldBeLast: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int):
-    
 SamShouldBeLast: android.database.sqlite.SQLiteDebug#dump(android.util.Printer, String[]):
-    
+    SAM-compatible parameters (such as parameter 1, "printer", in android.database.sqlite.SQLiteDebug.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]):
-    
-SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper):
-    
-SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, java.util.concurrent.Executor, android.location.LocationListener):
-    
-SamShouldBeLast: android.os.BugreportManager#startBugreport(android.os.ParcelFileDescriptor, android.os.ParcelFileDescriptor, android.os.BugreportParams, java.util.concurrent.Executor, android.os.BugreportManager.BugreportCallback):
-    
-SamShouldBeLast: android.os.IHwBinder#linkToDeath(android.os.IHwBinder.DeathRecipient, long):
-    
+    SAM-compatible parameters (such as parameter 1, "factory", in android.database.sqlite.SQLiteDirectCursorDriver.query) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.os.StrictMode.ViolationInfo#dump(android.util.Printer, String):
-    
+    SAM-compatible parameters (such as parameter 1, "pw", in android.os.StrictMode.ViolationInfo.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.permission.PermissionControllerManager#countPermissionApps(java.util.List<java.lang.String>, int, android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, android.os.Handler):
-    
+    SAM-compatible parameters (such as parameter 3, "callback", in android.permission.PermissionControllerManager.countPermissionApps) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler):
-    
-SamShouldBeLast: android.permission.PermissionControllerManager#revokeRuntimePermissions(java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, java.util.concurrent.Executor, android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback):
-    
+    SAM-compatible parameters (such as parameter 2, "callback", in android.permission.PermissionControllerManager.getAppPermissions) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.service.autofill.CharSequenceTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
+    SAM-compatible parameters (such as parameter 1, "finder", in android.service.autofill.CharSequenceTransformation.apply) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.service.autofill.DateTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
+    SAM-compatible parameters (such as parameter 1, "finder", in android.service.autofill.DateTransformation.apply) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.service.autofill.ImageTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
-    
+    SAM-compatible parameters (such as parameter 1, "finder", in android.service.autofill.ImageTransformation.apply) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.service.autofill.InternalTransformation#batchApply(android.service.autofill.ValueFinder, android.widget.RemoteViews, java.util.ArrayList<android.util.Pair<java.lang.Integer,android.service.autofill.InternalTransformation>>):
-    
-SamShouldBeLast: android.telephony.ims.ImsMmTelManager#getFeatureState(java.util.function.Consumer<java.lang.Integer>, java.util.concurrent.Executor):
-    
+    SAM-compatible parameters (such as parameter 1, "finder", in android.service.autofill.InternalTransformation.batchApply) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.Choreographer#postCallback(int, Runnable, Object):
-    
+    SAM-compatible parameters (such as parameter 2, "action", in android.view.Choreographer.postCallback) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.Choreographer#postCallbackDelayed(int, Runnable, Object, long):
-    
+    SAM-compatible parameters (such as parameter 2, "action", in android.view.Choreographer.postCallbackDelayed) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.view.Choreographer#removeCallbacks(int, Runnable, Object):
-    
-SamShouldBeLast: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>):
-    
-SamShouldBeLast: android.view.accessibility.AccessibilityManager#addAccessibilityServicesStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener, android.os.Handler):
-    
-
-
-ServiceName: android.Manifest.permission#BIND_CELL_BROADCAST_SERVICE:
-    
-ServiceName: android.app.AppOpsManager#OPSTR_BIND_ACCESSIBILITY_SERVICE:
-    
-ServiceName: android.provider.Settings.Secure#ACCESSIBILITY_SHORTCUT_TARGET_SERVICE:
-    
-ServiceName: android.provider.Settings.Secure#AUTOFILL_SERVICE:
-    
-ServiceName: android.provider.Settings.Secure#VOICE_INTERACTION_SERVICE:
-    
-
-
-SetterReturnsThis: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener):
-    
-SetterReturnsThis: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener):
-    
-
-
-StartWithLower: android.content.pm.PackageManager#BINDER():
-    Method name must start with lowercase char: BINDER
-
-
-StaticFinalBuilder: android.content.integrity.RuleSet.Builder:
-    
-StaticFinalBuilder: android.hardware.display.BrightnessConfiguration.Builder:
-    
-StaticFinalBuilder: android.media.audiopolicy.AudioMix.Builder:
-    
-StaticFinalBuilder: android.media.audiopolicy.AudioMixingRule.Builder:
-    
-StaticFinalBuilder: android.media.audiopolicy.AudioPolicy.Builder:
-    
-StaticFinalBuilder: android.net.CaptivePortalData.Builder:
-    
-StaticFinalBuilder: android.net.TetheringManager.TetheringRequest.Builder:
-    
-StaticFinalBuilder: android.telephony.ims.stub.ImsFeatureConfiguration.Builder:
-    
+    SAM-compatible parameters (such as parameter 2, "action", in android.view.Choreographer.removeCallbacks) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 
 
 StaticUtils: android.os.health.HealthKeys:
-    
+    Fully-static utility classes must not have constructor
 StaticUtils: android.service.autofill.InternalTransformation:
-    
-StaticUtils: android.telephony.mbms.vendor.VendorUtils:
-    
+    Fully-static utility classes must not have constructor
 StaticUtils: android.util.FeatureFlagUtils:
-    
-StaticUtils: android.util.proto.ProtoStream:
-    
+    Fully-static utility classes must not have constructor
 
 
 StreamFiles: android.os.Environment#buildPath(java.io.File, java.lang.String...):
-    
+    Methods accepting `File` should also accept `FileDescriptor` or streams: method android.os.Environment.buildPath(java.io.File,java.lang.String...)
 StreamFiles: android.os.FileUtils#contains(java.io.File, java.io.File):
-    
-StreamFiles: android.provider.MediaStore#scanFile(android.content.Context, java.io.File):
-    
-StreamFiles: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File):
-    
-StreamFiles: android.provider.MediaStore#scanVolume(android.content.Context, java.io.File):
-    
+    Methods accepting `File` should also accept `FileDescriptor` or streams: method android.os.FileUtils.contains(java.io.File,java.io.File)
 
 
 UseIcu: android.hardware.soundtrigger.KeyphraseEnrollmentInfo#getKeyphraseMetadata(String, java.util.Locale) parameter #1:
-    
+    Type `java.util.Locale` should be replaced with richer ICU type `android.icu.util.ULocale`
 UseIcu: android.hardware.soundtrigger.KeyphraseEnrollmentInfo#getManageKeyphraseIntent(int, String, java.util.Locale) parameter #2:
-    
+    Type `java.util.Locale` should be replaced with richer ICU type `android.icu.util.ULocale`
 UseIcu: android.hardware.soundtrigger.KeyphraseMetadata#supportsLocale(java.util.Locale) parameter #0:
-    
-UseIcu: android.hardware.soundtrigger.SoundTrigger.Keyphrase#Keyphrase(int, int, java.util.Locale, String, int[]) parameter #2:
-    
-UseIcu: android.hardware.soundtrigger.SoundTrigger.Keyphrase#getLocale():
-    
+    Type `java.util.Locale` should be replaced with richer ICU type `android.icu.util.ULocale`
 
 
-UseParcelFileDescriptor: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.FileDescriptor) parameter #0:
-    
-
-
-UserHandle: android.app.ActivityManager#switchUser(android.os.UserHandle):
-    
 UserHandle: android.app.admin.DevicePolicyManager#getOwnerInstalledCaCerts(android.os.UserHandle):
-    
+    When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added
 UserHandle: android.app.usage.StorageStatsManager#queryCratesForPackage(java.util.UUID, String, android.os.UserHandle):
-    
+    When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added
 UserHandle: android.app.usage.StorageStatsManager#queryCratesForUser(java.util.UUID, android.os.UserHandle):
-    
-UserHandle: android.companion.CompanionDeviceManager#isDeviceAssociated(String, android.net.MacAddress, android.os.UserHandle):
-    
-UserHandle: android.companion.CompanionDeviceManager#isDeviceAssociatedForWifiConnection(String, android.net.MacAddress, android.os.UserHandle):
-    
+    When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added
 UserHandle: android.content.pm.PackageManager#getInstallReason(String, android.os.UserHandle):
-    
-UserHandle: android.content.pm.PackageManager#getPermissionFlags(String, String, android.os.UserHandle):
-    
-UserHandle: android.content.pm.PackageManager#grantRuntimePermission(String, String, android.os.UserHandle):
-    
-UserHandle: android.content.pm.PackageManager#revokeRuntimePermission(String, String, android.os.UserHandle):
-    
-UserHandle: android.content.pm.PackageManager#revokeRuntimePermission(String, String, android.os.UserHandle, String):
-    
-UserHandle: android.content.pm.PackageManager#updatePermissionFlags(String, String, int, int, android.os.UserHandle):
-    
-UserHandle: android.location.LocationManager#setLocationEnabledForUser(boolean, android.os.UserHandle):
-    
-UserHandle: android.permission.PermissionControllerManager#applyStagedRuntimePermissionBackup(String, android.os.UserHandle, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Boolean>):
-    
-UserHandle: android.permission.PermissionControllerManager#getRuntimePermissionBackup(android.os.UserHandle, java.util.concurrent.Executor, java.util.function.Consumer<byte[]>):
-    
-UserHandle: android.permission.PermissionControllerManager#stageAndApplyRuntimePermissionsBackup(byte[], android.os.UserHandle):
-    
-UserHandle: android.telecom.TelecomManager#getDefaultDialerPackage(android.os.UserHandle):
-    
+    When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added
 
 
 UserHandleName: android.content.AutofillOptions:
-    
+    Classes holding a set of parameters should be called `FooParams`, was `AutofillOptions`
 UserHandleName: android.content.ContentCaptureOptions:
-    
-UserHandleName: android.os.IncidentReportArgs:
-    
-UserHandleName: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle):
-    
-UserHandleName: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle):
-    
+    Classes holding a set of parameters should be called `FooParams`, was `ContentCaptureOptions`
 
 
-VisiblySynchronized: PsiClassObjectAccessExpression:
-    
-VisiblySynchronized: PsiThisExpression:
-    
-VisiblySynchronized: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int):
-    
-VisiblySynchronized: android.app.ActivityManager#removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener):
-    
-VisiblySynchronized: android.content.ContentProviderClient#setDetectNotResponding(long):
-    
+VisiblySynchronized: PsiThisExpression:this:
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.getApkPaths()
 VisiblySynchronized: android.content.res.AssetManager#getApkPaths():
-    
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.getApkPaths()
 VisiblySynchronized: android.content.res.AssetManager#getLastResourceResolution():
-    
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.getLastResourceResolution()
 VisiblySynchronized: android.content.res.AssetManager#getOverlayablesToString(String):
-    
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.getOverlayablesToString(String)
 VisiblySynchronized: android.content.res.AssetManager#setResourceResolutionLoggingEnabled(boolean):
-    
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.setResourceResolutionLoggingEnabled(boolean)
 VisiblySynchronized: android.os.MessageQueue#removeSyncBarrier(int):
-    
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.os.MessageQueue.removeSyncBarrier(int)
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 709272c..2eebc01 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -46,6 +46,7 @@
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.transition.TransitionManager;
 import android.util.Pair;
@@ -634,9 +635,10 @@
             mAnimationStartedListener = new IRemoteCallback.Stub() {
                 @Override
                 public void sendResult(Bundle data) throws RemoteException {
+                    final long elapsedRealtime = SystemClock.elapsedRealtime();
                     handler.post(new Runnable() {
                         @Override public void run() {
-                            listener.onAnimationStarted();
+                            listener.onAnimationStarted(elapsedRealtime);
                         }
                     });
                 }
@@ -645,13 +647,15 @@
     }
 
     /**
-     * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation}
-     * to find out when the given animation has started running.
+     * Callback for finding out when the given animation has started running.
      * @hide
      */
     @TestApi
     public interface OnAnimationStartedListener {
-        void onAnimationStarted();
+        /**
+         * @param elapsedRealTime {@link SystemClock#elapsedRealTime} when animation started.
+         */
+        void onAnimationStarted(long elapsedRealTime);
     }
 
     private void setOnAnimationFinishedListener(final Handler handler,
@@ -660,10 +664,11 @@
             mAnimationFinishedListener = new IRemoteCallback.Stub() {
                 @Override
                 public void sendResult(Bundle data) throws RemoteException {
+                    final long elapsedRealtime = SystemClock.elapsedRealtime();
                     handler.post(new Runnable() {
                         @Override
                         public void run() {
-                            listener.onAnimationFinished();
+                            listener.onAnimationFinished(elapsedRealtime);
                         }
                     });
                 }
@@ -672,13 +677,15 @@
     }
 
     /**
-     * Callback for use with {@link ActivityOptions#makeThumbnailAspectScaleDownAnimation}
-     * to find out when the given animation has drawn its last frame.
+     * Callback for finding out when the given animation has drawn its last frame.
      * @hide
      */
     @TestApi
     public interface OnAnimationFinishedListener {
-        void onAnimationFinished();
+        /**
+         * @param elapsedRealTime {@link SystemClock#elapsedRealTime} when animation finished.
+         */
+        void onAnimationFinished(long elapsedRealTime);
     }
 
     /**
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 4829dc0..6e395be 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2916,6 +2916,133 @@
     };
 
     /**
+     * This specifies whether each option is only allowed to be read
+     * by apps with manage appops permission.
+     */
+    private static boolean[] sOpRestrictRead = new boolean[] {
+            false, // COARSE_LOCATION
+            false, // FINE_LOCATION
+            false, // GPS
+            false, // VIBRATE
+            false, // READ_CONTACTS
+            false, // WRITE_CONTACTS
+            false, // READ_CALL_LOG
+            false, // WRITE_CALL_LOG
+            false, // READ_CALENDAR
+            false, // WRITE_CALENDAR
+            false, // WIFI_SCAN
+            false, // POST_NOTIFICATION
+            false, // NEIGHBORING_CELLS
+            false, // CALL_PHONE
+            false, // READ_SMS
+            false, // WRITE_SMS
+            false, // RECEIVE_SMS
+            false, // RECEIVE_EMERGENCY_BROADCAST
+            false, // RECEIVE_MMS
+            false, // RECEIVE_WAP_PUSH
+            false, // SEND_SMS
+            false, // READ_ICC_SMS
+            false, // WRITE_ICC_SMS
+            false, // WRITE_SETTINGS
+            false, // SYSTEM_ALERT_WINDOW
+            false, // ACCESS_NOTIFICATIONS
+            false, // CAMERA
+            false, // RECORD_AUDIO
+            false, // PLAY_AUDIO
+            false, // READ_CLIPBOARD
+            false, // WRITE_CLIPBOARD
+            false, // TAKE_MEDIA_BUTTONS
+            false, // TAKE_AUDIO_FOCUS
+            false, // AUDIO_MASTER_VOLUME
+            false, // AUDIO_VOICE_VOLUME
+            false, // AUDIO_RING_VOLUME
+            false, // AUDIO_MEDIA_VOLUME
+            false, // AUDIO_ALARM_VOLUME
+            false, // AUDIO_NOTIFICATION_VOLUME
+            false, // AUDIO_BLUETOOTH_VOLUME
+            false, // WAKE_LOCK
+            false, // MONITOR_LOCATION
+            false, // MONITOR_HIGH_POWER_LOCATION
+            false, // GET_USAGE_STATS
+            false, // MUTE_MICROPHONE
+            false, // TOAST_WINDOW
+            false, // PROJECT_MEDIA
+            false, // ACTIVATE_VPN
+            false, // WRITE_WALLPAPER
+            false, // ASSIST_STRUCTURE
+            false, // ASSIST_SCREENSHOT
+            false, // READ_PHONE_STATE
+            false, // ADD_VOICEMAIL
+            false, // USE_SIP
+            false, // PROCESS_OUTGOING_CALLS
+            false, // USE_FINGERPRINT
+            false, // BODY_SENSORS
+            false, // READ_CELL_BROADCASTS
+            false, // MOCK_LOCATION
+            false, // READ_EXTERNAL_STORAGE
+            false, // WRITE_EXTERNAL_STORAGE
+            false, // TURN_SCREEN_ON
+            false, // GET_ACCOUNTS
+            false, // RUN_IN_BACKGROUND
+            false, // AUDIO_ACCESSIBILITY_VOLUME
+            false, // READ_PHONE_NUMBERS
+            false, // REQUEST_INSTALL_PACKAGES
+            false, // PICTURE_IN_PICTURE
+            false, // INSTANT_APP_START_FOREGROUND
+            false, // ANSWER_PHONE_CALLS
+            false, // RUN_ANY_IN_BACKGROUND
+            false, // CHANGE_WIFI_STATE
+            false, // REQUEST_DELETE_PACKAGES
+            false, // BIND_ACCESSIBILITY_SERVICE
+            false, // ACCEPT_HANDOVER
+            false, // MANAGE_IPSEC_TUNNELS
+            false, // START_FOREGROUND
+            false, // BLUETOOTH_SCAN
+            false, // USE_BIOMETRIC
+            false, // ACTIVITY_RECOGNITION
+            false, // SMS_FINANCIAL_TRANSACTIONS
+            false, // READ_MEDIA_AUDIO
+            false, // WRITE_MEDIA_AUDIO
+            false, // READ_MEDIA_VIDEO
+            false,  // WRITE_MEDIA_VIDEO
+            false, // READ_MEDIA_IMAGES
+            false,  // WRITE_MEDIA_IMAGES
+            false,  // LEGACY_STORAGE
+            false, // ACCESS_ACCESSIBILITY
+            false, // READ_DEVICE_IDENTIFIERS
+            false, // ACCESS_MEDIA_LOCATION
+            false, // QUERY_ALL_PACKAGES
+            false, // MANAGE_EXTERNAL_STORAGE
+            false, // INTERACT_ACROSS_PROFILES
+            false, // ACTIVATE_PLATFORM_VPN
+            false, // LOADER_USAGE_STATS
+            false, // deprecated operation
+            false, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
+            false, // AUTO_REVOKE_MANAGED_BY_INSTALLER
+            false, // NO_ISOLATED_STORAGE
+            false, // PHONE_CALL_MICROPHONE
+            false, // PHONE_CALL_CAMERA
+            false, // RECORD_AUDIO_HOTWORD
+            false, // MANAGE_ONGOING_CALLS
+            false, // MANAGE_CREDENTIALS
+            false, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER
+            false, // RECORD_AUDIO_OUTPUT
+            false, // SCHEDULE_EXACT_ALARM
+            false, // ACCESS_FINE_LOCATION_SOURCE
+            false, // ACCESS_COARSE_LOCATION_SOURCE
+            false, // MANAGE_MEDIA
+            false, // BLUETOOTH_CONNECT
+            false, // UWB_RANGING
+            false, // ACTIVITY_RECOGNITION_SOURCE
+            false, // BLUETOOTH_ADVERTISE
+            false, // RECORD_INCOMING_PHONE_AUDIO
+            false, // NEARBY_WIFI_DEVICES
+            false, // OP_ESTABLISH_VPN_SERVICE
+            false, // OP_ESTABLISH_VPN_MANAGER
+            true, // ACCESS_RESTRICTED_SETTINGS
+    };
+
+    /**
      * Mapping from an app op name to the app op code.
      */
     private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
@@ -3143,6 +3270,14 @@
     }
 
     /**
+     * Retrieve whether the op can be read by apps with manage appops permission.
+     * @hide
+     */
+    public static boolean opRestrictsRead(int op) {
+        return sOpRestrictRead[op];
+    }
+
+    /**
      * Retrieve whether the op allows itself to be reset.
      * @hide
      */
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 7c337a4..2767b43 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -30,11 +30,9 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.util.Log;
-import android.util.Slog;
 import android.view.autofill.AutofillManager;
 
 import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Base class for maintaining global application state. You can provide your own
@@ -56,9 +54,6 @@
 public class Application extends ContextWrapper implements ComponentCallbacks2 {
     private static final String TAG = "Application";
 
-    /** Whether to enable the check to detect "duplicate application instances". */
-    private static final boolean DEBUG_DUP_APP_INSTANCES = true;
-
     @UnsupportedAppUsage
     private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
             new ArrayList<ActivityLifecycleCallbacks>();
@@ -72,9 +67,6 @@
     @UnsupportedAppUsage
     public LoadedApk mLoadedApk;
 
-    private static final AtomicReference<StackTrace> sConstructorStackTrace =
-            new AtomicReference<>();
-
     public interface ActivityLifecycleCallbacks {
 
         /**
@@ -240,26 +232,6 @@
 
     public Application() {
         super(null);
-        if (DEBUG_DUP_APP_INSTANCES) {
-            checkDuplicateInstances();
-        }
-    }
-
-    private void checkDuplicateInstances() {
-        // STOPSHIP: Delete this check b/221248960
-        // Only run this check for gms-core.
-        if (!"com.google.android.gms".equals(ActivityThread.currentOpPackageName())) {
-            return;
-        }
-
-        final StackTrace previousStackTrace = sConstructorStackTrace.getAndSet(
-                new StackTrace("Previous stack trace"));
-        if (previousStackTrace == null) {
-            // This is the first call.
-            return;
-        }
-        Slog.wtf(TAG, "Application ctor called twice for " + this.getClass(),
-                new StackTrace("Current stack trace", previousStackTrace));
     }
 
     private String getLoadedApkInfo() {
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index e9c29b8..c802d20 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -261,8 +261,10 @@
             CharSequence title, CharSequence description, int userId,
             boolean disallowBiometricsIfPolicyExists) {
         Intent intent = this.createConfirmDeviceCredentialIntent(title, description, userId);
-        intent.putExtra(EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS,
-                disallowBiometricsIfPolicyExists);
+        if (intent != null) {
+            intent.putExtra(EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS,
+                    disallowBiometricsIfPolicyExists);
+        }
         return intent;
     }
 
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 53e7559..974d20a 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1901,6 +1901,11 @@
 
             /**
              * Construct a new builder for {@link Action} object.
+             * <p>As of Android {@link android.os.Build.VERSION_CODES#N},
+             * action button icons will not be displayed on action buttons, but are still required
+             * and are available to
+             * {@link android.service.notification.NotificationListenerService notification listeners},
+             * which may display them in other contexts, for example on a wearable device.
              * @param icon icon to show for this action
              * @param title the title of the action
              * @param intent the {@link PendingIntent} to fire when users trigger this action
@@ -1923,6 +1928,12 @@
              * both are displayed or required, depends on where and how the action is used, and the
              * {@link Style} applied to the Notification.
              *
+             * <p>As of Android {@link android.os.Build.VERSION_CODES#N}, action button icons
+             * will not be displayed on action buttons, but are still required and are available
+             * to {@link android.service.notification.NotificationListenerService notification
+             * listeners}, which may display them in other contexts, for example on a wearable
+             * device.
+             *
              * <p>When the {@code title} is a {@link android.text.Spanned}, any colors set by a
              * {@link ForegroundColorSpan} or {@link TextAppearanceSpan} may be removed or displayed
              * with an altered in luminance to ensure proper contrast within the Notification.
@@ -4918,6 +4929,12 @@
          * while processing broadcast receivers or services in response to notification action
          * clicks. To launch an activity in those cases, provide a {@link PendingIntent} to the
          * activity itself.
+         * <p>
+         * As of Android {@link android.os.Build.VERSION_CODES#N},
+         * action button icons will not be displayed on action buttons, but are still required
+         * and are available to
+         * {@link android.service.notification.NotificationListenerService notification listeners},
+         * which may display them in other contexts, for example on a wearable device.
          *
          * @param icon Resource ID of a drawable that represents the action.
          * @param title Text describing the action.
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index e502ba0..5ef3fc0 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -819,11 +819,8 @@
         return isFloating(mWindowingMode);
     }
 
-    /**
-     * Returns true if the windowingMode represents a floating window.
-     * @hide
-     */
-    public static boolean isFloating(int windowingMode) {
+    /** Returns true if the windowingMode represents a floating window. */
+    public static boolean isFloating(@WindowingMode int windowingMode) {
         return windowingMode == WINDOWING_MODE_FREEFORM || windowingMode == WINDOWING_MODE_PINNED;
     }
 
diff --git a/core/java/android/app/admin/DevicePolicyCache.java b/core/java/android/app/admin/DevicePolicyCache.java
index 9c07f85..da62375 100644
--- a/core/java/android/app/admin/DevicePolicyCache.java
+++ b/core/java/android/app/admin/DevicePolicyCache.java
@@ -41,8 +41,7 @@
     /**
      * See {@link DevicePolicyManager#getScreenCaptureDisabled}
      */
-    public abstract boolean isScreenCaptureAllowed(@UserIdInt int userHandle,
-            boolean ownerCanAddInternalSystemWindow);
+    public abstract boolean isScreenCaptureAllowed(@UserIdInt int userHandle);
 
     /**
      * Caches {@link DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} of the
@@ -70,8 +69,7 @@
         private static final EmptyDevicePolicyCache INSTANCE = new EmptyDevicePolicyCache();
 
         @Override
-        public boolean isScreenCaptureAllowed(int userHandle,
-                boolean ownerCanAddInternalSystemWindow) {
+        public boolean isScreenCaptureAllowed(int userHandle) {
             return true;
         }
 
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d11b23c..b7b93aa 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3322,8 +3322,8 @@
      * Activity action: Starts the device policy management role holder updater.
      *
      * <p>The activity must handle the device policy management role holder update and set the
-     * intent result to either {@link Activity#RESULT_OK} if the update was successful or not
-     * necessary, {@link #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR} if
+     * intent result. This can include {@link Activity#RESULT_OK} if the update was successful,
+     * {@link #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR} if
      * it encounters a problem that may be solved by relaunching it again, {@link
      * #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_PROVISIONING_DISABLED} if role holder
      * provisioning is disabled, or {@link
@@ -3376,7 +3376,8 @@
 
     /**
      * An {@code int} extra which contains the result code of the last attempt to update
-     * the device policy management role holder.
+     * the device policy management role holder via {@link
+     * #ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER}.
      *
      * <p>This extra is provided to the device policy management role holder via either {@link
      * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE} or {@link
@@ -3394,6 +3395,8 @@
      *    encounters a problem that may be solved by relaunching it again.
      *    <li>{@link #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR} if
      *    it encounters a problem that will not be solved by relaunching it again.
+     *    <li>Any other value returned by {@link
+     *    #ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER}
      * </ul>
      *
      * @hide
diff --git a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
index 54170a2..24b4f4b 100644
--- a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
+++ b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
@@ -16,15 +16,31 @@
 
 package android.app.admin;
 
+import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.END_TAG;
+import static org.xmlpull.v1.XmlPullParser.TEXT;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * Network configuration to be set for the user profile
@@ -37,6 +53,20 @@
     final int[] mIncludedUids;
     final int[] mExcludedUids;
 
+    private static final String LOG_TAG = "PreferentialNetworkServiceConfig";
+    private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG =
+            "preferential_network_service_config";
+    private static final String TAG_CONFIG_ENABLED =
+            "preferential_network_service_config_enabled";
+    private static final String TAG_UID = "uid";
+    private static final String TAG_NETWORK_ID =
+            "preferential_network_service_network_id";
+    private static final String TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION =
+            "allow_fallback_to_default_connection";
+    private static final String TAG_INCLUDED_UIDS = "included_uids";
+    private static final String TAG_EXCLUDED_UIDS = "excluded_uids";
+    private static final String ATTR_VALUE = "value";
+
     /** @hide */
     public static final PreferentialNetworkServiceConfig DEFAULT =
             (new PreferentialNetworkServiceConfig.Builder()).build();
@@ -159,8 +189,8 @@
         return "PreferentialNetworkServiceConfig{"
                 + "mIsEnabled=" + isEnabled()
                 + "mAllowFallbackToDefaultConnection=" + isFallbackToDefaultConnectionAllowed()
-                + "mIncludedUids=" + mIncludedUids.toString()
-                + "mExcludedUids=" + mExcludedUids.toString()
+                + "mIncludedUids=" + Arrays.toString(mIncludedUids)
+                + "mExcludedUids=" + Arrays.toString(mExcludedUids)
                 + "mNetworkId=" + mNetworkId
                 + '}';
     }
@@ -309,6 +339,135 @@
         dest.writeIntArray(mExcludedUids);
     }
 
+    private void writeAttributeValueToXml(TypedXmlSerializer out, String tag, int value)
+            throws IOException {
+        out.startTag(null, tag);
+        out.attributeInt(null, ATTR_VALUE, value);
+        out.endTag(null, tag);
+    }
+
+    private void writeAttributeValueToXml(TypedXmlSerializer out, String tag, boolean value)
+            throws IOException {
+        out.startTag(null, tag);
+        out.attributeBoolean(null, ATTR_VALUE, value);
+        out.endTag(null, tag);
+    }
+
+    private void writeAttributeValuesToXml(TypedXmlSerializer out, String outerTag, String innerTag,
+            @NonNull Collection<String> values) throws IOException {
+        out.startTag(null, outerTag);
+        for (String value : values) {
+            out.startTag(null, innerTag);
+            out.attribute(null, ATTR_VALUE, value);
+            out.endTag(null, innerTag);
+        }
+        out.endTag(null, outerTag);
+    }
+
+    private static  void readAttributeValues(
+            TypedXmlPullParser parser, String tag, Collection<String> result)
+            throws XmlPullParserException, IOException {
+        result.clear();
+        int outerDepthDAM = parser.getDepth();
+        int typeDAM;
+        while ((typeDAM = parser.next()) != END_DOCUMENT
+                && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
+            if (typeDAM == END_TAG || typeDAM == TEXT) {
+                continue;
+            }
+            String tagDAM = parser.getName();
+            if (tag.equals(tagDAM)) {
+                result.add(parser.getAttributeValue(null, ATTR_VALUE));
+            } else {
+                Log.e(LOG_TAG, "Expected tag " + tag + " but found " + tagDAM);
+            }
+        }
+    }
+
+    private List<String> intArrayToStringList(int[] array) {
+        return Arrays.stream(array).mapToObj(String::valueOf).collect(Collectors.toList());
+    }
+
+    private static int[] readStringListToIntArray(TypedXmlPullParser parser, String tag)
+            throws XmlPullParserException, IOException {
+        List<String> stringList = new ArrayList<>();
+        readAttributeValues(parser, tag, stringList);
+        int[] intArray = stringList.stream()
+                .map(s -> Integer.parseInt(s))
+                .mapToInt(Integer::intValue)
+                .toArray();
+        return intArray;
+    }
+
+    /**
+     * @hide
+     */
+    public static PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig(
+            TypedXmlPullParser parser, String tag) throws XmlPullParserException, IOException  {
+        int outerDepthDAM = parser.getDepth();
+        int typeDAM;
+        PreferentialNetworkServiceConfig.Builder resultBuilder =
+                new PreferentialNetworkServiceConfig.Builder();
+        while ((typeDAM = parser.next()) != END_DOCUMENT
+                && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
+            if (typeDAM == END_TAG || typeDAM == TEXT) {
+                continue;
+            }
+            String tagDAM = parser.getName();
+            if (TAG_CONFIG_ENABLED.equals(tagDAM)) {
+                resultBuilder.setEnabled(parser.getAttributeBoolean(null, ATTR_VALUE,
+                        DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT));
+            } else if (TAG_NETWORK_ID.equals(tagDAM)) {
+                int val = parser.getAttributeInt(null, ATTR_VALUE, 0);
+                if (val != 0) {
+                    resultBuilder.setNetworkId(val);
+                }
+            } else if (TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION.equals(tagDAM)) {
+                resultBuilder.setFallbackToDefaultConnectionAllowed(parser.getAttributeBoolean(
+                        null, ATTR_VALUE, true));
+            } else if (TAG_INCLUDED_UIDS.equals(tagDAM)) {
+                resultBuilder.setIncludedUids(readStringListToIntArray(parser, TAG_UID));
+            } else if (TAG_EXCLUDED_UIDS.equals(tagDAM)) {
+                resultBuilder.setExcludedUids(readStringListToIntArray(parser, TAG_UID));
+            } else {
+                Log.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM);
+            }
+        }
+        return resultBuilder.build();
+    }
+
+    /**
+     * @hide
+     */
+    public void writeToXml(@NonNull TypedXmlSerializer out) throws IOException {
+        out.startTag(null, TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG);
+        writeAttributeValueToXml(out, TAG_CONFIG_ENABLED, isEnabled());
+        writeAttributeValueToXml(out, TAG_NETWORK_ID, getNetworkId());
+        writeAttributeValueToXml(out, TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION,
+                isFallbackToDefaultConnectionAllowed());
+        writeAttributeValuesToXml(out, TAG_INCLUDED_UIDS, TAG_UID,
+                intArrayToStringList(getIncludedUids()));
+        writeAttributeValuesToXml(out, TAG_EXCLUDED_UIDS, TAG_UID,
+                intArrayToStringList(getExcludedUids()));
+        out.endTag(null, TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG);
+    }
+
+    /**
+     * @hide
+     */
+    public void dump(IndentingPrintWriter pw) {
+        pw.print("networkId=");
+        pw.println(mNetworkId);
+        pw.print("isEnabled=");
+        pw.println(mIsEnabled);
+        pw.print("allowFallbackToDefaultConnection=");
+        pw.println(mAllowFallbackToDefaultConnection);
+        pw.print("includedUids=");
+        pw.println(mIncludedUids);
+        pw.print("excludedUids=");
+        pw.println(mExcludedUids);
+    }
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/core/java/android/app/smartspace/ISmartspaceManager.aidl b/core/java/android/app/smartspace/ISmartspaceManager.aidl
index e7ec889..8dc07a1 100644
--- a/core/java/android/app/smartspace/ISmartspaceManager.aidl
+++ b/core/java/android/app/smartspace/ISmartspaceManager.aidl
@@ -26,7 +26,7 @@
 /**
  * @hide
  */
-interface ISmartspaceManager {
+oneway interface ISmartspaceManager {
 
     void createSmartspaceSession(in SmartspaceConfig config, in SmartspaceSessionId sessionId,
             in IBinder token);
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index dc65bef..d235f12 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -422,6 +422,18 @@
         }
 
         /**
+         * Set if BiometricPrompt is being used by the legacy fingerprint manager API.
+         * @param sensorId sensor id
+         * @return This builder.
+         * @hide
+         */
+        @NonNull
+        public Builder setIsForLegacyFingerprintManager(int sensorId) {
+            mPromptInfo.setIsForLegacyFingerprintManager(sensorId);
+            return this;
+        }
+
+        /**
          * Creates a {@link BiometricPrompt}.
          *
          * @return An instance of {@link BiometricPrompt}.
@@ -883,28 +895,36 @@
             @NonNull @CallbackExecutor Executor executor,
             @NonNull AuthenticationCallback callback,
             int userId) {
-        authenticateUserForOperation(cancel, executor, callback, userId, 0 /* operationId */);
+        if (cancel == null) {
+            throw new IllegalArgumentException("Must supply a cancellation signal");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException("Must supply an executor");
+        }
+        if (callback == null) {
+            throw new IllegalArgumentException("Must supply a callback");
+        }
+
+        authenticateInternal(0 /* operationId */, cancel, executor, callback, userId);
     }
 
     /**
-     * Authenticates for the given user and keystore operation.
+     * Authenticates for the given keystore operation.
      *
      * @param cancel An object that can be used to cancel authentication
      * @param executor An executor to handle callback events
      * @param callback An object to receive authentication events
-     * @param userId The user to authenticate
      * @param operationId The keystore operation associated with authentication
      *
      * @return A requestId that can be used to cancel this operation.
      *
      * @hide
      */
-    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
-    public long authenticateUserForOperation(
+    @RequiresPermission(USE_BIOMETRIC)
+    public long authenticateForOperation(
             @NonNull CancellationSignal cancel,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull AuthenticationCallback callback,
-            int userId,
             long operationId) {
         if (cancel == null) {
             throw new IllegalArgumentException("Must supply a cancellation signal");
@@ -916,7 +936,7 @@
             throw new IllegalArgumentException("Must supply a callback");
         }
 
-        return authenticateInternal(operationId, cancel, executor, callback, userId);
+        return authenticateInternal(operationId, cancel, executor, callback, mContext.getUserId());
     }
 
     /**
@@ -1050,7 +1070,7 @@
     private void cancelAuthentication(long requestId) {
         if (mService != null) {
             try {
-                mService.cancelAuthentication(mToken, mContext.getOpPackageName(), requestId);
+                mService.cancelAuthentication(mToken, mContext.getPackageName(), requestId);
             } catch (RemoteException e) {
                 Log.e(TAG, "Unable to cancel authentication", e);
             }
@@ -1109,7 +1129,7 @@
             }
 
             final long authId = mService.authenticate(mToken, operationId, userId,
-                    mBiometricServiceReceiver, mContext.getOpPackageName(), promptInfo);
+                    mBiometricServiceReceiver, mContext.getPackageName(), promptInfo);
             cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId));
             return authId;
         } catch (RemoteException e) {
diff --git a/core/java/android/hardware/biometrics/ITestSessionCallback.aidl b/core/java/android/hardware/biometrics/ITestSessionCallback.aidl
index 3d9517f..b336a9f 100644
--- a/core/java/android/hardware/biometrics/ITestSessionCallback.aidl
+++ b/core/java/android/hardware/biometrics/ITestSessionCallback.aidl
@@ -19,7 +19,7 @@
  * ITestSession callback for FingerprintManager and BiometricManager.
  * @hide
  */
-interface ITestSessionCallback {
+oneway interface ITestSessionCallback {
     void onCleanupStarted(int userId);
     void onCleanupFinished(int userId);
 }
diff --git a/core/java/android/hardware/biometrics/PromptInfo.java b/core/java/android/hardware/biometrics/PromptInfo.java
index 0c03948..a6b8096 100644
--- a/core/java/android/hardware/biometrics/PromptInfo.java
+++ b/core/java/android/hardware/biometrics/PromptInfo.java
@@ -46,6 +46,7 @@
     @NonNull private List<Integer> mAllowedSensorIds = new ArrayList<>();
     private boolean mAllowBackgroundAuthentication;
     private boolean mIgnoreEnrollmentState;
+    private boolean mIsForLegacyFingerprintManager = false;
 
     public PromptInfo() {
 
@@ -68,6 +69,7 @@
         mAllowedSensorIds = in.readArrayList(Integer.class.getClassLoader(), java.lang.Integer.class);
         mAllowBackgroundAuthentication = in.readBoolean();
         mIgnoreEnrollmentState = in.readBoolean();
+        mIsForLegacyFingerprintManager = in.readBoolean();
     }
 
     public static final Creator<PromptInfo> CREATOR = new Creator<PromptInfo>() {
@@ -105,10 +107,15 @@
         dest.writeList(mAllowedSensorIds);
         dest.writeBoolean(mAllowBackgroundAuthentication);
         dest.writeBoolean(mIgnoreEnrollmentState);
+        dest.writeBoolean(mIsForLegacyFingerprintManager);
     }
 
     public boolean containsTestConfigurations() {
-        if (!mAllowedSensorIds.isEmpty()) {
+        if (mIsForLegacyFingerprintManager
+                && mAllowedSensorIds.size() == 1
+                && !mAllowBackgroundAuthentication) {
+            return false;
+        } else if (!mAllowedSensorIds.isEmpty()) {
             return true;
         } else if (mAllowBackgroundAuthentication) {
             return true;
@@ -188,7 +195,8 @@
     }
 
     public void setAllowedSensorIds(@NonNull List<Integer> sensorIds) {
-        mAllowedSensorIds = sensorIds;
+        mAllowedSensorIds.clear();
+        mAllowedSensorIds.addAll(sensorIds);
     }
 
     public void setAllowBackgroundAuthentication(boolean allow) {
@@ -199,6 +207,12 @@
         mIgnoreEnrollmentState = ignoreEnrollmentState;
     }
 
+    public void setIsForLegacyFingerprintManager(int sensorId) {
+        mIsForLegacyFingerprintManager = true;
+        mAllowedSensorIds.clear();
+        mAllowedSensorIds.add(sensorId);
+    }
+
     // Getters
 
     public CharSequence getTitle() {
@@ -272,4 +286,8 @@
     public boolean isIgnoreEnrollmentState() {
         return mIgnoreEnrollmentState;
     }
+
+    public boolean isForLegacyFingerprintManager() {
+        return mIsForLegacyFingerprintManager;
+    }
 }
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 31f3b6a..06edf66 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -1363,19 +1363,27 @@
 
             // Consolidate positional feedback to reduce noise during authentication.
             case FACE_ACQUIRED_NOT_DETECTED:
+                return context.getString(R.string.face_acquired_not_detected);
             case FACE_ACQUIRED_TOO_CLOSE:
+                return context.getString(R.string.face_acquired_too_close);
             case FACE_ACQUIRED_TOO_FAR:
+                return context.getString(R.string.face_acquired_too_far);
             case FACE_ACQUIRED_TOO_HIGH:
+                return context.getString(R.string.face_acquired_too_high);
             case FACE_ACQUIRED_TOO_LOW:
+                return context.getString(R.string.face_acquired_too_low);
             case FACE_ACQUIRED_TOO_RIGHT:
+                return context.getString(R.string.face_acquired_too_right);
             case FACE_ACQUIRED_TOO_LEFT:
+                return context.getString(R.string.face_acquired_too_left);
             case FACE_ACQUIRED_POOR_GAZE:
-            case FACE_ACQUIRED_PAN_TOO_EXTREME:
-            case FACE_ACQUIRED_TILT_TOO_EXTREME:
-            case FACE_ACQUIRED_ROLL_TOO_EXTREME:
                 return context.getString(R.string.face_acquired_poor_gaze);
-
-            // Provide more detailed feedback for other soft errors.
+            case FACE_ACQUIRED_PAN_TOO_EXTREME:
+                return context.getString(R.string.face_acquired_pan_too_extreme);
+            case FACE_ACQUIRED_TILT_TOO_EXTREME:
+                return context.getString(R.string.face_acquired_tilt_too_extreme);
+            case FACE_ACQUIRED_ROLL_TOO_EXTREME:
+                return context.getString(R.string.face_acquired_roll_too_extreme);
             case FACE_ACQUIRED_INSUFFICIENT:
                 return context.getString(R.string.face_acquired_insufficient);
             case FACE_ACQUIRED_TOO_BRIGHT:
@@ -1394,6 +1402,10 @@
                 return context.getString(R.string.face_acquired_obscured);
             case FACE_ACQUIRED_SENSOR_DIRTY:
                 return context.getString(R.string.face_acquired_sensor_dirty);
+            case FACE_ACQUIRED_DARK_GLASSES_DETECTED:
+                return context.getString(R.string.face_acquired_dark_glasses_detected);
+            case FACE_ACQUIRED_MOUTH_COVERING_DETECTED:
+                return context.getString(R.string.face_acquired_mouth_covering_detected);
 
             // Find and return the appropriate vendor-specific message.
             case FACE_ACQUIRED_VENDOR: {
@@ -1459,11 +1471,13 @@
             case FACE_ACQUIRED_ROLL_TOO_EXTREME:
                 return context.getString(R.string.face_acquired_roll_too_extreme);
             case FACE_ACQUIRED_FACE_OBSCURED:
-            case FACE_ACQUIRED_DARK_GLASSES_DETECTED:
-            case FACE_ACQUIRED_MOUTH_COVERING_DETECTED:
                 return context.getString(R.string.face_acquired_obscured);
             case FACE_ACQUIRED_SENSOR_DIRTY:
                 return context.getString(R.string.face_acquired_sensor_dirty);
+            case FACE_ACQUIRED_DARK_GLASSES_DETECTED:
+                return context.getString(R.string.face_acquired_dark_glasses_detected);
+            case FACE_ACQUIRED_MOUTH_COVERING_DETECTED:
+                return context.getString(R.string.face_acquired_mouth_covering_detected);
             case FACE_ACQUIRED_VENDOR: {
                 String[] msgArray = context.getResources().getStringArray(
                         R.array.face_acquired_vendor);
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index eccbb40..9a7ccc6 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -53,7 +53,6 @@
     private static final int DO_APP_PRIVATE_COMMAND = 100;
     private static final int DO_FINISH_SESSION = 110;
     private static final int DO_VIEW_CLICKED = 115;
-    private static final int DO_NOTIFY_IME_HIDDEN = 120;
     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;
@@ -133,10 +132,6 @@
                 mInputMethodSession.viewClicked(msg.arg1 == 1);
                 return;
             }
-            case DO_NOTIFY_IME_HIDDEN: {
-                mInputMethodSession.notifyImeHidden();
-                return;
-            }
             case DO_REMOVE_IME_SURFACE: {
                 mInputMethodSession.removeImeSurface();
                 return;
@@ -198,11 +193,6 @@
     }
 
     @Override
-    public void notifyImeHidden() {
-        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_NOTIFY_IME_HIDDEN));
-    }
-
-    @Override
     public void removeImeSurface() {
         mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_REMOVE_IME_SURFACE));
     }
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 4fdd534..a6ed423 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -1058,10 +1058,6 @@
         return viewRoot == null ? null : viewRoot.getInputToken();
     }
 
-    private void notifyImeHidden() {
-        requestHideSelf(0);
-    }
-
     private void scheduleImeSurfaceRemoval() {
         if (mShowInputRequested || mWindowVisible || mWindow == null
                 || mImeSurfaceScheduledForRemoval) {
@@ -1225,14 +1221,6 @@
         }
 
         /**
-         * Notify IME that window is hidden.
-         * @hide
-         */
-        public final void notifyImeHidden() {
-            InputMethodService.this.notifyImeHidden();
-        }
-
-        /**
          * Notify IME that surface can be now removed.
          * @hide
          */
diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java
index dc38db2..6910501 100644
--- a/core/java/android/inputmethodservice/NavigationBarController.java
+++ b/core/java/android/inputmethodservice/NavigationBarController.java
@@ -152,6 +152,7 @@
         private boolean mDrawLegacyNavigationBarBackground;
 
         private final Rect mTempRect = new Rect();
+        private final int[] mTempPos = new int[2];
 
         Impl(@NonNull InputMethodService inputMethodService) {
             mService = inputMethodService;
@@ -259,21 +260,28 @@
                 switch (originalInsets.touchableInsets) {
                     case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
                         if (inputFrame.getVisibility() == View.VISIBLE) {
-                            inputFrame.getBoundsOnScreen(mTempRect);
+                            inputFrame.getLocationInWindow(mTempPos);
+                            mTempRect.set(mTempPos[0], mTempPos[1],
+                                    mTempPos[0] + inputFrame.getWidth(),
+                                    mTempPos[1] + inputFrame.getHeight());
                             touchableRegion = new Region(mTempRect);
                         }
                         break;
                     case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
                         if (inputFrame.getVisibility() == View.VISIBLE) {
-                            inputFrame.getBoundsOnScreen(mTempRect);
-                            mTempRect.top = originalInsets.contentTopInsets;
+                            inputFrame.getLocationInWindow(mTempPos);
+                            mTempRect.set(mTempPos[0], originalInsets.contentTopInsets,
+                                    mTempPos[0] + inputFrame.getWidth() ,
+                                    mTempPos[1] + inputFrame.getHeight());
                             touchableRegion = new Region(mTempRect);
                         }
                         break;
                     case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
                         if (inputFrame.getVisibility() == View.VISIBLE) {
-                            inputFrame.getBoundsOnScreen(mTempRect);
-                            mTempRect.top = originalInsets.visibleTopInsets;
+                            inputFrame.getLocationInWindow(mTempPos);
+                            mTempRect.set(mTempPos[0], originalInsets.visibleTopInsets,
+                                    mTempPos[0] + inputFrame.getWidth(),
+                                    mTempPos[1] + inputFrame.getHeight());
                             touchableRegion = new Region(mTempRect);
                         }
                         break;
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 815e4f0..d71faee4 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -1205,13 +1205,16 @@
         }
 
         static Uri readFrom(Parcel parcel) {
-            return new HierarchicalUri(
-                parcel.readString8(),
-                Part.readFrom(parcel),
-                PathPart.readFrom(parcel),
-                Part.readFrom(parcel),
-                Part.readFrom(parcel)
-            );
+            final String scheme = parcel.readString8();
+            final Part authority = Part.readFrom(parcel);
+            // In RFC3986 the path should be determined based on whether there is a scheme or
+            // authority present (https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3).
+            final boolean hasSchemeOrAuthority =
+                    (scheme != null && scheme.length() > 0) || !authority.isEmpty();
+            final PathPart path = PathPart.readFrom(hasSchemeOrAuthority, parcel);
+            final Part query = Part.readFrom(parcel);
+            final Part fragment = Part.readFrom(parcel);
+            return new HierarchicalUri(scheme, authority, path, query, fragment);
         }
 
         public int describeContents() {
@@ -2270,6 +2273,11 @@
             }
         }
 
+        static PathPart readFrom(boolean hasSchemeOrAuthority, Parcel parcel) {
+            final PathPart path = readFrom(parcel);
+            return hasSchemeOrAuthority ? makeAbsolute(path) : path;
+        }
+
         /**
          * Creates a path from the encoded string.
          *
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index c6cf097..cb7e6f7 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -94,6 +94,8 @@
 
     private static final int VULKAN_1_0 = 0x00400000;
     private static final int VULKAN_1_1 = 0x00401000;
+    private static final int VULKAN_1_2 = 0x00402000;
+    private static final int VULKAN_1_3 = 0x00403000;
 
     // Values for UPDATABLE_DRIVER_ALL_APPS
     // 0: Default (Invalid values fallback to default as well)
@@ -213,6 +215,14 @@
     private int getVulkanVersion(PackageManager pm) {
         // PackageManager doesn't have an API to retrieve the version of a specific feature, and we
         // need to avoid retrieving all system features here and looping through them.
+        if (pm.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, VULKAN_1_3)) {
+            return VULKAN_1_3;
+        }
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, VULKAN_1_2)) {
+            return VULKAN_1_2;
+        }
+
         if (pm.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, VULKAN_1_1)) {
             return VULKAN_1_1;
         }
diff --git a/core/java/android/permission/ILegacyPermissionManager.aidl b/core/java/android/permission/ILegacyPermissionManager.aidl
index f1f0836..78e12de 100644
--- a/core/java/android/permission/ILegacyPermissionManager.aidl
+++ b/core/java/android/permission/ILegacyPermissionManager.aidl
@@ -49,4 +49,6 @@
     void grantDefaultPermissionsToActiveLuiApp(in String packageName, int userId);
 
     void revokeDefaultPermissionsFromLuiApps(in String[] packageNames, int userId);
+
+    void grantDefaultPermissionsToCarrierServiceApp(in String packageName, int userId);
 }
diff --git a/core/java/android/permission/LegacyPermissionManager.java b/core/java/android/permission/LegacyPermissionManager.java
index a4fa11b..5777685 100644
--- a/core/java/android/permission/LegacyPermissionManager.java
+++ b/core/java/android/permission/LegacyPermissionManager.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemService;
+import android.annotation.UserIdInt;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.RemoteException;
@@ -244,4 +245,20 @@
             e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Grant permissions to a newly set Carrier Services app.
+     * @param packageName The newly set Carrier Services app
+     * @param userId The user for which to grant the permissions.
+     * @hide
+     */
+    public void grantDefaultPermissionsToCarrierServiceApp(@NonNull String packageName,
+            @UserIdInt int userId) {
+        try {
+            mLegacyPermissionManager.grantDefaultPermissionsToCarrierServiceApp(packageName,
+                    userId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index d25e456..37f44e9 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -731,6 +731,13 @@
     public static final String NAMESPACE_AMBIENT_CONTEXT_MANAGER_SERVICE =
             "ambient_context_manager_service";
 
+    /**
+     * Namespace for Vendor System Native related features.
+     *
+     * @hide
+     */
+    public static final String NAMESPACE_VENDOR_SYSTEM_NATIVE = "vendor_system_native";
+
     private static final Object sLock = new Object();
     @GuardedBy("sLock")
     private static ArrayMap<OnPropertiesChangedListener, Pair<String, Executor>> sListeners =
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e44d3de..e121ba7 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7086,7 +7086,7 @@
          *
          * @hide
          */
-        @Readable
+        @Readable(maxTargetSdk = Build.VERSION_CODES.S)
         public static final String ALWAYS_ON_VPN_LOCKDOWN_WHITELIST =
                 "always_on_vpn_lockdown_whitelist";
 
diff --git a/core/java/android/service/games/GameSession.java b/core/java/android/service/games/GameSession.java
index 0115294..e8d53d3 100644
--- a/core/java/android/service/games/GameSession.java
+++ b/core/java/android/service/games/GameSession.java
@@ -25,7 +25,6 @@
 import android.annotation.SystemApi;
 import android.app.ActivityTaskManager;
 import android.app.Instrumentation;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
@@ -511,14 +510,11 @@
                             callback.onActivityResult(result.getResultCode(), result.getData());
                         }, executor);
 
-        final Intent trampolineIntent = new Intent();
-        trampolineIntent.setComponent(
-                new ComponentName(
-                        "android", "android.service.games.GameSessionTrampolineActivity"));
-        trampolineIntent.putExtra(GameSessionTrampolineActivity.INTENT_KEY, intent);
-        trampolineIntent.putExtra(GameSessionTrampolineActivity.OPTIONS_KEY, options);
-        trampolineIntent.putExtra(
-                GameSessionTrampolineActivity.FUTURE_KEY, future);
+        final Intent trampolineIntent =
+                GameSessionTrampolineActivity.createIntent(
+                        intent,
+                        options,
+                        future);
 
         try {
             int result = ActivityTaskManager.getService().startActivityFromGameSession(
diff --git a/core/java/android/service/games/GameSessionActivityResult.java b/core/java/android/service/games/GameSessionActivityResult.java
index a2ec6ad..c8099e6 100644
--- a/core/java/android/service/games/GameSessionActivityResult.java
+++ b/core/java/android/service/games/GameSessionActivityResult.java
@@ -22,8 +22,12 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.annotations.VisibleForTesting;
 
-final class GameSessionActivityResult implements Parcelable {
+
+/** @hide */
+@VisibleForTesting
+public final class GameSessionActivityResult implements Parcelable {
 
     public static final Creator<GameSessionActivityResult> CREATOR =
             new Creator<GameSessionActivityResult>() {
@@ -44,17 +48,17 @@
     @Nullable
     private final Intent mData;
 
-    GameSessionActivityResult(int resultCode, @Nullable Intent data) {
+    public GameSessionActivityResult(int resultCode, @Nullable Intent data) {
         mResultCode = resultCode;
         mData = data;
     }
 
-    int getResultCode() {
+    public int getResultCode() {
         return mResultCode;
     }
 
     @Nullable
-    Intent getData() {
+    public Intent getData() {
         return mData;
     }
 
diff --git a/core/java/android/service/games/GameSessionService.java b/core/java/android/service/games/GameSessionService.java
index df5bad5..52c8ec3 100644
--- a/core/java/android/service/games/GameSessionService.java
+++ b/core/java/android/service/games/GameSessionService.java
@@ -21,6 +21,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
 import android.hardware.display.DisplayManager;
 import android.os.Binder;
@@ -28,6 +29,7 @@
 import android.os.IBinder;
 import android.view.Display;
 import android.view.SurfaceControlViewHost;
+import android.view.WindowManager;
 
 import com.android.internal.infra.AndroidFuture;
 import com.android.internal.util.function.pooled.PooledLambda;
@@ -117,13 +119,18 @@
         }
 
         IBinder hostToken = new Binder();
+
+        // Use a WindowContext so that views attached to the SurfaceControlViewHost will receive
+        // configuration changes (rather than always perceiving the global configuration).
+        final Context windowContext = createWindowContext(display,
+                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, /*options=*/ null);
         SurfaceControlViewHost surfaceControlViewHost =
-                new SurfaceControlViewHost(this, display, hostToken);
+                new SurfaceControlViewHost(windowContext, display, hostToken);
 
         gameSession.attach(
                 gameSessionController,
                 createGameSessionRequest.getTaskId(),
-                this,
+                windowContext,
                 surfaceControlViewHost,
                 gameSessionViewHostConfiguration.mWidthPx,
                 gameSessionViewHostConfiguration.mHeightPx);
diff --git a/core/java/android/service/games/GameSessionTrampolineActivity.java b/core/java/android/service/games/GameSessionTrampolineActivity.java
index 3d97d0f..b237918 100644
--- a/core/java/android/service/games/GameSessionTrampolineActivity.java
+++ b/core/java/android/service/games/GameSessionTrampolineActivity.java
@@ -16,12 +16,15 @@
 
 package android.service.games;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.infra.AndroidFuture;
 
 import java.util.concurrent.Executor;
@@ -35,6 +38,7 @@
  *
  * @hide
  */
+@VisibleForTesting
 public final class GameSessionTrampolineActivity extends Activity {
     private static final String TAG = "GameSessionTrampoline";
     private static final int REQUEST_CODE = 1;
@@ -42,11 +46,52 @@
     static final String FUTURE_KEY = "GameSessionTrampolineActivity.future";
     static final String INTENT_KEY = "GameSessionTrampolineActivity.intent";
     static final String OPTIONS_KEY = "GameSessionTrampolineActivity.options";
+    private static final String HAS_LAUNCHED_INTENT_KEY =
+            "GameSessionTrampolineActivity.hasLaunchedIntent";
+    private boolean mHasLaunchedIntent = false;
+
+    /**
+     * Create an {@link Intent} for the {@link GameSessionTrampolineActivity} with the given
+     * parameters.
+     *
+     * @param targetIntent the forwarded {@link Intent} that is associated with the Activity that
+     *                     will be launched by the {@link GameSessionTrampolineActivity}.
+     * @param options      Activity options. See {@link #startActivity(Intent, Bundle)}.
+     * @param resultFuture the {@link AndroidFuture} that will complete with the activity results of
+     *                     {@code targetIntent} launched.
+     * @return the Intent that will launch the {@link GameSessionTrampolineActivity} with the given
+     * parameters.
+     * @hide
+     */
+    @VisibleForTesting
+    public static Intent createIntent(
+            @NonNull Intent targetIntent,
+            @Nullable Bundle options,
+            @NonNull AndroidFuture<GameSessionActivityResult> resultFuture) {
+        final Intent trampolineIntent = new Intent();
+        trampolineIntent.setComponent(
+                new ComponentName(
+                        "android", "android.service.games.GameSessionTrampolineActivity"));
+        trampolineIntent.putExtra(INTENT_KEY, targetIntent);
+        trampolineIntent.putExtra(OPTIONS_KEY, options);
+        trampolineIntent.putExtra(FUTURE_KEY, resultFuture);
+
+        return trampolineIntent;
+    }
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        if (savedInstanceState != null) {
+            mHasLaunchedIntent = savedInstanceState.getBoolean(HAS_LAUNCHED_INTENT_KEY);
+        }
+
+        if (mHasLaunchedIntent) {
+            return;
+        }
+        mHasLaunchedIntent = true;
+
         try {
             startActivityAsCaller(
                     getIntent().getParcelableExtra(INTENT_KEY),
@@ -60,10 +105,17 @@
                     FUTURE_KEY);
             future.completeExceptionally(e);
             finish();
+            overridePendingTransition(0, 0);
         }
     }
 
     @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(HAS_LAUNCHED_INTENT_KEY, mHasLaunchedIntent);
+    }
+
+    @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode != REQUEST_CODE) {
             // Something went very wrong if we hit this code path, and we should bail.
@@ -74,5 +126,6 @@
                 FUTURE_KEY);
         future.complete(new GameSessionActivityResult(resultCode, data));
         finish();
+        overridePendingTransition(0, 0);
     }
 }
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 4bbfbc2..b783f6b8 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -1095,7 +1095,7 @@
             if (!mWindowVisible) {
                 mWindowVisible = true;
                 if (mUiEnabled) {
-                    mWindow.show();
+                    showWindow();
                 }
             }
             if (showCallback != null) {
@@ -1284,9 +1284,25 @@
         }
     }
 
+    void showWindow() {
+        if (mWindow != null) {
+            mWindow.show();
+            try {
+                mSystemService.setSessionWindowVisible(mToken, true);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to notify session window shown", e);
+            }
+        }
+    }
+
     void ensureWindowHidden() {
         if (mWindow != null) {
             mWindow.hide();
+            try {
+                mSystemService.setSessionWindowVisible(mToken, false);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to notify session window hidden", e);
+            }
         }
     }
 
@@ -1377,7 +1393,7 @@
             if (mWindowVisible) {
                 if (enabled) {
                     ensureWindowAdded();
-                    mWindow.show();
+                    showWindow();
                 } else {
                     ensureWindowHidden();
                 }
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 60593ca..77591a7 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -765,18 +765,24 @@
                 startNanos = System.nanoTime();
                 final long jitterNanos = startNanos - frameTimeNanos;
                 if (jitterNanos >= frameIntervalNanos) {
-                    final long skippedFrames = jitterNanos / frameIntervalNanos;
-                    if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
-                        Log.i(TAG, "Skipped " + skippedFrames + " frames!  "
-                                + "The application may be doing too much work on its main thread.");
-                    }
                     final long lastFrameOffset = jitterNanos % frameIntervalNanos;
-                    if (DEBUG_JANK) {
-                        Log.d(TAG, "Missed vsync by " + (jitterNanos * 0.000001f) + " ms "
-                                + "which is more than the frame interval of "
-                                + (frameIntervalNanos * 0.000001f) + " ms!  "
-                                + "Skipping " + skippedFrames + " frames and setting frame "
-                                + "time to " + (lastFrameOffset * 0.000001f) + " ms in the past.");
+                    if (frameIntervalNanos == 0) {
+                        Log.i(TAG, "Vsync data empty due to timeout");
+                    } else {
+                        final long skippedFrames = jitterNanos / frameIntervalNanos;
+                        if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
+                            Log.i(TAG, "Skipped " + skippedFrames + " frames!  "
+                                    + "The application may be doing too much work on its main "
+                                    + "thread.");
+                        }
+                        if (DEBUG_JANK) {
+                            Log.d(TAG, "Missed vsync by " + (jitterNanos * 0.000001f) + " ms "
+                                    + "which is more than the frame interval of "
+                                    + (frameIntervalNanos * 0.000001f) + " ms!  "
+                                    + "Skipping " + skippedFrames + " frames and setting frame "
+                                    + "time to " + (lastFrameOffset * 0.000001f)
+                                    + " ms in the past.");
+                        }
                     }
                     frameTimeNanos = startNanos - lastFrameOffset;
                     DisplayEventReceiver.VsyncEventData latestVsyncEventData =
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 0c4d9bf..f8a848e 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -26,11 +26,9 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressLint;
 import android.annotation.TestApi;
-import android.app.ActivityThread;
 import android.app.KeyguardManager;
 import android.app.WindowConfiguration;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.content.ComponentName;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -52,14 +50,11 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 
-import com.android.internal.R;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Optional;
 
 /**
  * Provides information about the size and density of a logical display.
@@ -116,12 +111,6 @@
     private int mCachedAppHeightCompat;
 
     /**
-     * Cache if the application is the recents component.
-     * TODO(b/179308296) Remove once Launcher addresses issue
-     */
-    private Optional<Boolean> mIsRecentsComponent = Optional.empty();
-
-    /**
      * The default Display id, which is the id of the primary display assuming there is one.
      */
     public static final int DEFAULT_DISPLAY = 0;
@@ -1584,36 +1573,7 @@
             return false;
         }
         final Configuration config = mResources.getConfiguration();
-        // TODO(b/179308296) Temporarily exclude Launcher from being given max bounds, by checking
-        // if the caller is the recents component.
-        return config != null && !config.windowConfiguration.getMaxBounds().isEmpty()
-                && !isRecentsComponent();
-    }
-
-    /**
-     * Returns {@code true} when the calling package is the recents component.
-     * TODO(b/179308296) Remove once Launcher addresses issue
-     */
-    boolean isRecentsComponent() {
-        if (mIsRecentsComponent.isPresent()) {
-            return mIsRecentsComponent.get();
-        }
-        if (mResources == null) {
-            return false;
-        }
-        try {
-            String recentsComponent = mResources.getString(R.string.config_recentsComponentName);
-            if (recentsComponent == null) {
-                return false;
-            }
-            String recentsPackage = ComponentName.unflattenFromString(recentsComponent)
-                    .getPackageName();
-            mIsRecentsComponent = Optional.of(recentsPackage != null
-                    && recentsPackage.equals(ActivityThread.currentPackageName()));
-            return mIsRecentsComponent.get();
-        } catch (Resources.NotFoundException e) {
-            return false;
-        }
+        return config != null && !config.windowConfiguration.getMaxBounds().isEmpty();
     }
 
     /**
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 5ce5477..c83869c 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -249,7 +249,7 @@
      * Set whether screen capture is disabled for all windows of a specific user from
      * the device policy cache.
      */
-    void refreshScreenCaptureDisabled(int userId);
+    void refreshScreenCaptureDisabled();
 
     // These can only be called with the SET_ORIENTATION permission.
     /**
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index d609fb8..4fdea3b 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -18,12 +18,13 @@
 
 import static android.os.Trace.TRACE_TAG_VIEW;
 import static android.view.ImeInsetsSourceConsumerProto.INSETS_SOURCE_CONSUMER;
+import static android.view.ImeInsetsSourceConsumerProto.IS_HIDE_ANIMATION_RUNNING;
 import static android.view.ImeInsetsSourceConsumerProto.IS_REQUESTED_VISIBLE_AWAITING_CONTROL;
+import static android.view.ImeInsetsSourceConsumerProto.IS_SHOW_REQUESTED_DURING_HIDE_ANIMATION;
 import static android.view.InsetsController.AnimationType;
 import static android.view.InsetsState.ITYPE_IME;
 
 import android.annotation.Nullable;
-import android.inputmethodservice.InputMethodService;
 import android.os.IBinder;
 import android.os.Trace;
 import android.util.proto.ProtoOutputStream;
@@ -44,6 +45,16 @@
      */
     private boolean mIsRequestedVisibleAwaitingControl;
 
+    private boolean mIsHideAnimationRunning;
+
+    /**
+     * Tracks whether {@link WindowInsetsController#show(int)} or
+     * {@link InputMethodManager#showSoftInput(View, int)} is called during IME hide animation.
+     * If it was called, we should not call {@link InputMethodManager#notifyImeHidden(IBinder)},
+     * because the IME is being shown.
+     */
+    private boolean mIsShowRequestedDuringHideAnimation;
+
     public ImeInsetsSourceConsumer(
             InsetsState state, Supplier<Transaction> transactionSupplier,
             InsetsController controller) {
@@ -64,6 +75,12 @@
     }
 
     @Override
+    public void show(boolean fromIme) {
+        super.show(fromIme);
+        onShowRequested();
+    }
+
+    @Override
     public void hide() {
         super.hide();
         mIsRequestedVisibleAwaitingControl = false;
@@ -74,10 +91,20 @@
         hide();
 
         if (animationFinished) {
-            // remove IME surface as IME has finished hide animation.
-            notifyHidden();
-            removeSurface();
+            // Remove IME surface as IME has finished hide animation, if there is no pending
+            // show request.
+            if (!mIsShowRequestedDuringHideAnimation) {
+                notifyHidden();
+                removeSurface();
+            }
         }
+        // This method is called
+        // (1) before the hide animation starts.
+        // (2) after the hide animation ends.
+        // (3) if the IME is not controllable (animationFinished == true in this case).
+        // We should reset mIsShowRequestedDuringHideAnimation in all cases.
+        mIsHideAnimationRunning = !animationFinished;
+        mIsShowRequestedDuringHideAnimation = false;
     }
 
     /**
@@ -104,7 +131,8 @@
     }
 
     /**
-     * Notify {@link InputMethodService} that IME window is hidden.
+     * Notify {@link com.android.server.inputmethod.InputMethodManagerService} that
+     * IME insets are hidden.
      */
     @Override
     void notifyHidden() {
@@ -157,9 +185,20 @@
         final long token = proto.start(fieldId);
         super.dumpDebug(proto, INSETS_SOURCE_CONSUMER);
         proto.write(IS_REQUESTED_VISIBLE_AWAITING_CONTROL, mIsRequestedVisibleAwaitingControl);
+        proto.write(IS_HIDE_ANIMATION_RUNNING, mIsHideAnimationRunning);
+        proto.write(IS_SHOW_REQUESTED_DURING_HIDE_ANIMATION, mIsShowRequestedDuringHideAnimation);
         proto.end(token);
     }
 
+    /**
+     * Called when {@link #show} or {@link InputMethodManager#showSoftInput(View, int)} is called.
+     */
+    public void onShowRequested() {
+        if (mIsHideAnimationRunning) {
+            mIsShowRequestedDuringHideAnimation = true;
+        }
+    }
+
     private InputMethodManager getImm() {
         return mController.getHost().getInputMethodManager();
     }
diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java
index e6cf683..5832527 100644
--- a/core/java/android/view/InsetsSource.java
+++ b/core/java/android/view/InsetsSource.java
@@ -47,6 +47,7 @@
     private final Rect mFrame;
     private @Nullable Rect mVisibleFrame;
     private boolean mVisible;
+    private boolean mInsetsRoundedCornerFrame;
 
     private final Rect mTmpFrame = new Rect();
 
@@ -63,6 +64,7 @@
         mVisibleFrame = other.mVisibleFrame != null
                 ? new Rect(other.mVisibleFrame)
                 : null;
+        mInsetsRoundedCornerFrame = other.mInsetsRoundedCornerFrame;
     }
 
     public void set(InsetsSource other) {
@@ -71,6 +73,7 @@
         mVisibleFrame = other.mVisibleFrame != null
                 ? new Rect(other.mVisibleFrame)
                 : null;
+        mInsetsRoundedCornerFrame = other.mInsetsRoundedCornerFrame;
     }
 
     public void setFrame(int left, int top, int right, int bottom) {
@@ -110,6 +113,14 @@
         return mVisibleFrame == null || !mVisibleFrame.isEmpty();
     }
 
+    public boolean getInsetsRoundedCornerFrame() {
+        return mInsetsRoundedCornerFrame;
+    }
+
+    public void setInsetsRoundedCornerFrame(boolean insetsRoundedCornerFrame) {
+        mInsetsRoundedCornerFrame = insetsRoundedCornerFrame;
+    }
+
     /**
      * Calculates the insets this source will cause to a client window.
      *
@@ -225,6 +236,7 @@
             pw.print(" visibleFrame="); pw.print(mVisibleFrame.toShortString());
         }
         pw.print(" visible="); pw.print(mVisible);
+        pw.print(" insetsRoundedCornerFrame="); pw.print(mInsetsRoundedCornerFrame);
         pw.println();
     }
 
@@ -247,6 +259,7 @@
         if (mVisible != that.mVisible) return false;
         if (excludeInvisibleImeFrames && !mVisible && mType == ITYPE_IME) return true;
         if (!Objects.equals(mVisibleFrame, that.mVisibleFrame)) return false;
+        if (mInsetsRoundedCornerFrame != that.mInsetsRoundedCornerFrame) return false;
         return mFrame.equals(that.mFrame);
     }
 
@@ -256,6 +269,7 @@
         result = 31 * result + mFrame.hashCode();
         result = 31 * result + (mVisibleFrame != null ? mVisibleFrame.hashCode() : 0);
         result = 31 * result + (mVisible ? 1 : 0);
+        result = 31 * result + (mInsetsRoundedCornerFrame ? 1 : 0);
         return result;
     }
 
@@ -268,6 +282,7 @@
             mVisibleFrame = null;
         }
         mVisible = in.readBoolean();
+        mInsetsRoundedCornerFrame = in.readBoolean();
     }
 
     @Override
@@ -286,6 +301,7 @@
             dest.writeInt(0);
         }
         dest.writeBoolean(mVisible);
+        dest.writeBoolean(mInsetsRoundedCornerFrame);
     }
 
     @Override
@@ -294,6 +310,7 @@
                 + "mType=" + InsetsState.typeToString(mType)
                 + ", mFrame=" + mFrame.toShortString()
                 + ", mVisible=" + mVisible
+                + ", mInsetsRoundedCornerFrame=" + mInsetsRoundedCornerFrame
                 + "}";
     }
 
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 6aab635..4d9033d 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -25,6 +25,7 @@
 import static android.view.InsetsSourceConsumerProto.PENDING_FRAME;
 import static android.view.InsetsSourceConsumerProto.PENDING_VISIBLE_FRAME;
 import static android.view.InsetsSourceConsumerProto.SOURCE_CONTROL;
+import static android.view.InsetsSourceControl.INVALID_HINTS;
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.getDefaultVisibility;
 import static android.view.InsetsState.toPublicType;
@@ -163,8 +164,10 @@
             // We are gaining control, and need to run an animation since previous state
             // didn't match
             final boolean requestedVisible = isRequestedVisibleAwaitingControl();
-            final boolean needAnimation = requestedVisible != mState.getSource(mType).isVisible();
-            if (control.getLeash() != null && (needAnimation || mIsAnimationPending)) {
+            final boolean fakeControl = INVALID_HINTS.equals(control.getInsetsHint());
+            final boolean needsAnimation = requestedVisible != mState.getSource(mType).isVisible()
+                    && !fakeControl;
+            if (control.getLeash() != null && (needsAnimation || mIsAnimationPending)) {
                 if (DEBUG) Log.d(TAG, String.format("Gaining control in %s, requestedVisible: %b",
                         mController.getHost().getRootViewTitle(), requestedVisible));
                 if (requestedVisible) {
@@ -174,7 +177,7 @@
                 }
                 mIsAnimationPending = false;
             } else {
-                if (needAnimation) {
+                if (needsAnimation) {
                     // We need animation but we haven't had a leash yet. Set this flag that when we
                     // get the leash we can play the deferred animation.
                     mIsAnimationPending = true;
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index 9d98a3e..2cf827d 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -39,6 +39,8 @@
  */
 public class InsetsSourceControl implements Parcelable {
 
+    public static final Insets INVALID_HINTS = Insets.of(-1, -1, -1, -1);
+
     private final @InternalInsetsType int mType;
     private final @Nullable SurfaceControl mLeash;
     private final Point mSurfacePosition;
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index eb74608..9d6b982 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -294,9 +294,16 @@
             return RoundedCorners.NO_ROUNDED_CORNERS;
         }
         // If mRoundedCornerFrame is set, we should calculate the new RoundedCorners based on this
-        // frame. It's used for split-screen mode and devices with a task bar.
-        if (!mRoundedCornerFrame.isEmpty() && !mRoundedCornerFrame.equals(mDisplayFrame)) {
-            return mRoundedCorners.insetWithFrame(frame, mRoundedCornerFrame);
+        // frame.
+        final Rect roundedCornerFrame = new Rect(mRoundedCornerFrame);
+        for (InsetsSource source : mSources) {
+            if (source != null && source.getInsetsRoundedCornerFrame()) {
+                final Insets insets = source.calculateInsets(roundedCornerFrame, false);
+                roundedCornerFrame.inset(insets);
+            }
+        }
+        if (!roundedCornerFrame.isEmpty() && !roundedCornerFrame.equals(mDisplayFrame)) {
+            return mRoundedCorners.insetWithFrame(frame, roundedCornerFrame);
         }
         if (mDisplayFrame.equals(frame)) {
             return mRoundedCorners;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index dc3620b..62d0d37d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12063,8 +12063,11 @@
      * Gets the coordinates of this view in the coordinate space of the
      * {@link Surface} that contains the view.
      *
-     * <p>After the method returns, the argument array contains the x- and
-     * y-coordinates of the view relative to the view's left and top edges,
+     * <p>In multiple-screen scenarios, if the surface spans multiple screens,
+     * the coordinate space of the surface also spans multiple screens.
+     *
+     * <p>After the method returns, the argument array contains the x and y
+     * coordinates of the view relative to the view's left and top edges,
      * respectively.
      *
      * @param location A two-element integer array in which the view coordinates
@@ -18740,18 +18743,37 @@
     }
 
     /**
-     * If some part of this view is not clipped by any of its parents, then
-     * return that area in r in global (root) coordinates. To convert r to local
-     * coordinates (without taking possible View rotations into account), offset
-     * it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)).
-     * If the view is completely clipped or translated out, return false.
+     * Sets {@code r} to the coordinates of the non-clipped area of this view in
+     * the coordinate space of the view's root view. Sets {@code globalOffset}
+     * to the offset of the view's x and y coordinates from the coordinate space
+     * origin, which is the top left corner of the root view irrespective of
+     * screen decorations and system UI elements.
      *
-     * @param r If true is returned, r holds the global coordinates of the
-     *        visible portion of this view.
-     * @param globalOffset If true is returned, globalOffset holds the dx,dy
-     *        between this view and its root. globalOffet may be null.
-     * @return true if r is non-empty (i.e. part of the view is visible at the
-     *         root level.
+     * <p>To convert {@code r} to coordinates relative to the top left corner of
+     * this view (without taking view rotations into account), offset {@code r}
+     * by the inverse values of
+     * {@code globalOffset}&mdash;{@code r.offset(-globalOffset.x,
+     * -globalOffset.y)}&mdash;which is equivalent to calling
+     * {@link #getLocalVisibleRect(Rect) getLocalVisibleRect(Rect)}.
+     *
+     * <p><b>Note:</b> Do not use this method to determine the size of a window
+     * in multi-window mode; use
+     * {@link WindowManager#getCurrentWindowMetrics()}.
+     *
+     * @param r If the method returns true, contains the coordinates of the
+     *      visible portion of this view in the coordinate space of the view's
+     *      root view. If the method returns false, the contents of {@code r}
+     *      are undefined.
+     * @param globalOffset If the method returns true, contains the offset of
+     *      the x and y coordinates of this view from the top left corner of the
+     *      view's root view. If the method returns false, the contents of
+     *      {@code globalOffset} are undefined. The argument can be null (see
+     *      {@link #getGlobalVisibleRect(Rect) getGlobalVisibleRect(Rect)}.
+     * @return true if at least part of the view is visible within the root
+     *      view; false if the view is completely clipped or translated out of
+     *      the visible area of the root view.
+     *
+     * @see #getLocalVisibleRect(Rect)
      */
     public boolean getGlobalVisibleRect(Rect r, Point globalOffset) {
         int width = mRight - mLeft;
@@ -18766,10 +18788,48 @@
         return false;
     }
 
+    /**
+     * Sets {@code r} to the coordinates of the non-clipped area of this view in
+     * the coordinate space of the view's root view.
+     *
+     * <p>See {@link #getGlobalVisibleRect(Rect, Point)
+     * getGlobalVisibleRect(Rect, Point)} for more information.
+     *
+     * @param r If the method returns true, contains the coordinates of the
+     *      visible portion of this view in the coordinate space of the view's
+     *      root view. If the method returns false, the contents of {@code r}
+     *      are undefined.
+     * @return true if at least part of the view is visible within the root
+     *      view; otherwise false.
+     */
     public final boolean getGlobalVisibleRect(Rect r) {
         return getGlobalVisibleRect(r, null);
     }
 
+    /**
+     * Sets {@code r} to the coordinates of the non-clipped area of this view
+     * relative to the top left corner of the view.
+     *
+     * <p>If the view is clipped on the left or top, the left and top
+     * coordinates are offset from 0 by the clipped amount. For example, if the
+     * view is off screen 50px on the left and 30px at the top, the left and top
+     * coordinates are 50 and 30 respectively.
+     *
+     * <p>If the view is clipped on the right or bottom, the right and bottom
+     * coordinates are reduced by the clipped amount. For example, if the view
+     * is off screen 40px on the right and 20px at the bottom, the right
+     * coordinate is the view width - 40, and the bottom coordinate is the view
+     * height - 20.
+     *
+     * @param r If the method returns true, contains the coordinates of the
+     *      visible portion of this view relative to the top left corner of the
+     *      view. If the method returns false, the contents of {@code r} are
+     *      undefined.
+     * @return true if at least part of the view is visible; false if the view
+     *      is completely clipped or translated out of the visible area.
+     *
+     * @see #getGlobalVisibleRect(Rect, Point)
+     */
     public final boolean getLocalVisibleRect(Rect r) {
         final Point offset = mAttachInfo != null ? mAttachInfo.mPoint : new Point();
         if (getGlobalVisibleRect(r, offset)) {
@@ -25585,22 +25645,26 @@
     }
 
     /**
-     * Gets the global coordinates of this view. The coordinates are in the
-     * coordinate space of the device screen, irrespective of system decorations
-     * and whether the system is in multi-window mode.
+     * Gets the coordinates of this view in the coordinate space of the device
+     * screen, irrespective of system decorations and whether the system is in
+     * multi-window mode.
      *
-     * <p>In multi-window mode, the global coordinate space encompasses the
-     * entire device screen, ignoring the bounds of the app window. For
-     * example, if the view is in the bottom portion of a horizontal split
-     * screen, the top edge of the screen&mdash;not the top edge of the
-     * window&mdash;is the origin from which the y-coordinate is calculated.
+     * <p>In multi-window mode, the coordinate space encompasses the entire
+     * device screen, ignoring the bounds of the app window. For example, if the
+     * view is in the bottom portion of a horizontal split screen, the top edge
+     * of the screen&mdash;not the top edge of the window&mdash;is the origin
+     * from which the y-coordinate is calculated.
      *
-     * <p><b>Note:</b> In multiple-screen scenarios, the global coordinate space
-     * is restricted to the screen on which the view is displayed. The
-     * coordinate space does not span multiple screens.
+     * <p>In multiple-screen scenarios, the coordinate space can span screens.
+     * For example, if the app is spanning both screens of a dual-screen device
+     * and the view is located on the right-hand screen, the x-coordinate is
+     * calculated from the left edge of the left-hand screen to the left edge of
+     * the view. When the app is restricted to a single screen in a
+     * multiple-screen environment, the coordinate space includes only the
+     * screen on which the app is running.
      *
-     * <p>After the method returns, the argument array contains the x- and
-     * y-coordinates of the view relative to the view's left and top edges,
+     * <p>After the method returns, the argument array contains the x and y
+     * coordinates of the view relative to the view's left and top edges,
      * respectively.
      *
      * @param outLocation A two-element integer array in which the view
@@ -25625,8 +25689,13 @@
      * top left corner of the window that contains the view. In full screen
      * mode, the origin is the top left corner of the device screen.
      *
-     * <p>After the method returns, the argument array contains the x- and
-     * y-coordinates of the view relative to the view's left and top edges,
+     * <p>In multiple-screen scenarios, if the app spans multiple screens, the
+     * coordinate space also spans multiple screens. But if the app is
+     * restricted to a single screen, the coordinate space includes only the
+     * screen on which the app is running.
+     *
+     * <p>After the method returns, the argument array contains the x and y
+     * coordinates of the view relative to the view's left and top edges,
      * respectively.
      *
      * @param outLocation A two-element integer array in which the view
@@ -28733,7 +28802,7 @@
      *     {@link InputDevice#SOURCE_MOUSE_RELATIVE}, and relative position changes will be
      *     available through {@link MotionEvent#getX} and {@link MotionEvent#getY}.</li>
      *
-     *     <li>Events from a touchpad will be delivered with the source
+     *     <li>Events from a touchpad or trackpad will be delivered with the source
      *     {@link InputDevice#SOURCE_TOUCHPAD}, where the absolute position of each of the pointers
      *     on the touchpad will be available through {@link MotionEvent#getX(int)} and
      *     {@link MotionEvent#getY(int)}, and their relative movements are stored in
@@ -28742,6 +28811,12 @@
      *     <li>Events from other types of devices, such as touchscreens, will not be affected.</li>
      * </ul>
      * <p>
+     * When pointer capture changes, connected mouse and trackpad devices may be reconfigured,
+     * and their properties (such as their sources or motion ranges) may change. Use an
+     * {@link android.hardware.input.InputManager.InputDeviceListener} to be notified when a device
+     * changes (which may happen after enabling or disabling pointer capture), and use
+     * {@link InputDevice#getDevice(int)} to get the updated {@link InputDevice}.
+     * <p>
      * Events captured through pointer capture will be dispatched to
      * {@link OnCapturedPointerListener#onCapturedPointer(View, MotionEvent)} if an
      * {@link OnCapturedPointerListener} is set, and otherwise to
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 90e3498..4baad1e 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -1058,11 +1058,6 @@
 
     /**
      * Refreshes this info with the latest state of the view it represents.
-     * <p>
-     * <strong>Note:</strong> If this method returns false this info is obsolete
-     * since it represents a view that is no longer in the view tree and should
-     * be recycled.
-     * </p>
      *
      * @param bypassCache Whether to bypass the cache.
      * @return Whether the refresh succeeded.
@@ -1089,8 +1084,7 @@
      * Refreshes this info with the latest state of the view it represents.
      *
      * @return {@code true} if the refresh succeeded. {@code false} if the {@link View} represented
-     * by this node is no longer in the view tree (and thus this node is obsolete and should be
-     * recycled).
+     * by this node is no longer in the view tree (and thus this node is obsolete).
      */
     public boolean refresh() {
         return refresh(null, true);
@@ -1109,8 +1103,7 @@
      * @param args A bundle of arguments for the request. These depend on the particular request.
      *
      * @return {@code true} if the refresh succeeded. {@code false} if the {@link View} represented
-     * by this node is no longer in the view tree (and thus this node is obsolete and should be
-     * recycled).
+     * by this node is no longer in the view tree (and thus this node is obsolete).
      */
     public boolean refreshWithExtraData(String extraDataKey, Bundle args) {
         // limits the text location length to make sure the rectangle array allocation avoids
@@ -1823,11 +1816,6 @@
      * this info is the root of the traversed tree.
      *
      * <p>
-     *   <strong>Note:</strong> It is a client responsibility to recycle the
-     *     received info by calling {@link AccessibilityNodeInfo#recycle()}
-     *     to avoid creating of multiple instances.
-     * </p>
-     * <p>
      * <strong>Note:</strong> If this view hierarchy has a {@link SurfaceView} embedding another
      * view hierarchy via {@link SurfaceView#setChildSurfacePackage}, there is a limitation that
      * this API won't be able to find the node for the view on the embedded view hierarchy. It's
@@ -1855,11 +1843,6 @@
      * resource name is "baz", the fully qualified resource id is "foo.bar:id/baz".
      *
      * <p>
-     *   <strong>Note:</strong> It is a client responsibility to recycle the
-     *     received info by calling {@link AccessibilityNodeInfo#recycle()}
-     *     to avoid creating of multiple instances.
-     * </p>
-     * <p>
      *   <strong>Note:</strong> The primary usage of this API is for UI test automation
      *   and in order to report the fully qualified view id if an {@link AccessibilityNodeInfo}
      *   the client has to set the {@link AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS}
@@ -3282,11 +3265,6 @@
     /**
      * Gets the node info for which the view represented by this info serves as
      * a label for accessibility purposes.
-     * <p>
-     *   <strong>Note:</strong> It is a client responsibility to recycle the
-     *     received info by calling {@link AccessibilityNodeInfo#recycle()}
-     *     to avoid creating of multiple instances.
-     * </p>
      *
      * @return The labeled info.
      */
@@ -3334,11 +3312,6 @@
     /**
      * Gets the node info which serves as the label of the view represented by
      * this info for accessibility purposes.
-     * <p>
-     *   <strong>Note:</strong> It is a client responsibility to recycle the
-     *     received info by calling {@link AccessibilityNodeInfo#recycle()}
-     *     to avoid creating of multiple instances.
-     * </p>
      *
      * @return The label.
      */
@@ -5312,9 +5285,7 @@
     }
 
     /**
-     * Class with information if a node is a range. Use
-     * {@link RangeInfo#obtain(int, float, float, float)} to get an instance. Recycling is
-     * handled by the {@link AccessibilityNodeInfo} to which this object is attached.
+     * Class with information if a node is a range.
      */
     public static final class RangeInfo {
 
@@ -5423,9 +5394,7 @@
     }
 
     /**
-     * Class with information if a node is a collection. Use
-     * {@link CollectionInfo#obtain(int, int, boolean)} to get an instance. Recycling is
-     * handled by the {@link AccessibilityNodeInfo} to which this object is attached.
+     * Class with information if a node is a collection.
      * <p>
      * A collection of items has rows and columns and may be hierarchical.
      * For example, a horizontal list is a collection with one column, as
@@ -5591,10 +5560,7 @@
     }
 
     /**
-     * Class with information if a node is a collection item. Use
-     * {@link CollectionItemInfo#obtain(int, int, int, int, boolean)}
-     * to get an instance. Recycling is handled by the {@link AccessibilityNodeInfo} to which this
-     * object is attached.
+     * Class with information if a node is a collection item.
      * <p>
      * A collection item is contained in a collection, it starts at
      * a given row and column in the collection, and spans one or
@@ -6085,11 +6051,6 @@
          * <p>
          *   <strong>Note:</strong> This api can only be called from {@link AccessibilityService}.
          * </p>
-         * <p>
-         *   <strong>Note:</strong> It is a client responsibility to recycle the
-         *     received info by calling {@link AccessibilityNodeInfo#recycle()}
-         *     to avoid creating of multiple instances.
-         * </p>
          *
          * @param region The region retrieved from {@link #getRegionAt(int)}.
          * @return The target node associates with the given region.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 84f1393..8502568 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -543,6 +543,7 @@
     static final int MSG_BIND_ACCESSIBILITY_SERVICE = 11;
     static final int MSG_UNBIND_ACCESSIBILITY_SERVICE = 12;
     static final int MSG_UPDATE_VIRTUAL_DISPLAY_TO_SCREEN_MATRIX = 30;
+    static final int MSG_ON_SHOW_REQUESTED = 31;
 
     private static boolean isAutofillUIShowing(View servedView) {
         AutofillManager afm = servedView.getContext().getSystemService(AutofillManager.class);
@@ -1117,6 +1118,14 @@
                     }
                     return;
                 }
+                case MSG_ON_SHOW_REQUESTED: {
+                    synchronized (mH) {
+                        if (mImeInsetsConsumer != null) {
+                            mImeInsetsConsumer.onShowRequested();
+                        }
+                    }
+                    return;
+                }
             }
         }
     }
@@ -1834,6 +1843,9 @@
                 return false;
             }
 
+            // Makes sure to call ImeInsetsSourceConsumer#onShowRequested on the UI thread.
+            // TODO(b/229426865): call WindowInsetsController#show instead.
+            mH.executeOrSendMessage(Message.obtain(mH, MSG_ON_SHOW_REQUESTED));
             try {
                 Log.d(TAG, "showSoftInput() view=" + view + " flags=" + flags + " reason="
                         + InputMethodDebug.softInputDisplayReasonToString(reason));
@@ -1869,6 +1881,9 @@
                     Log.w(TAG, "No current root view, ignoring showSoftInputUnchecked()");
                     return;
                 }
+                // Makes sure to call ImeInsetsSourceConsumer#onShowRequested on the UI thread.
+                // TODO(b/229426865): call WindowInsetsController#show instead.
+                mH.executeOrSendMessage(Message.obtain(mH, MSG_ON_SHOW_REQUESTED));
                 mService.showSoftInput(
                         mClient,
                         mCurRootView.getView().getWindowToken(),
@@ -2521,7 +2536,7 @@
     }
 
     /**
-     * Notify IME directly that it is no longer visible.
+     * Notify IMMS that IME insets are no longer visible.
      *
      * @param windowToken the window from which this request originates. If this doesn't match the
      *                    currently served view, the request is ignored.
@@ -2533,7 +2548,13 @@
         synchronized (mH) {
             if (mCurrentInputMethodSession != null && mCurRootView != null
                     && mCurRootView.getWindowToken() == windowToken) {
-                mCurrentInputMethodSession.notifyImeHidden();
+                try {
+                    mService.hideSoftInput(mClient, windowToken, 0 /* flags */,
+                            null /* resultReceiver */,
+                            SoftInputShowHideReason.HIDE_SOFT_INPUT);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
             }
         }
     }
diff --git a/core/java/android/view/inputmethod/InputMethodSession.java b/core/java/android/view/inputmethod/InputMethodSession.java
index a178ee8..28c4450 100644
--- a/core/java/android/view/inputmethod/InputMethodSession.java
+++ b/core/java/android/view/inputmethod/InputMethodSession.java
@@ -195,13 +195,6 @@
     public void updateCursorAnchorInfo(CursorAnchorInfo cursorAnchorInfo);
 
     /**
-     * Notifies {@link android.inputmethodservice.InputMethodService} that IME has been
-     * hidden from user.
-     * @hide
-     */
-    public void notifyImeHidden();
-
-    /**
      * Notify IME directly to remove surface as it is no longer visible.
      * @hide
      */
diff --git a/core/java/android/view/inputmethod/InputMethodSessionWrapper.java b/core/java/android/view/inputmethod/InputMethodSessionWrapper.java
index a199520..ee22b65 100644
--- a/core/java/android/view/inputmethod/InputMethodSessionWrapper.java
+++ b/core/java/android/view/inputmethod/InputMethodSessionWrapper.java
@@ -106,15 +106,6 @@
     }
 
     @AnyThread
-    void notifyImeHidden() {
-        try {
-            mSession.notifyImeHidden();
-        } catch (RemoteException e) {
-            Log.w(TAG, "IME died", e);
-        }
-    }
-
-    @AnyThread
     void viewClicked(boolean focusChanged) {
         try {
             mSession.viewClicked(focusChanged);
diff --git a/core/java/android/view/translation/UiTranslationStateCallback.java b/core/java/android/view/translation/UiTranslationStateCallback.java
index 3ccca5f..96b6f8c 100644
--- a/core/java/android/view/translation/UiTranslationStateCallback.java
+++ b/core/java/android/view/translation/UiTranslationStateCallback.java
@@ -25,14 +25,28 @@
  * Callback for listening to UI Translation state changes. See {@link
  * UiTranslationManager#registerUiTranslationStateCallback(Executor, UiTranslationStateCallback)}.
  * <p>
- * Prior to Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}, callback methods
- * <em>without</em> {@code packageName} are invoked. Apps with minSdkVersion lower than {@link
- * android.os.Build.VERSION_CODES#TIRAMISU} <em>must</em> implement those methods if they want to
- * handle the events.
+ * Prior to Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}:
+ * <ul>
+ *     <li>Callback methods <em>without</em> {@code packageName} are invoked. Apps with
+ *     minSdkVersion lower than {@link android.os.Build.VERSION_CODES#TIRAMISU} <em>must</em>
+ *     implement those methods if they want to handle the events.</li>
+ *     <li>Callback methods for a particular event <em>may</em> be called multiple times
+ *     consecutively, even when the translation state has not changed (e.g.,
+ *     {@link #onStarted(ULocale, ULocale, String)} may be called multiple times even after
+ *     translation has already started).</li>
+ * </ul>
  * <p>
- * In Android version {@link android.os.Build.VERSION_CODES#TIRAMISU} and later, if both methods
- * with and without {@code packageName} are implemented (e.g., {@link #onFinished()} and {@link
- * #onFinished(String)}, only the one <em>with</em> {@code packageName} will be called.
+ * In Android version {@link android.os.Build.VERSION_CODES#TIRAMISU} and later:
+ * <ul>
+ *     <li>If both methods with and without {@code packageName} are implemented (e.g.,
+ *     {@link #onFinished()} and {@link #onFinished(String)}, only the one <em>with</em> {@code
+ *     packageName} will be called.</li>
+ *     <li>Callback methods for a particular event will <em>not</em> be called multiple times
+ *     consecutively. They will only be called when the translation state has actually changed
+ *     (e.g., from "started" to "paused"). Note: "resumed" is not considered a separate state
+ *     from "started", so {@link #onResumed(ULocale, ULocale, String)} will never be called after
+ *     {@link #onStarted(ULocale, ULocale, String)}.<</li>
+ * </ul>
  */
 public interface UiTranslationStateCallback {
 
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index 2c62647..41ff69d 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -32,6 +32,7 @@
 import android.database.ContentObserver;
 import android.os.Build;
 import android.os.Handler;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.PluralsMessageFormatter;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -230,7 +231,7 @@
 
         // Set the text
         String text = format.format(new Date(time));
-        setText(text);
+        maybeSetText(text);
 
         // Schedule the next update
         if (display == SHOW_TIME) {
@@ -258,7 +259,7 @@
         boolean past = (now >= mTimeMillis);
         String result;
         if (duration < MINUTE_IN_MILLIS) {
-            setText(mNowText);
+            maybeSetText(mNowText);
             mUpdateTimeMillis = mTimeMillis + MINUTE_IN_MILLIS + 1;
             return;
         } else if (duration < HOUR_IN_MILLIS) {
@@ -308,7 +309,19 @@
                 mUpdateTimeMillis = mTimeMillis - millisIncrease * count + 1;
             }
         }
-        setText(result);
+        maybeSetText(result);
+    }
+
+    /**
+     * Sets text only if the text has actually changed. This prevents needles relayouts of this
+     * view when set to wrap_content.
+     */
+    private void maybeSetText(String text) {
+        if (TextUtils.equals(getText(), text)) {
+            return;
+        }
+
+        setText(text);
     }
 
     /**
diff --git a/core/java/android/window/ITaskFragmentOrganizer.aidl b/core/java/android/window/ITaskFragmentOrganizer.aidl
index cdfa206..8dfda7d 100644
--- a/core/java/android/window/ITaskFragmentOrganizer.aidl
+++ b/core/java/android/window/ITaskFragmentOrganizer.aidl
@@ -16,6 +16,7 @@
 
 package android.window;
 
+import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -48,4 +49,20 @@
      *                          {@link TaskFragmentOrganizer#putExceptionInBundle}.
      */
     void onTaskFragmentError(in IBinder errorCallbackToken, in Bundle exceptionBundle);
+
+    /**
+     * Called when an Activity is reparented to the Task with organized TaskFragment. For example,
+     * when an Activity enters and then exits Picture-in-picture, it will be reparented back to its
+     * orginial Task. In this case, we need to notify the organizer so that it can check if the
+     * Activity matches any split rule.
+     *
+     * @param taskId            The Task that the activity is reparented to.
+     * @param activityIntent    The intent that the activity is original launched with.
+     * @param activityToken     If the activity belongs to the same process as the organizer, this
+     *                          will be the actual activity token; if the activity belongs to a
+     *                          different process, the server will generate a temporary token that
+     *                          the organizer can use to reparent the activity through
+     *                          {@link WindowContainerTransaction} if needed.
+     */
+    void onActivityReparentToTask(int taskId, in Intent activityIntent, in IBinder activityToken);
 }
diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl
index 172456e4..e6bb1f6 100644
--- a/core/java/android/window/ITaskOrganizerController.aidl
+++ b/core/java/android/window/ITaskOrganizerController.aidl
@@ -69,4 +69,14 @@
 
     /** Updates a state of camera compat control for stretched issues in the viewfinder. */
     void updateCameraCompatControlState(in WindowContainerToken task, int state);
+
+    /**
+     * Controls whether ignore orientation request logic in {@link
+     * com.android.server.wm.DisplayArea} is disabled at runtime.
+     *
+     * @param isDisabled when {@code true}, the system always ignores the value of {@link
+     *                   com.android.server.wm.DisplayArea#getIgnoreOrientationRequest} and app
+     *                   requested orientation is respected.
+     */
+     void setIsIgnoreOrientationRequestDisabled(boolean isDisabled);
 }
diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java
index 1d1deac..2ef49c3 100644
--- a/core/java/android/window/TaskFragmentOrganizer.java
+++ b/core/java/android/window/TaskFragmentOrganizer.java
@@ -19,6 +19,7 @@
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
 import android.annotation.TestApi;
+import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -154,6 +155,24 @@
     public void onTaskFragmentError(
             @NonNull IBinder errorCallbackToken, @NonNull Throwable exception) {}
 
+    /**
+     * Called when an Activity is reparented to the Task with organized TaskFragment. For example,
+     * when an Activity enters and then exits Picture-in-picture, it will be reparented back to its
+     * orginial Task. In this case, we need to notify the organizer so that it can check if the
+     * Activity matches any split rule.
+     *
+     * @param taskId            The Task that the activity is reparented to.
+     * @param activityIntent    The intent that the activity is original launched with.
+     * @param activityToken     If the activity belongs to the same process as the organizer, this
+     *                          will be the actual activity token; if the activity belongs to a
+     *                          different process, the server will generate a temporary token that
+     *                          the organizer can use to reparent the activity through
+     *                          {@link WindowContainerTransaction} if needed.
+     * @hide
+     */
+    public void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent,
+            @NonNull IBinder activityToken) {}
+
     @Override
     public void applyTransaction(@NonNull WindowContainerTransaction t) {
         t.setTaskFragmentOrganizer(mInterface);
@@ -203,6 +222,14 @@
                     errorCallbackToken,
                     (Throwable) exceptionBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION)));
         }
+
+        @Override
+        public void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent,
+                @NonNull IBinder activityToken) {
+            mExecutor.execute(
+                    () -> TaskFragmentOrganizer.this.onActivityReparentToTask(
+                            taskId, activityIntent, activityToken));
+        }
     };
 
     private final TaskFragmentOrganizerToken mToken = new TaskFragmentOrganizerToken(mInterface);
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index 8d88f80..bffd4e4 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -253,6 +253,24 @@
     }
 
     /**
+     * Controls whether ignore orientation request logic in {@link
+     * com.android.server.wm.DisplayArea} is disabled at runtime.
+     *
+     * @param isDisabled when {@code true}, the system always ignores the value of {@link
+     *                   com.android.server.wm.DisplayArea#getIgnoreOrientationRequest} and app
+     *                   requested orientation is respected.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
+    public void setIsIgnoreOrientationRequestDisabled(boolean isDisabled) {
+        try {
+            mTaskOrganizerController.setIsIgnoreOrientationRequestDisabled(isDisabled);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Gets the executor to run callbacks on.
      * @hide
      */
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 79dac19..7dc039d 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -650,6 +650,26 @@
     }
 
     /**
+     * Requests focus on the top running Activity in the given TaskFragment. This will only take
+     * effect if there is no focus, or if the current focus is in the same Task as the requested
+     * TaskFragment.
+     * @param fragmentToken client assigned unique token to create TaskFragment with specified in
+     *                      {@link TaskFragmentCreationParams#getFragmentToken()}.
+     * @hide
+     */
+    @NonNull
+    public WindowContainerTransaction requestFocusOnTaskFragment(@NonNull IBinder fragmentToken) {
+        final HierarchyOp hierarchyOp =
+                new HierarchyOp.Builder(
+                        HierarchyOp.HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT)
+                        .setContainer(fragmentToken)
+                        .build();
+        mHierarchyOps.add(hierarchyOp);
+        return this;
+
+    }
+
+    /**
      * When this {@link WindowContainerTransaction} failed to finish on the server side, it will
      * trigger callback with this {@param errorCallbackToken}.
      * @param errorCallbackToken    client provided token that will be passed back as parameter in
@@ -1057,6 +1077,7 @@
         public static final int HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER = 15;
         public static final int HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER = 16;
         public static final int HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER = 17;
+        public static final int HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT = 18;
 
         // The following key(s) are for use with mLaunchOptions:
         // When launching a task (eg. from recents), this is the taskId to be launched.
@@ -1368,6 +1389,8 @@
                 case HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER:
                     return "{removeLocalInsetsProvider: container=" + mContainer
                             + " insetsType=" + Arrays.toString(mInsetsTypes) + "}";
+                case HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT:
+                    return "{requestFocusOnTaskFragment: container=" + mContainer + "}";
                 default:
                     return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent
                             + " mToTop=" + mToTop
diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java
index b0be0df..7db4243 100644
--- a/core/java/android/window/WindowTokenClient.java
+++ b/core/java/android/window/WindowTokenClient.java
@@ -19,8 +19,8 @@
 import static android.window.ConfigurationHelper.isDifferentDisplay;
 import static android.window.ConfigurationHelper.shouldUpdateResources;
 
+import android.annotation.AnyThread;
 import android.annotation.BinderThread;
-import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.IWindowToken;
@@ -40,6 +40,7 @@
 import android.view.WindowManager.LayoutParams.WindowType;
 import android.view.WindowManagerGlobal;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.lang.ref.WeakReference;
@@ -68,6 +69,7 @@
 
     private IWindowManager mWms;
 
+    @GuardedBy("itself")
     private final Configuration mConfiguration = new Configuration();
 
     private boolean mShouldDumpConfigForIme;
@@ -111,8 +113,7 @@
             if (configuration == null) {
                 return false;
             }
-            mHandler.runWithScissors(() -> onConfigurationChanged(configuration, displayId,
-                    false /* shouldReportConfigChange */), 0 /* timeout */);
+            onConfigurationChanged(configuration, displayId, false /* shouldReportConfigChange */);
             mAttachToWindowContainer = true;
             return true;
         } catch (RemoteException e) {
@@ -137,8 +138,7 @@
             if (configuration == null) {
                 return false;
             }
-            mHandler.runWithScissors(() -> onConfigurationChanged(configuration, displayId,
-                    false /* shouldReportConfigChange */), 0 /* timeout */);
+            onConfigurationChanged(configuration, displayId, false /* shouldReportConfigChange */);
             mAttachToWindowContainer = true;
             return true;
         } catch (RemoteException e) {
@@ -199,8 +199,19 @@
      *
      * Similar to {@link #onConfigurationChanged(Configuration, int)}, but adds a flag to control
      * whether to dispatch configuration update or not.
+     * <p>
+     * Note that this method must be executed on the main thread if
+     * {@code shouldReportConfigChange} is {@code true}, which is usually from
+     * {@link IWindowToken#onConfigurationChanged(Configuration, int)}
+     * directly, while this method could be run on any thread if it is used to initialize
+     * Context's {@code Configuration} via {@link #attachToDisplayArea(int, int, Bundle)}
+     * or {@link #attachToDisplayContent(int)}.
+     *
+     * @param shouldReportConfigChange {@code true} to indicate that the {@code Configuration}
+     *                                 should be dispatched to listeners.
+     *
      */
-    @MainThread
+    @AnyThread
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     public void onConfigurationChanged(Configuration newConfig, int newDisplayId,
             boolean shouldReportConfigChange) {
@@ -208,18 +219,29 @@
         if (context == null) {
             return;
         }
-        final boolean displayChanged = isDifferentDisplay(context.getDisplayId(), newDisplayId);
-        final boolean shouldUpdateResources = shouldUpdateResources(this, mConfiguration,
-                newConfig, newConfig /* overrideConfig */, displayChanged,
-                null /* configChanged */);
+        final boolean displayChanged;
+        final boolean shouldUpdateResources;
+        final int diff;
+        final Configuration currentConfig;
+
+        synchronized (mConfiguration) {
+            displayChanged = isDifferentDisplay(context.getDisplayId(), newDisplayId);
+            shouldUpdateResources = shouldUpdateResources(this, mConfiguration,
+                    newConfig, newConfig /* overrideConfig */, displayChanged,
+                    null /* configChanged */);
+            diff = mConfiguration.diffPublicOnly(newConfig);
+            currentConfig = mShouldDumpConfigForIme ? new Configuration(mConfiguration) : null;
+            if (shouldUpdateResources) {
+                mConfiguration.setTo(newConfig);
+            }
+        }
 
         if (!shouldUpdateResources && mShouldDumpConfigForIme) {
             Log.d(TAG, "Configuration not dispatch to IME because configuration is up"
                     + " to date. Current config=" + context.getResources().getConfiguration()
-                    + ", reported config=" + mConfiguration
+                    + ", reported config=" + currentConfig
                     + ", updated config=" + newConfig);
         }
-
         if (shouldUpdateResources) {
             // TODO(ag/9789103): update resource manager logic to track non-activity tokens
             mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId);
@@ -229,7 +251,7 @@
                 windowContext.dispatchConfigurationChanged(newConfig);
             }
 
-            final int diff = mConfiguration.diffPublicOnly(newConfig);
+
             if (shouldReportConfigChange && diff != 0
                     && context instanceof WindowProviderService) {
                 final WindowProviderService windowProviderService = (WindowProviderService) context;
@@ -244,11 +266,10 @@
                     Log.d(TAG, "Configuration not dispatch to IME because configuration has no "
                             + " public difference with updated config. "
                             + " Current config=" + context.getResources().getConfiguration()
-                            + ", reported config=" + mConfiguration
+                            + ", reported config=" + currentConfig
                             + ", updated config=" + newConfig);
                 }
             }
-            mConfiguration.setTo(newConfig);
         }
         if (displayChanged) {
             context.updateDisplay(newDisplayId);
diff --git a/core/java/com/android/internal/app/AbstractResolverComparator.java b/core/java/com/android/internal/app/AbstractResolverComparator.java
index 42fc7bd..9759540 100644
--- a/core/java/com/android/internal/app/AbstractResolverComparator.java
+++ b/core/java/com/android/internal/app/AbstractResolverComparator.java
@@ -228,12 +228,6 @@
      */
     abstract float getScore(ComponentName name);
 
-    /**
-     * Returns the list of top K component names which have highest
-     * {@link #getScore(ComponentName)}
-     */
-    abstract List<ComponentName> getTopComponentNames(int topK);
-
     /** Handles result message sent to mHandler. */
     abstract void handleResultMessage(Message message);
 
diff --git a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
index bc9eff0..b19ac2f 100644
--- a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
@@ -18,6 +18,7 @@
 
 import static android.app.prediction.AppTargetEvent.ACTION_LAUNCH;
 
+import android.annotation.Nullable;
 import android.app.prediction.AppPredictor;
 import android.app.prediction.AppTarget;
 import android.app.prediction.AppTargetEvent;
@@ -33,12 +34,11 @@
 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.concurrent.Executors;
-import java.util.stream.Collectors;
 
 /**
  * Uses an {@link AppPredictor} to sort Resolver targets. If the AppPredictionService appears to be
@@ -58,7 +58,9 @@
     private final String mReferrerPackage;
     // If this is non-null (and this is not destroyed), it means APS is disabled and we should fall
     // back to using the ResolverRankerService.
+    // TODO: responsibility for this fallback behavior can live outside of the AppPrediction client.
     private ResolverRankerServiceResolverComparator mResolverRankerService;
+    private AppPredictionServiceComparatorModel mComparatorModel;
 
     AppPredictionServiceResolverComparator(
             Context context,
@@ -74,25 +76,12 @@
         mUser = user;
         mReferrerPackage = referrerPackage;
         setChooserActivityLogger(chooserActivityLogger);
+        mComparatorModel = buildUpdatedModel();
     }
 
     @Override
     int compare(ResolveInfo lhs, ResolveInfo rhs) {
-        if (mResolverRankerService != null) {
-            return mResolverRankerService.compare(lhs, rhs);
-        }
-        Integer lhsRank = mTargetRanks.get(new ComponentName(lhs.activityInfo.packageName,
-                lhs.activityInfo.name));
-        Integer rhsRank = mTargetRanks.get(new ComponentName(rhs.activityInfo.packageName,
-                rhs.activityInfo.name));
-        if (lhsRank == null && rhsRank == null) {
-            return 0;
-        } else if (lhsRank == null) {
-            return -1;
-        } else if (rhsRank == null) {
-            return 1;
-        }
-        return lhsRank - rhsRank;
+        return mComparatorModel.getComparator().compare(lhs, rhs);
     }
 
     @Override
@@ -121,6 +110,7 @@
                                         mContext, mIntent, mReferrerPackage,
                                         () -> mHandler.sendEmptyMessage(RANKER_SERVICE_RESULT),
                                         getChooserActivityLogger());
+                        mComparatorModel = buildUpdatedModel();
                         mResolverRankerService.compute(targets);
                     } else {
                         Log.i(TAG, "AppPredictionService response received");
@@ -163,6 +153,7 @@
             mTargetRanks.put(componentName, i);
             Log.i(TAG, "handleSortedAppTargets, sortedAppTargets #" + i + ": " + componentName);
         }
+        mComparatorModel = buildUpdatedModel();
     }
 
     private boolean checkAppTargetRankValid(List<AppTarget> sortedAppTargets) {
@@ -176,43 +167,12 @@
 
     @Override
     float getScore(ComponentName name) {
-        if (mResolverRankerService != null) {
-            return mResolverRankerService.getScore(name);
-        }
-        Integer rank = mTargetRanks.get(name);
-        if (rank == null) {
-            Log.w(TAG, "Score requested for unknown component. Did you call compute yet?");
-            return 0f;
-        }
-        int consecutiveSumOfRanks = (mTargetRanks.size() - 1) * (mTargetRanks.size()) / 2;
-        return 1.0f - (((float) rank) / consecutiveSumOfRanks);
-    }
-
-    @Override
-    List<ComponentName> getTopComponentNames(int topK) {
-        if (mResolverRankerService != null) {
-            return mResolverRankerService.getTopComponentNames(topK);
-        }
-        return mTargetRanks.entrySet().stream()
-                .sorted(Entry.comparingByValue())
-                .limit(topK)
-                .map(Entry::getKey)
-                .collect(Collectors.toList());
+        return mComparatorModel.getScore(name);
     }
 
     @Override
     void updateModel(ComponentName componentName) {
-        if (mResolverRankerService != null) {
-            mResolverRankerService.updateModel(componentName);
-            return;
-        }
-        mAppPredictor.notifyAppTargetEvent(
-                new AppTargetEvent.Builder(
-                    new AppTarget.Builder(
-                        new AppTargetId(componentName.toString()),
-                        componentName.getPackageName(), mUser)
-                        .setClassName(componentName.getClassName()).build(),
-                    ACTION_LAUNCH).build());
+        mComparatorModel.notifyOnTargetSelected(componentName);
     }
 
     @Override
@@ -220,6 +180,97 @@
         if (mResolverRankerService != null) {
             mResolverRankerService.destroy();
             mResolverRankerService = null;
+            mComparatorModel = buildUpdatedModel();
+        }
+    }
+
+    /**
+     * Re-construct an {@code AppPredictionServiceComparatorModel} to replace the current model
+     * instance (if any) using the up-to-date {@code AppPredictionServiceResolverComparator} ivar
+     * values.
+     *
+     * TODO: each time we replace the model instance, we're either updating the model to use
+     * adjusted data (which is appropriate), or we're providing a (late) value for one of our ivars
+     * that wasn't available the last time the model was updated. For those latter cases, we should
+     * just avoid creating the model altogether until we have all the prerequisites we'll need. Then
+     * we can probably simplify the logic in {@code AppPredictionServiceComparatorModel} since we
+     * won't need to handle edge cases when the model data isn't fully prepared.
+     * (In some cases, these kinds of "updates" might interleave -- e.g., we might have finished
+     * initializing the first time and now want to adjust some data, but still need to wait for
+     * changes to propagate to the other ivars before rebuilding the model.)
+     */
+    private AppPredictionServiceComparatorModel buildUpdatedModel() {
+        return new AppPredictionServiceComparatorModel(
+                mAppPredictor, mResolverRankerService, mUser, mTargetRanks);
+    }
+
+    // TODO: Finish separating behaviors of AbstractResolverComparator, then (probably) make this a
+    // standalone class once clients are written in terms of ResolverComparatorModel.
+    static class AppPredictionServiceComparatorModel implements ResolverComparatorModel {
+        private final AppPredictor mAppPredictor;
+        private final ResolverRankerServiceResolverComparator mResolverRankerService;
+        private final UserHandle mUser;
+        private final Map<ComponentName, Integer> mTargetRanks;  // Treat as immutable.
+
+        AppPredictionServiceComparatorModel(
+                AppPredictor appPredictor,
+                @Nullable ResolverRankerServiceResolverComparator resolverRankerService,
+                UserHandle user,
+                Map<ComponentName, Integer> targetRanks) {
+            mAppPredictor = appPredictor;
+            mResolverRankerService = resolverRankerService;
+            mUser = user;
+            mTargetRanks = targetRanks;
+        }
+
+        @Override
+        public Comparator<ResolveInfo> getComparator() {
+            return (lhs, rhs) -> {
+                if (mResolverRankerService != null) {
+                    return mResolverRankerService.compare(lhs, rhs);
+                }
+                Integer lhsRank = mTargetRanks.get(new ComponentName(lhs.activityInfo.packageName,
+                        lhs.activityInfo.name));
+                Integer rhsRank = mTargetRanks.get(new ComponentName(rhs.activityInfo.packageName,
+                        rhs.activityInfo.name));
+                if (lhsRank == null && rhsRank == null) {
+                    return 0;
+                } else if (lhsRank == null) {
+                    return -1;
+                } else if (rhsRank == null) {
+                    return 1;
+                }
+                return lhsRank - rhsRank;
+            };
+        }
+
+        @Override
+        public float getScore(ComponentName name) {
+            if (mResolverRankerService != null) {
+                return mResolverRankerService.getScore(name);
+            }
+            Integer rank = mTargetRanks.get(name);
+            if (rank == null) {
+                Log.w(TAG, "Score requested for unknown component. Did you call compute yet?");
+                return 0f;
+            }
+            int consecutiveSumOfRanks = (mTargetRanks.size() - 1) * (mTargetRanks.size()) / 2;
+            return 1.0f - (((float) rank) / consecutiveSumOfRanks);
+        }
+
+        @Override
+        public void notifyOnTargetSelected(ComponentName componentName) {
+            if (mResolverRankerService != null) {
+                mResolverRankerService.updateModel(componentName);
+                return;
+            }
+            mAppPredictor.notifyAppTargetEvent(
+                    new AppTargetEvent.Builder(
+                        new AppTarget.Builder(
+                            new AppTargetId(componentName.toString()),
+                            componentName.getPackageName(), mUser)
+                            .setClassName(componentName.getClassName()).build(),
+                        ACTION_LAUNCH).build());
         }
     }
 }
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 49ee91c..3cb39e7 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -194,9 +194,6 @@
     private static final String PLURALS_COUNT = "count";
     private static final String PLURALS_FILE_NAME = "file_name";
 
-    @VisibleForTesting
-    public static final int LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS = 250;
-
     private boolean mIsAppPredictorComponentAvailable;
     private Map<ChooserTarget, AppTarget> mDirectShareAppTargetCache;
     private Map<ChooserTarget, ShortcutInfo> mDirectShareShortcutInfoCache;
@@ -248,6 +245,13 @@
                     SystemUiDeviceConfigFlags.IS_NEARBY_SHARE_FIRST_TARGET_IN_RANKED_APP,
                     DEFAULT_IS_NEARBY_SHARE_FIRST_TARGET_IN_RANKED_APP);
 
+    private static final int DEFAULT_LIST_VIEW_UPDATE_DELAY_MS = 250;
+
+    @VisibleForTesting
+    int mListViewUpdateDelayMs = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
+            SystemUiDeviceConfigFlags.SHARESHEET_LIST_VIEW_UPDATE_DELAY,
+            DEFAULT_LIST_VIEW_UPDATE_DELAY_MS);
+
     private Bundle mReplacementExtras;
     private IntentSender mChosenComponentSender;
     private IntentSender mRefinementIntentSender;
@@ -2624,7 +2628,7 @@
         Message msg = Message.obtain();
         msg.what = ChooserHandler.LIST_VIEW_UPDATE_MESSAGE;
         msg.obj = userHandle;
-        mChooserHandler.sendMessageDelayed(msg, LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        mChooserHandler.sendMessageDelayed(msg, mListViewUpdateDelayMs);
     }
 
     @Override
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 52d54cd..681693b 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -284,4 +284,9 @@
      * Stops to listen the status of visible activity.
      */
     void stopListeningVisibleActivityChanged(in IBinder token);
+
+    /**
+     * Notifies when the session window is shown or hidden.
+     */
+    void setSessionWindowVisible(in IBinder token, boolean visible);
 }
diff --git a/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl b/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl
index bc757e2..6e40988 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl
@@ -30,6 +30,11 @@
     void onVoiceSessionHidden();
 
     /**
+     * Called when a voice session window is shown/hidden.
+     */
+    void onVoiceSessionWindowVisibilityChanged(boolean visible);
+
+    /**
      * Called when UI hints were received.
      */
     void onSetUiHints(in Bundle args);
diff --git a/core/java/com/android/internal/app/LocalePickerWithRegion.java b/core/java/com/android/internal/app/LocalePickerWithRegion.java
index 314b0a0..a06ba9b 100644
--- a/core/java/com/android/internal/app/LocalePickerWithRegion.java
+++ b/core/java/com/android/internal/app/LocalePickerWithRegion.java
@@ -247,6 +247,7 @@
         // In order to make the list view work with CollapsingToolbarLayout,
         // we have to enable the nested scrolling feature of the list view.
         getListView().setNestedScrollingEnabled(true);
+        getListView().setDivider(null);
     }
 
     @Override
diff --git a/core/java/com/android/internal/app/ResolverComparatorModel.java b/core/java/com/android/internal/app/ResolverComparatorModel.java
new file mode 100644
index 0000000..3e8f64b
--- /dev/null
+++ b/core/java/com/android/internal/app/ResolverComparatorModel.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.content.ComponentName;
+import android.content.pm.ResolveInfo;
+
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * A ranking model for resolver targets, providing ordering and (optionally) numerical scoring.
+ *
+ * As required by the {@link Comparator} contract, objects returned by {@code getComparator()} must
+ * apply a total ordering on its inputs consistent across all calls to {@code Comparator#compare()}.
+ * Other query methods and ranking feedback should refer to that same ordering, so implementors are
+ * generally advised to "lock in" an immutable snapshot of their model data when this object is
+ * initialized (preferring to replace the entire {@code ResolverComparatorModel} instance if the
+ * backing data needs to be updated in the future).
+ */
+interface ResolverComparatorModel {
+    /**
+     * Get a {@code Comparator} that can be used to sort {@code ResolveInfo} targets according to
+     * the model ranking.
+     */
+    Comparator<ResolveInfo> getComparator();
+
+    /**
+     * Get the numerical score, if any, that the model assigns to the component with the specified
+     * {@code name}. Scores range from zero to one, with one representing the highest possible
+     * likelihood that the user will select that component as the target. Implementations that don't
+     * assign numerical scores are <em>recommended</em> to return a value of 0 for all components.
+     */
+    float getScore(ComponentName name);
+
+    /**
+     * Notify the model that the user selected a target. (Models may log this information, use it as
+     * a feedback signal for their ranking, etc.) Because the data in this
+     * {@code ResolverComparatorModel} instance is immutable, clients will need to get an up-to-date
+     * instance in order to see any changes in the ranking that might result from this feedback.
+     */
+    void notifyOnTargetSelected(ComponentName componentName);
+}
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index ac9b2d8..0a07e0a 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -155,14 +155,6 @@
         return mResolverListController.getScore(componentName);
     }
 
-    /**
-     * Returns the list of top K component names which have highest
-     * {@link #getScore(DisplayResolveInfo)}
-     */
-    public List<ComponentName> getTopComponentNames(int topK) {
-        return mResolverListController.getTopComponentNames(topK);
-    }
-
     public void updateModel(ComponentName componentName) {
         mResolverListController.updateModel(componentName);
     }
@@ -177,107 +169,212 @@
     }
 
     /**
-     * Rebuild the list of resolvers. In some cases some parts will need some asynchronous work
-     * to complete.
+     * Rebuild the list of resolvers. When rebuilding is complete, queue the {@code onPostListReady}
+     * callback on the main handler with {@code rebuildCompleted} true.
      *
-     * The {@code doPostProcessing } parameter is used to specify whether to update the UI and
-     * load additional targets (e.g. direct share) after the list has been rebuilt. This is used
-     * in the case where we want to load the inactive profile's resolved apps to know the
+     * In some cases some parts will need some asynchronous work to complete. Then this will first
+     * immediately queue {@code onPostListReady} (on the main handler) with {@code rebuildCompleted}
+     * false; only when the asynchronous work completes will this then go on to queue another
+     * {@code onPostListReady} callback with {@code rebuildCompleted} true.
+     *
+     * The {@code doPostProcessing} parameter is used to specify whether to update the UI and
+     * load additional targets (e.g. direct share) after the list has been rebuilt. We may choose
+     * to skip that step if we're only loading the inactive profile's resolved apps to know the
      * number of targets.
      *
-     * @return Whether or not the list building is completed.
+     * @return Whether the list building was completed synchronously. If not, we'll queue the
+     * {@code onPostListReady} callback first with {@code rebuildCompleted} false, and then again
+     * with {@code rebuildCompleted} true at the end of some newly-launched asynchronous work.
+     * Otherwise the callback is only queued once, with {@code rebuildCompleted} true.
      */
     protected boolean rebuildList(boolean doPostProcessing) {
-        List<ResolvedComponentInfo> currentResolveList = null;
-        // Clear the value of mOtherProfile from previous call.
-        mOtherProfile = null;
-        mLastChosen = null;
-        mLastChosenPosition = -1;
         mDisplayList.clear();
         mIsTabLoaded = false;
+        mLastChosenPosition = -1;
 
-        if (mBaseResolveList != null) {
-            currentResolveList = mUnfilteredResolveList = new ArrayList<>();
-            mResolverListController.addResolveListDedupe(currentResolveList,
-                    mResolverListCommunicator.getTargetIntent(),
-                    mBaseResolveList);
-        } else {
-            currentResolveList = mUnfilteredResolveList =
-                    mResolverListController.getResolversForIntent(
-                            /* shouldGetResolvedFilter= */ true,
-                            mResolverListCommunicator.shouldGetActivityMetadata(),
-                            mIntents);
-            if (currentResolveList == null) {
-                processSortedList(currentResolveList, doPostProcessing);
-                return true;
-            }
-            List<ResolvedComponentInfo> originalList =
-                    mResolverListController.filterIneligibleActivities(currentResolveList,
-                            true);
-            if (originalList != null) {
-                mUnfilteredResolveList = originalList;
-            }
-        }
+        List<ResolvedComponentInfo> currentResolveList = getInitialRebuiltResolveList();
+
+        /* TODO: this seems like unnecessary extra complexity; why do we need to do this "primary"
+         * (i.e. "eligibility") filtering before evaluating the "other profile" special-treatment,
+         * but the "secondary" (i.e. "priority") filtering after? Are there in fact cases where the
+         * eligibility conditions will filter out a result that would've otherwise gotten the "other
+         * profile" treatment? Or, are there cases where the priority conditions *would* filter out
+         * a result, but we *want* that result to get the "other profile" treatment, so we only
+         * filter *after* evaluating the special-treatment conditions? If the answer to either is
+         * "no," then the filtering steps can be consolidated. (And that also makes the "unfiltered
+         * list" bookkeeping a little cleaner.)
+         */
+        mUnfilteredResolveList = performPrimaryResolveListFiltering(currentResolveList);
 
         // So far we only support a single other profile at a time.
         // The first one we see gets special treatment.
-        for (ResolvedComponentInfo info : currentResolveList) {
-            ResolveInfo resolveInfo = info.getResolveInfoAt(0);
-            if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) {
-                Intent pOrigIntent = mResolverListCommunicator.getReplacementIntent(
-                        resolveInfo.activityInfo,
-                        info.getIntentAt(0));
-                Intent replacementIntent = mResolverListCommunicator.getReplacementIntent(
-                        resolveInfo.activityInfo,
-                        mResolverListCommunicator.getTargetIntent());
-                mOtherProfile = new DisplayResolveInfo(info.getIntentAt(0),
-                        resolveInfo,
-                        resolveInfo.loadLabel(mPm),
-                        resolveInfo.loadLabel(mPm),
-                        pOrigIntent != null ? pOrigIntent : replacementIntent,
-                        makePresentationGetter(resolveInfo));
-                currentResolveList.remove(info);
-                break;
-            }
+        ResolvedComponentInfo otherProfileInfo =
+                getFirstNonCurrentUserResolvedComponentInfo(currentResolveList);
+        updateOtherProfileTreatment(otherProfileInfo);
+        if (otherProfileInfo != null) {
+            currentResolveList.remove(otherProfileInfo);
+            /* TODO: the previous line removed the "other profile info" item from
+             * mUnfilteredResolveList *ONLY IF* that variable is an alias for the same List instance
+             * as currentResolveList (i.e., if no items were filtered out as the result of the
+             * earlier "primary" filtering). It seems wrong for our behavior to depend on that.
+             * Should we:
+             *  A. replicate the above removal to mUnfilteredResolveList (which is idempotent, so we
+             *     don't even have to check whether they're aliases); or
+             *  B. break the alias relationship by copying currentResolveList to a new
+             *  mUnfilteredResolveList instance if necessary before removing otherProfileInfo?
+             * In other words: do we *want* otherProfileInfo in the "unfiltered" results? Either
+             * way, we'll need one of the changes suggested above.
+             */
         }
 
-        if (mOtherProfile == null) {
+        // If no results have yet been filtered, mUnfilteredResolveList is an alias for the same
+        // List instance as currentResolveList. Then we need to make a copy to store as the
+        // mUnfilteredResolveList if we go on to filter any more items. Otherwise we've already
+        // copied the original unfiltered items to a separate List instance and can now filter
+        // the remainder in-place without any further bookkeeping.
+        boolean needsCopyOfUnfiltered = (mUnfilteredResolveList == currentResolveList);
+        List<ResolvedComponentInfo> originalList = performSecondaryResolveListFiltering(
+                currentResolveList, needsCopyOfUnfiltered);
+        if (originalList != null) {
+            // Only need the originalList value if there was a modification (otherwise it's null
+            // and shouldn't overwrite mUnfilteredResolveList).
+            mUnfilteredResolveList = originalList;
+        }
+
+
+        return finishRebuildingListWithFilteredResults(currentResolveList, doPostProcessing);
+    }
+
+    /**
+     * Get the full (unfiltered) set of {@code ResolvedComponentInfo} records for all resolvers
+     * to be considered in a newly-rebuilt list. This list will be filtered and ranked before the
+     * rebuild is complete.
+     */
+    List<ResolvedComponentInfo> getInitialRebuiltResolveList() {
+        if (mBaseResolveList != null) {
+            List<ResolvedComponentInfo> currentResolveList = new ArrayList<>();
+            mResolverListController.addResolveListDedupe(currentResolveList,
+                    mResolverListCommunicator.getTargetIntent(),
+                    mBaseResolveList);
+            return currentResolveList;
+        } else {
+            return mResolverListController.getResolversForIntent(
+                            /* shouldGetResolvedFilter= */ true,
+                            mResolverListCommunicator.shouldGetActivityMetadata(),
+                            mIntents);
+        }
+    }
+
+    /**
+     * Remove ineligible activities from {@code currentResolveList} (if non-null), in-place. More
+     * broadly, filtering logic should apply in the "primary" stage if it should preclude items from
+     * receiving the "other profile" special-treatment described in {@code rebuildList()}.
+     *
+     * @return A copy of the original {@code currentResolveList}, if any items were removed, or a
+     * (possibly null) reference to the original list otherwise. (That is, this always returns a
+     * list of all the unfiltered items, but if no items were filtered, it's just an alias for the
+     * same list that was passed in).
+     */
+    @Nullable
+    List<ResolvedComponentInfo> performPrimaryResolveListFiltering(
+            @Nullable List<ResolvedComponentInfo> currentResolveList) {
+        /* TODO: mBaseResolveList appears to be(?) some kind of configured mode. Why is it not
+         * subject to filterIneligibleActivities, even though all the other logic still applies
+         * (including "secondary" filtering)? (This also relates to the earlier question; do we
+         * believe there's an item that would be eligible for "other profile" special treatment,
+         * except we want to filter it out as ineligible... but only if we're not in
+         * "mBaseResolveList mode"? */
+        if ((mBaseResolveList != null) || (currentResolveList == null)) {
+            return currentResolveList;
+        }
+
+        List<ResolvedComponentInfo> originalList =
+                mResolverListController.filterIneligibleActivities(currentResolveList, true);
+        return (originalList == null) ? currentResolveList : originalList;
+    }
+
+    /**
+     * Remove low-priority activities from {@code currentResolveList} (if non-null), in place. More
+     * broadly, filtering logic should apply in the "secondary" stage to prevent items from
+     * appearing in the rebuilt-list results, while still considering those items for the "other
+     * profile" special-treatment described in {@code rebuildList()}.
+     *
+     * @return the same (possibly null) List reference as {@code currentResolveList} if the list is
+     * unmodified as a result of filtering; or, if some item(s) were removed, then either a copy of
+     * the original {@code currentResolveList} (if {@code returnCopyOfOriginalListIfModified} is
+     * true), or null (otherwise).
+     */
+    @Nullable
+    List<ResolvedComponentInfo> performSecondaryResolveListFiltering(
+            @Nullable List<ResolvedComponentInfo> currentResolveList,
+            boolean returnCopyOfOriginalListIfModified) {
+        if ((currentResolveList == null) || currentResolveList.isEmpty()) {
+            return currentResolveList;
+        }
+        return mResolverListController.filterLowPriority(
+                currentResolveList, returnCopyOfOriginalListIfModified);
+    }
+
+    /**
+     * Update the special "other profile" UI treatment based on the components resolved for a
+     * newly-built list.
+     *
+     * @param otherProfileInfo the first {@code ResolvedComponentInfo} specifying a
+     * {@code targetUserId} other than {@code USER_CURRENT}, or null if no such component info was
+     * found in the process of rebuilding the list (or if any such candidates were already removed
+     * due to "primary filtering").
+     */
+    void updateOtherProfileTreatment(@Nullable ResolvedComponentInfo otherProfileInfo) {
+        mLastChosen = null;
+
+        if (otherProfileInfo != null) {
+            mOtherProfile = makeOtherProfileDisplayResolveInfo(
+                    mContext, otherProfileInfo, mPm, mResolverListCommunicator, mIconDpi);
+        } else {
+            mOtherProfile = null;
             try {
                 mLastChosen = mResolverListController.getLastChosen();
+                // TODO: does this also somehow need to update mLastChosenPosition? If so, maybe
+                // the current method should also take responsibility for re-initializing
+                // mLastChosenPosition, where it's currently done at the start of rebuildList()?
+                // (Why is this related to the presence of mOtherProfile in fhe first place?)
             } catch (RemoteException re) {
                 Log.d(TAG, "Error calling getLastChosenActivity\n" + re);
             }
         }
+    }
 
-        setPlaceholderCount(0);
-        int n;
-        if ((currentResolveList != null) && ((n = currentResolveList.size()) > 0)) {
-            // We only care about fixing the unfilteredList if the current resolve list and
-            // current resolve list are currently the same.
-            List<ResolvedComponentInfo> originalList =
-                    mResolverListController.filterLowPriority(currentResolveList,
-                            mUnfilteredResolveList == currentResolveList);
-            if (originalList != null) {
-                mUnfilteredResolveList = originalList;
-            }
-
-            if (currentResolveList.size() > 1) {
-                int placeholderCount = currentResolveList.size();
-                if (mResolverListCommunicator.useLayoutWithDefault()) {
-                    --placeholderCount;
-                }
-                setPlaceholderCount(placeholderCount);
-                createSortingTask(doPostProcessing).execute(currentResolveList);
-                postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ false);
-                return false;
-            } else {
-                processSortedList(currentResolveList, doPostProcessing);
-                return true;
-            }
-        } else {
-            processSortedList(currentResolveList, doPostProcessing);
+    /**
+     * Prepare the appropriate placeholders to eventually display the final set of resolved
+     * components in a newly-rebuilt list, and spawn an asynchronous sorting task if necessary.
+     * This eventually results in a {@code onPostListReady} callback with {@code rebuildCompleted}
+     * true; if any asynchronous work is required, that will first be preceded by a separate
+     * occurrence of the callback with {@code rebuildCompleted} false (once there are placeholders
+     * set up to represent the pending asynchronous results).
+     * @return Whether we were able to do all the work to prepare the list for display
+     * synchronously; if false, there will eventually be two separate {@code onPostListReady}
+     * callbacks, first with placeholders to represent pending asynchronous results, then later when
+     * the results are ready for presentation.
+     */
+    boolean finishRebuildingListWithFilteredResults(
+            @Nullable List<ResolvedComponentInfo> filteredResolveList, boolean doPostProcessing) {
+        if (filteredResolveList == null || filteredResolveList.size() < 2) {
+            // No asynchronous work to do.
+            setPlaceholderCount(0);
+            processSortedList(filteredResolveList, doPostProcessing);
             return true;
         }
+
+        int placeholderCount = filteredResolveList.size();
+        if (mResolverListCommunicator.useLayoutWithDefault()) {
+            --placeholderCount;
+        }
+        setPlaceholderCount(placeholderCount);
+
+        // Send an "incomplete" list-ready while the async task is running.
+        postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ false);
+        createSortingTask(doPostProcessing).execute(filteredResolveList);
+        return false;
     }
 
     AsyncTask<List<ResolvedComponentInfo>,
@@ -644,6 +741,59 @@
     }
 
     /**
+     * Find the first element in a list of {@code ResolvedComponentInfo} objects whose
+     * {@code ResolveInfo} specifies a {@code targetUserId} other than the current user.
+     * @return the first ResolvedComponentInfo targeting a non-current user, or null if there are
+     * none (or if the list itself is null).
+     */
+    private static ResolvedComponentInfo getFirstNonCurrentUserResolvedComponentInfo(
+            @Nullable List<ResolvedComponentInfo> resolveList) {
+        if (resolveList == null) {
+            return null;
+        }
+
+        for (ResolvedComponentInfo info : resolveList) {
+            ResolveInfo resolveInfo = info.getResolveInfoAt(0);
+            if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) {
+                return info;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Set up a {@code DisplayResolveInfo} to provide "special treatment" for the first "other"
+     * profile in the resolve list (i.e., the first non-current profile to appear as the target user
+     * of an element in the resolve list).
+     */
+    private static DisplayResolveInfo makeOtherProfileDisplayResolveInfo(
+            Context context,
+            ResolvedComponentInfo resolvedComponentInfo,
+            PackageManager pm,
+            ResolverListCommunicator resolverListCommunicator,
+            int iconDpi) {
+        ResolveInfo resolveInfo = resolvedComponentInfo.getResolveInfoAt(0);
+
+        Intent pOrigIntent = resolverListCommunicator.getReplacementIntent(
+                resolveInfo.activityInfo,
+                resolvedComponentInfo.getIntentAt(0));
+        Intent replacementIntent = resolverListCommunicator.getReplacementIntent(
+                resolveInfo.activityInfo,
+                resolverListCommunicator.getTargetIntent());
+
+        ResolveInfoPresentationGetter presentationGetter =
+                new ResolveInfoPresentationGetter(context, iconDpi, resolveInfo);
+
+        return new DisplayResolveInfo(
+                resolvedComponentInfo.getIntentAt(0),
+                resolveInfo,
+                resolveInfo.loadLabel(pm),
+                resolveInfo.loadLabel(pm),
+                pOrigIntent != null ? pOrigIntent : replacementIntent,
+                presentationGetter);
+    }
+
+    /**
      * Necessary methods to communicate between {@link ResolverListAdapter}
      * and {@link ResolverActivity}.
      */
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 9a95e64..2757363 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -393,14 +393,6 @@
         return mResolverComparator.getScore(componentName);
     }
 
-    /**
-     * Returns the list of top K component names which have highest
-     * {@link #getScore(DisplayResolveInfo)}
-     */
-    public List<ComponentName> getTopComponentNames(int topK) {
-        return mResolverComparator.getTopComponentNames(topK);
-    }
-
     public void updateModel(ComponentName componentName) {
         mResolverComparator.updateModel(componentName);
     }
diff --git a/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
index cb946c0..c5b21ac 100644
--- a/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
@@ -43,12 +43,12 @@
 
 import java.text.Collator;
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 /**
  * Ranks and compares packages based on usage stats and uses the {@link ResolverRankerService}.
@@ -83,6 +83,7 @@
     private ResolverRankerServiceConnection mConnection;
     private Context mContext;
     private CountDownLatch mConnectSignal;
+    private ResolverRankerServiceComparatorModel mComparatorModel;
 
     public ResolverRankerServiceResolverComparator(Context context, Intent intent,
                 String referrerPackage, AfterCompute afterCompute,
@@ -99,6 +100,8 @@
         mRankerServiceName = new ComponentName(mContext, this.getClass());
         setCallBack(afterCompute);
         setChooserActivityLogger(chooserActivityLogger);
+
+        mComparatorModel = buildUpdatedModel();
     }
 
     @Override
@@ -125,6 +128,7 @@
             }
             if (isUpdated) {
                 mRankerServiceName = mResolvedRankerName;
+                mComparatorModel = buildUpdatedModel();
             }
         } else {
             Log.e(TAG, "Sizes of sent and received ResolverTargets diff.");
@@ -218,83 +222,25 @@
             }
         }
         predictSelectProbabilities(mTargets);
+
+        mComparatorModel = buildUpdatedModel();
     }
 
     @Override
     public int compare(ResolveInfo lhs, ResolveInfo rhs) {
-        if (mStats != null) {
-            final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
-                    lhs.activityInfo.packageName, lhs.activityInfo.name));
-            final ResolverTarget rhsTarget = mTargetsDict.get(new ComponentName(
-                    rhs.activityInfo.packageName, rhs.activityInfo.name));
-
-            if (lhsTarget != null && rhsTarget != null) {
-                final int selectProbabilityDiff = Float.compare(
-                        rhsTarget.getSelectProbability(), lhsTarget.getSelectProbability());
-
-                if (selectProbabilityDiff != 0) {
-                    return selectProbabilityDiff > 0 ? 1 : -1;
-                }
-            }
-        }
-
-        CharSequence  sa = lhs.loadLabel(mPm);
-        if (sa == null) sa = lhs.activityInfo.name;
-        CharSequence  sb = rhs.loadLabel(mPm);
-        if (sb == null) sb = rhs.activityInfo.name;
-
-        return mCollator.compare(sa.toString().trim(), sb.toString().trim());
+        return mComparatorModel.getComparator().compare(lhs, rhs);
     }
 
     @Override
     public float getScore(ComponentName name) {
-        final ResolverTarget target = mTargetsDict.get(name);
-        if (target != null) {
-            return target.getSelectProbability();
-        }
-        return 0;
-    }
-
-    @Override
-    List<ComponentName> getTopComponentNames(int topK) {
-        return mTargetsDict.entrySet().stream()
-                .sorted((o1, o2) -> -Float.compare(getScore(o1.getKey()), getScore(o2.getKey())))
-                .limit(topK)
-                .map(Map.Entry::getKey)
-                .collect(Collectors.toList());
+        return mComparatorModel.getScore(name);
     }
 
     // update ranking model when the connection to it is valid.
     @Override
     public void updateModel(ComponentName componentName) {
         synchronized (mLock) {
-            if (mRanker != null) {
-                try {
-                    int selectedPos = new ArrayList<ComponentName>(mTargetsDict.keySet())
-                            .indexOf(componentName);
-                    if (selectedPos >= 0 && mTargets != null) {
-                        final float selectedProbability = getScore(componentName);
-                        int order = 0;
-                        for (ResolverTarget target : mTargets) {
-                            if (target.getSelectProbability() > selectedProbability) {
-                                order++;
-                            }
-                        }
-                        logMetrics(order);
-                        mRanker.train(mTargets, selectedPos);
-                    } else {
-                        if (DEBUG) {
-                            Log.d(TAG, "Selected a unknown component: " + componentName);
-                        }
-                    }
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Error in Train: " + e);
-                }
-            } else {
-                if (DEBUG) {
-                    Log.d(TAG, "Ranker is null; skip updateModel.");
-                }
-            }
+            mComparatorModel.notifyOnTargetSelected(componentName);
         }
     }
 
@@ -313,19 +259,6 @@
         }
     }
 
-    // records metrics for evaluation.
-    private void logMetrics(int selectedPos) {
-        if (mRankerServiceName != null) {
-            MetricsLogger metricsLogger = new MetricsLogger();
-            LogMaker log = new LogMaker(MetricsEvent.ACTION_TARGET_SELECTED);
-            log.setComponentName(mRankerServiceName);
-            int isCategoryUsed = (mAnnotations == null) ? 0 : 1;
-            log.addTaggedData(MetricsEvent.FIELD_IS_CATEGORY_USED, isCategoryUsed);
-            log.addTaggedData(MetricsEvent.FIELD_RANKED_POSITION, selectedPos);
-            metricsLogger.write(log);
-        }
-    }
-
     // connect to a ranking service.
     private void initRanker(Context context) {
         synchronized (mLock) {
@@ -426,6 +359,7 @@
             }
             synchronized (mLock) {
                 mRanker = IResolverRankerService.Stub.asInterface(service);
+                mComparatorModel = buildUpdatedModel();
                 mConnectSignal.countDown();
             }
         }
@@ -443,6 +377,7 @@
         public void destroy() {
             synchronized (mLock) {
                 mRanker = null;
+                mComparatorModel = buildUpdatedModel();
             }
         }
     }
@@ -453,6 +388,7 @@
         mTargetsDict.clear();
         mTargets = null;
         mRankerServiceName = new ComponentName(mContext, this.getClass());
+        mComparatorModel = buildUpdatedModel();
         mResolvedRankerName = null;
         initRanker(mContext);
     }
@@ -508,4 +444,155 @@
         }
         return false;
     }
+
+    /**
+     * Re-construct a {@code ResolverRankerServiceComparatorModel} to replace the current model
+     * instance (if any) using the up-to-date {@code ResolverRankerServiceResolverComparator} ivar
+     * values.
+     *
+     * TODO: each time we replace the model instance, we're either updating the model to use
+     * adjusted data (which is appropriate), or we're providing a (late) value for one of our ivars
+     * that wasn't available the last time the model was updated. For those latter cases, we should
+     * just avoid creating the model altogether until we have all the prerequisites we'll need. Then
+     * we can probably simplify the logic in {@code ResolverRankerServiceComparatorModel} since we
+     * won't need to handle edge cases when the model data isn't fully prepared.
+     * (In some cases, these kinds of "updates" might interleave -- e.g., we might have finished
+     * initializing the first time and now want to adjust some data, but still need to wait for
+     * changes to propagate to the other ivars before rebuilding the model.)
+     */
+    private ResolverRankerServiceComparatorModel buildUpdatedModel() {
+        // TODO: we don't currently guarantee that the underlying target list/map won't be mutated,
+        // so the ResolverComparatorModel may provide inconsistent results. We should make immutable
+        // copies of the data (waiting for any necessary remaining data before creating the model).
+        return new ResolverRankerServiceComparatorModel(
+                mStats,
+                mTargetsDict,
+                mTargets,
+                mCollator,
+                mRanker,
+                mRankerServiceName,
+                (mAnnotations != null),
+                mPm);
+    }
+
+    /**
+     * Implementation of a {@code ResolverComparatorModel} that provides the same ranking logic as
+     * the legacy {@code ResolverRankerServiceResolverComparator}, as a refactoring step toward
+     * removing the complex legacy API.
+     */
+    static class ResolverRankerServiceComparatorModel implements ResolverComparatorModel {
+        private final Map<String, UsageStats> mStats;  // Treat as immutable.
+        private final Map<ComponentName, ResolverTarget> mTargetsDict;  // Treat as immutable.
+        private final List<ResolverTarget> mTargets;  // Treat as immutable.
+        private final Collator mCollator;
+        private final IResolverRankerService mRanker;
+        private final ComponentName mRankerServiceName;
+        private final boolean mAnnotationsUsed;
+        private final PackageManager mPm;
+
+        // TODO: it doesn't look like we should have to pass both targets and targetsDict, but it's
+        // not written in a way that makes it clear whether we can derive one from the other (at
+        // least in this constructor).
+        ResolverRankerServiceComparatorModel(
+                Map<String, UsageStats> stats,
+                Map<ComponentName, ResolverTarget> targetsDict,
+                List<ResolverTarget> targets,
+                Collator collator,
+                IResolverRankerService ranker,
+                ComponentName rankerServiceName,
+                boolean annotationsUsed,
+                PackageManager pm) {
+            mStats = stats;
+            mTargetsDict = targetsDict;
+            mTargets = targets;
+            mCollator = collator;
+            mRanker = ranker;
+            mRankerServiceName = rankerServiceName;
+            mAnnotationsUsed = annotationsUsed;
+            mPm = pm;
+        }
+
+        @Override
+        public Comparator<ResolveInfo> getComparator() {
+            // TODO: doCompute() doesn't seem to be concerned about null-checking mStats. Is that
+            // a bug there, or do we have a way of knowing it will be non-null under certain
+            // conditions?
+            return (lhs, rhs) -> {
+                if (mStats != null) {
+                    final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
+                            lhs.activityInfo.packageName, lhs.activityInfo.name));
+                    final ResolverTarget rhsTarget = mTargetsDict.get(new ComponentName(
+                            rhs.activityInfo.packageName, rhs.activityInfo.name));
+
+                    if (lhsTarget != null && rhsTarget != null) {
+                        final int selectProbabilityDiff = Float.compare(
+                                rhsTarget.getSelectProbability(), lhsTarget.getSelectProbability());
+
+                        if (selectProbabilityDiff != 0) {
+                            return selectProbabilityDiff > 0 ? 1 : -1;
+                        }
+                    }
+                }
+
+                CharSequence  sa = lhs.loadLabel(mPm);
+                if (sa == null) sa = lhs.activityInfo.name;
+                CharSequence  sb = rhs.loadLabel(mPm);
+                if (sb == null) sb = rhs.activityInfo.name;
+
+                return mCollator.compare(sa.toString().trim(), sb.toString().trim());
+            };
+        }
+
+        @Override
+        public float getScore(ComponentName name) {
+            final ResolverTarget target = mTargetsDict.get(name);
+            if (target != null) {
+                return target.getSelectProbability();
+            }
+            return 0;
+        }
+
+        @Override
+        public void notifyOnTargetSelected(ComponentName componentName) {
+            if (mRanker != null) {
+                try {
+                    int selectedPos = new ArrayList<ComponentName>(mTargetsDict.keySet())
+                            .indexOf(componentName);
+                    if (selectedPos >= 0 && mTargets != null) {
+                        final float selectedProbability = getScore(componentName);
+                        int order = 0;
+                        for (ResolverTarget target : mTargets) {
+                            if (target.getSelectProbability() > selectedProbability) {
+                                order++;
+                            }
+                        }
+                        logMetrics(order);
+                        mRanker.train(mTargets, selectedPos);
+                    } else {
+                        if (DEBUG) {
+                            Log.d(TAG, "Selected a unknown component: " + componentName);
+                        }
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error in Train: " + e);
+                }
+            } else {
+                if (DEBUG) {
+                    Log.d(TAG, "Ranker is null; skip updateModel.");
+                }
+            }
+        }
+
+        /** Records metrics for evaluation. */
+        private void logMetrics(int selectedPos) {
+            if (mRankerServiceName != null) {
+                MetricsLogger metricsLogger = new MetricsLogger();
+                LogMaker log = new LogMaker(MetricsEvent.ACTION_TARGET_SELECTED);
+                log.setComponentName(mRankerServiceName);
+                log.addTaggedData(MetricsEvent.FIELD_IS_CATEGORY_USED, mAnnotationsUsed);
+                log.addTaggedData(MetricsEvent.FIELD_RANKED_POSITION, selectedPos);
+                metricsLogger.write(log);
+            }
+        }
+    }
 }
diff --git a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
index 18fde47..5fe1111 100644
--- a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
+++ b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
@@ -27,7 +27,6 @@
 import android.widget.BaseAdapter;
 import android.widget.Filter;
 import android.widget.Filterable;
-import android.widget.FrameLayout;
 import android.widget.TextView;
 
 import com.android.internal.R;
@@ -222,6 +221,7 @@
                         convertView = mInflater.inflate(
                                 R.layout.app_language_picker_current_locale_item, parent, false);
                         title = convertView.findViewById(R.id.language_picker_item);
+                        addStateDescriptionIntoCurrentLocaleItem(convertView);
                     } else {
                         convertView = mInflater.inflate(
                                 R.layout.language_picker_item, parent, false);
@@ -234,6 +234,7 @@
                 if (!(convertView instanceof ViewGroup)) {
                     convertView = mInflater.inflate(
                             R.layout.app_language_picker_current_locale_item, parent, false);
+                    addStateDescriptionIntoCurrentLocaleItem(convertView);
                 }
                 updateTextView(
                         convertView, convertView.findViewById(R.id.language_picker_item), position);
@@ -369,4 +370,9 @@
                     : View.TEXT_DIRECTION_LTR);
         }
     }
+
+    private void addStateDescriptionIntoCurrentLocaleItem(View root) {
+        String description = root.getContext().getResources().getString(R.string.checked);
+        root.setStateDescription(description);
+    }
 }
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index c94438e..ffb3752 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -520,6 +520,13 @@
     public static final String USE_UNBUNDLED_SHARESHEET = "use_unbundled_sharesheet";
 
     /**
+     * (int) The delay (in ms) before refreshing the Sharesheet UI after a change to the share
+     * target data model. For more info see go/sharesheet-list-view-update-delay.
+     */
+    public static final String SHARESHEET_LIST_VIEW_UPDATE_DELAY =
+            "sharesheet_list_view_update_delay";
+
+    /**
      * (string) Name of the default QR code scanner activity. On the eligible devices this activity
      * is provided by GMS core.
      */
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index a60b310..563cf04 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -414,6 +414,12 @@
         final File parent = getFileForDocId(parentDocumentId);
         final MatrixCursor result = new DirectoryCursor(
                 resolveProjection(projection), parentDocumentId, parent);
+
+        if (!filter.test(parent)) {
+            Log.w(TAG, "No permission to access parentDocumentId: " + parentDocumentId);
+            return result;
+        }
+
         if (parent.isDirectory()) {
             for (File file : FileUtils.listFilesOrEmpty(parent)) {
                 if (filter.test(file)) {
diff --git a/core/java/com/android/internal/inputmethod/RemoteAccessibilityInputConnection.java b/core/java/com/android/internal/inputmethod/RemoteAccessibilityInputConnection.java
index b2ab819..0ee8ee7 100644
--- a/core/java/com/android/internal/inputmethod/RemoteAccessibilityInputConnection.java
+++ b/core/java/com/android/internal/inputmethod/RemoteAccessibilityInputConnection.java
@@ -115,14 +115,6 @@
     @AnyThread
     public SurroundingText getSurroundingText(
             @IntRange(from = 0) int beforeLength, @IntRange(from = 0) int afterLength, int flags) {
-        if (beforeLength < 0) {
-            throw new IllegalArgumentException("beforeLength cannot be negative but was "
-                + beforeLength);
-        }
-        if (afterLength < 0) {
-            throw new IllegalArgumentException("afterLength cannot be negative but was "
-                    + afterLength);
-        }
         if (mCancellationGroup.isCanceled()) {
             return null;
         }
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index 4f51a5b..825b486 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -36,7 +36,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseArray;
-import android.util.StatsLog;
 import android.view.Choreographer;
 import android.view.FrameMetrics;
 import android.view.SurfaceControl;
@@ -481,6 +480,8 @@
         int missedFramesCount = 0;
         int missedAppFramesCount = 0;
         int missedSfFramesCount = 0;
+        int maxSuccessiveMissedFramesCount = 0;
+        int successiveMissedFramesCount = 0;
 
         for (int i = 0; i < mJankInfos.size(); i++) {
             JankInfo info = mJankInfos.valueAt(i);
@@ -510,6 +511,11 @@
                 }
                 if (missedFrame) {
                     missedFramesCount++;
+                    successiveMissedFramesCount++;
+                } else {
+                    maxSuccessiveMissedFramesCount = Math.max(
+                            maxSuccessiveMissedFramesCount, successiveMissedFramesCount);
+                    successiveMissedFramesCount = 0;
                 }
                 // TODO (b/174755489): Early latch currently gets fired way too often, so we have
                 // to ignore it for now.
@@ -524,6 +530,8 @@
                 }
             }
         }
+        maxSuccessiveMissedFramesCount = Math.max(
+                maxSuccessiveMissedFramesCount, successiveMissedFramesCount);
 
         // Log the frame stats as counters to make them easily accessible in traces.
         Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#missedFrames",
@@ -536,6 +544,8 @@
                 totalFramesCount);
         Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#maxFrameTimeMillis",
                 (int) (maxFrameTimeNanos / NANOS_IN_MILLISECOND));
+        Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#maxSuccessiveMissedFrames",
+                maxSuccessiveMissedFramesCount);
 
         // Trigger perfetto if necessary.
         if (shouldTriggerPerfetto(missedFramesCount, (int) maxFrameTimeNanos)) {
@@ -549,7 +559,8 @@
                     missedFramesCount,
                     maxFrameTimeNanos, /* will be 0 if mSurfaceOnly == true */
                     missedSfFramesCount,
-                    missedAppFramesCount);
+                    missedAppFramesCount,
+                    maxSuccessiveMissedFramesCount);
         }
         if (DEBUG) {
             Log.i(TAG, "finish: CUJ=" + mSession.getName()
@@ -558,7 +569,8 @@
                     + " missedAppFrames=" + missedAppFramesCount
                     + " missedSfFrames=" + missedSfFramesCount
                     + " missedFrames=" + missedFramesCount
-                    + " maxFrameTimeMillis=" + maxFrameTimeNanos / NANOS_IN_MILLISECOND);
+                    + " maxFrameTimeMillis=" + maxFrameTimeNanos / NANOS_IN_MILLISECOND
+                    + " maxSuccessiveMissedFramesCount=" + maxSuccessiveMissedFramesCount);
         }
     }
 
@@ -694,8 +706,8 @@
 
     public static class StatsLogWrapper {
         public void write(int code,
-                int arg1, long arg2, long arg3, long arg4, long arg5, long arg6) {
-            FrameworkStatsLog.write(code, arg1, arg2, arg3, arg4, arg5, arg6);
+                int arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7) {
+            FrameworkStatsLog.write(code, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
         }
     }
 
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 6424989..1b52aa9 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -28,6 +28,7 @@
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_WIDGET;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_ALL_APPS;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_QUICK_SWITCH;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_LAUNCH_CAMERA;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PASSWORD_APPEAR;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PASSWORD_DISAPPEAR;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PATTERN_APPEAR;
@@ -189,7 +190,8 @@
     public static final int CUJ_SUW_LOADING_SCREEN_FOR_STATUS = 48;
     public static final int CUJ_SPLIT_SCREEN_ENTER = 49;
     public static final int CUJ_SPLIT_SCREEN_EXIT = 50;
-    public static final int CUJ_SPLIT_SCREEN_RESIZE = 51;
+    public static final int CUJ_LOCKSCREEN_LAUNCH_CAMERA = 51; // reserved.
+    public static final int CUJ_SPLIT_SCREEN_RESIZE = 52;
 
     private static final int NO_STATSD_LOGGING = -1;
 
@@ -249,6 +251,7 @@
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_SCREEN_FOR_STATUS,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_ENTER,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_EXIT,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_LAUNCH_CAMERA,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_RESIZE,
     };
 
@@ -321,6 +324,7 @@
             CUJ_SUW_LOADING_SCREEN_FOR_STATUS,
             CUJ_SPLIT_SCREEN_ENTER,
             CUJ_SPLIT_SCREEN_EXIT,
+            CUJ_LOCKSCREEN_LAUNCH_CAMERA,
             CUJ_SPLIT_SCREEN_RESIZE
     })
     @Retention(RetentionPolicy.SOURCE)
@@ -742,6 +746,8 @@
                 return "SPLIT_SCREEN_ENTER";
             case CUJ_SPLIT_SCREEN_EXIT:
                 return "SPLIT_SCREEN_EXIT";
+            case CUJ_LOCKSCREEN_LAUNCH_CAMERA:
+                return "CUJ_LOCKSCREEN_LAUNCH_CAMERA";
             case CUJ_SPLIT_SCREEN_RESIZE:
                 return "CUJ_SPLIT_SCREEN_RESIZE";
         }
diff --git a/core/java/com/android/internal/policy/KidsModeSettingsObserver.java b/core/java/com/android/internal/policy/ForceShowNavBarSettingsObserver.java
similarity index 68%
copy from core/java/com/android/internal/policy/KidsModeSettingsObserver.java
copy to core/java/com/android/internal/policy/ForceShowNavBarSettingsObserver.java
index 8a1d407..fc064ea 100644
--- a/core/java/com/android/internal/policy/KidsModeSettingsObserver.java
+++ b/core/java/com/android/internal/policy/ForceShowNavBarSettingsObserver.java
@@ -24,17 +24,15 @@
 import android.provider.Settings;
 
 /**
- * A ContentObserver for listening kids mode relative setting keys:
- *  - {@link Settings.Secure#NAVIGATION_MODE}
- *  - {@link Settings.Secure#NAV_BAR_KIDS_MODE}
+ * A ContentObserver for listening {@link Settings.Secure#NAV_BAR_FORCE_VISIBLE} setting key.
  *
  * @hide
  */
-public class KidsModeSettingsObserver extends ContentObserver {
+public class ForceShowNavBarSettingsObserver extends ContentObserver {
     private Context mContext;
     private Runnable mOnChangeRunnable;
 
-    public KidsModeSettingsObserver(Handler handler, Context context) {
+    public ForceShowNavBarSettingsObserver(Handler handler, Context context) {
         super(handler);
         mContext = context;
     }
@@ -49,10 +47,7 @@
     public void register() {
         final ContentResolver r = mContext.getContentResolver();
         r.registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.NAVIGATION_MODE),
-                false, this, UserHandle.USER_ALL);
-        r.registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE),
+                Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_FORCE_VISIBLE),
                 false, this, UserHandle.USER_ALL);
     }
 
@@ -71,13 +66,10 @@
     }
 
     /**
-     * Returns true only when it's in three button nav mode and the kid nav bar mode is enabled.
-     * Otherwise, return false.
+     * Returns true only when it's in orce show navigation bar mode. Otherwise, return false.
      */
     public boolean isEnabled() {
         return Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.NAVIGATION_MODE, 0, UserHandle.USER_CURRENT) == 0
-                && Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.NAV_BAR_KIDS_MODE, 0, UserHandle.USER_CURRENT) == 1;
+                Settings.Secure.NAV_BAR_FORCE_VISIBLE, 0, UserHandle.USER_CURRENT) == 1;
     }
 }
diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl
index b9eb997..d505c19 100644
--- a/core/java/com/android/internal/view/IInputMethodSession.aidl
+++ b/core/java/com/android/internal/view/IInputMethodSession.aidl
@@ -50,8 +50,6 @@
 
     void updateCursorAnchorInfo(in CursorAnchorInfo cursorAnchorInfo);
 
-    void notifyImeHidden();
-
     void removeImeSurface();
 
     void finishInput();
diff --git a/core/java/com/android/internal/view/ScrollCaptureViewSupport.java b/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
index 94a8ae5..f2c27a4 100644
--- a/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
+++ b/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
@@ -76,6 +76,7 @@
         ContentResolver contentResolver = context.getContentResolver();
         mPostScrollDelayMillis = Settings.Global.getLong(contentResolver,
                 SETTING_CAPTURE_DELAY, SETTING_CAPTURE_DELAY_DEFAULT);
+        Log.d(TAG, "screenshot.scroll_capture_delay = " + mPostScrollDelayMillis);
     }
 
     /** Based on ViewRootImpl#updateColorModeIfNeeded */
@@ -271,6 +272,13 @@
         Rect viewCaptureArea = new Rect(scrollResult.availableArea);
         viewCaptureArea.offset(0, -scrollResult.scrollDelta);
 
+        view.postOnAnimationDelayed(
+                () -> doCapture(scrollResult, view, viewCaptureArea, onComplete),
+                mPostScrollDelayMillis);
+    }
+
+    private void doCapture(ScrollResult scrollResult, V view, Rect viewCaptureArea,
+            Consumer<Rect> onComplete) {
         int result = mRenderer.renderView(view, viewCaptureArea);
         if (result == HardwareRenderer.SYNC_OK
                 || result == HardwareRenderer.SYNC_REDRAW_REQUESTED) {
diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp
index fc12e17..a8d7231 100644
--- a/core/jni/android_content_res_ApkAssets.cpp
+++ b/core/jni/android_content_res_ApkAssets.cpp
@@ -459,8 +459,12 @@
     return nullptr;
   }
 
-  auto overlayable_name_native = std::string(env->GetStringUTFChars(overlayable_name, NULL));
+  const char* overlayable_name_native = env->GetStringUTFChars(overlayable_name, nullptr);
+  if (overlayable_name_native == nullptr) {
+      return nullptr;
+  }
   auto actor = overlayable_map.find(overlayable_name_native);
+  env->ReleaseStringUTFChars(overlayable_name, overlayable_name_native);
   if (actor == overlayable_map.end()) {
     return nullptr;
   }
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index db33863d..c947fba 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -48,6 +48,7 @@
 
 #include <jni.h>
 #include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedUtfChars.h>
 
 using namespace android;
 using namespace img_utils;
@@ -1264,16 +1265,14 @@
 
     sp<NativeContext> nativeContext = new NativeContext(characteristics, results);
 
-    const char* captureTime = env->GetStringUTFChars(formattedCaptureTime, nullptr);
-
-    size_t len = strlen(captureTime) + 1;
-    if (len != NativeContext::DATETIME_COUNT) {
+    ScopedUtfChars captureTime(env, formattedCaptureTime);
+    if (captureTime.size() + 1 != NativeContext::DATETIME_COUNT) {
         jniThrowException(env, "java/lang/IllegalArgumentException",
                 "Formatted capture time string length is not required 20 characters");
         return;
     }
 
-    nativeContext->setCaptureTime(String8(captureTime));
+    nativeContext->setCaptureTime(String8(captureTime.c_str()));
 
     DngCreator_setNativeContext(env, thiz, nativeContext);
 }
diff --git a/core/jni/com_android_internal_os_LongArrayMultiStateCounter.cpp b/core/jni/com_android_internal_os_LongArrayMultiStateCounter.cpp
index 6e7ebda..0ebf2dd 100644
--- a/core/jni/com_android_internal_os_LongArrayMultiStateCounter.cpp
+++ b/core/jni/com_android_internal_os_LongArrayMultiStateCounter.cpp
@@ -111,17 +111,17 @@
                                  jint flags) {
     battery::LongArrayMultiStateCounter *counter =
             reinterpret_cast<battery::LongArrayMultiStateCounter *>(nativePtr);
-    AParcel *parcel = AParcel_fromJavaParcel(env, jParcel);
+    ndk::ScopedAParcel parcel(AParcel_fromJavaParcel(env, jParcel));
 
     uint16_t stateCount = counter->getStateCount();
-    THROW_ON_WRITE_ERROR(AParcel_writeInt32(parcel, stateCount));
+    THROW_ON_WRITE_ERROR(AParcel_writeInt32(parcel.get(), stateCount));
 
     // LongArrayMultiStateCounter has at least state 0
     const std::vector<uint64_t> &anyState = counter->getCount(0);
-    THROW_ON_WRITE_ERROR(AParcel_writeInt32(parcel, anyState.size()));
+    THROW_ON_WRITE_ERROR(AParcel_writeInt32(parcel.get(), anyState.size()));
 
     for (battery::state_t state = 0; state < stateCount; state++) {
-        THROW_ON_WRITE_ERROR(ndk::AParcel_writeVector(parcel, counter->getCount(state)));
+        THROW_ON_WRITE_ERROR(ndk::AParcel_writeVector(parcel.get(), counter->getCount(state)));
     }
 }
 
@@ -139,13 +139,13 @@
     }
 
 static jlong native_initFromParcel(JNIEnv *env, jclass theClass, jobject jParcel) {
-    AParcel *parcel = AParcel_fromJavaParcel(env, jParcel);
+    ndk::ScopedAParcel parcel(AParcel_fromJavaParcel(env, jParcel));
 
     int32_t stateCount;
-    THROW_ON_READ_ERROR(AParcel_readInt32(parcel, &stateCount));
+    THROW_ON_READ_ERROR(AParcel_readInt32(parcel.get(), &stateCount));
 
     int32_t arrayLength;
-    THROW_ON_READ_ERROR(AParcel_readInt32(parcel, &arrayLength));
+    THROW_ON_READ_ERROR(AParcel_readInt32(parcel.get(), &arrayLength));
 
     battery::LongArrayMultiStateCounter *counter =
             new battery::LongArrayMultiStateCounter(stateCount, std::vector<uint64_t>(arrayLength));
@@ -154,7 +154,7 @@
     value.reserve(arrayLength);
 
     for (battery::state_t state = 0; state < stateCount; state++) {
-        THROW_ON_READ_ERROR(ndk::AParcel_readVector(parcel, &value));
+        THROW_ON_READ_ERROR(ndk::AParcel_readVector(parcel.get(), &value));
         counter->setValue(state, value);
     }
 
diff --git a/core/jni/com_android_internal_os_LongMultiStateCounter.cpp b/core/jni/com_android_internal_os_LongMultiStateCounter.cpp
index 69c4f3d..8c69d27 100644
--- a/core/jni/com_android_internal_os_LongMultiStateCounter.cpp
+++ b/core/jni/com_android_internal_os_LongMultiStateCounter.cpp
@@ -120,13 +120,13 @@
 static void native_writeToParcel(JNIEnv *env, jobject self, jlong nativePtr, jobject jParcel,
                                  jint flags) {
     battery::LongMultiStateCounter *counter = asLongMultiStateCounter(nativePtr);
-    AParcel *parcel = AParcel_fromJavaParcel(env, jParcel);
+    ndk::ScopedAParcel parcel(AParcel_fromJavaParcel(env, jParcel));
 
     uint16_t stateCount = counter->getStateCount();
-    THROW_ON_WRITE_ERROR(AParcel_writeInt32(parcel, stateCount));
+    THROW_ON_WRITE_ERROR(AParcel_writeInt32(parcel.get(), stateCount));
 
     for (battery::state_t state = 0; state < stateCount; state++) {
-        THROW_ON_WRITE_ERROR(AParcel_writeInt64(parcel, counter->getCount(state)));
+        THROW_ON_WRITE_ERROR(AParcel_writeInt64(parcel.get(), counter->getCount(state)));
     }
 }
 
@@ -144,16 +144,16 @@
     }
 
 static jlong native_initFromParcel(JNIEnv *env, jclass theClass, jobject jParcel) {
-    AParcel *parcel = AParcel_fromJavaParcel(env, jParcel);
+    ndk::ScopedAParcel parcel(AParcel_fromJavaParcel(env, jParcel));
 
     int32_t stateCount;
-    THROW_ON_READ_ERROR(AParcel_readInt32(parcel, &stateCount));
+    THROW_ON_READ_ERROR(AParcel_readInt32(parcel.get(), &stateCount));
 
     battery::LongMultiStateCounter *counter = new battery::LongMultiStateCounter(stateCount, 0);
 
     for (battery::state_t state = 0; state < stateCount; state++) {
         int64_t value;
-        THROW_ON_READ_ERROR(AParcel_readInt64(parcel, &value));
+        THROW_ON_READ_ERROR(AParcel_readInt64(parcel.get(), &value));
         counter->setValue(state, value);
     }
 
diff --git a/core/proto/android/os/appbackgroundrestrictioninfo.proto b/core/proto/android/os/appbackgroundrestrictioninfo.proto
index 502fd64..5bf8ea7 100644
--- a/core/proto/android/os/appbackgroundrestrictioninfo.proto
+++ b/core/proto/android/os/appbackgroundrestrictioninfo.proto
@@ -73,12 +73,17 @@
     optional FgsTrackerInfo fgs_tracker_info = 5;
 
     message BatteryTrackerInfo {
-        // total battery usage within last 24h (percentage)
+        // total battery usage within last 24h (1/10000th)
         optional int32 battery_24h = 1;
-        // background battery usage (percentage)
+        // background battery usage (1/10000th)
         optional int32 battery_usage_background = 2;
-        // FGS battery usage (percentage)
+        // FGS battery usage (1/10000th)
         optional int32 battery_usage_fgs = 3;
+        // Foreground battery usage (1/10000th)
+        optional int32 battery_usage_foreground = 4;
+        // Cached battery usage (1/10000th)
+        optional int32 battery_usage_cached = 5;
+
     }
     optional BatteryTrackerInfo battery_tracker_info = 6;
 
@@ -197,5 +202,8 @@
 
     // indicates if the current device is a low ram device.
     optional bool low_mem_device = 12;
+
+    // indicates previous background restriction level.
+    optional RestrictionLevel previous_restriction_level = 13;
 }
 
diff --git a/core/proto/android/view/imeinsetssourceconsumer.proto b/core/proto/android/view/imeinsetssourceconsumer.proto
index b1ed365..6e007fa 100644
--- a/core/proto/android/view/imeinsetssourceconsumer.proto
+++ b/core/proto/android/view/imeinsetssourceconsumer.proto
@@ -29,4 +29,6 @@
     optional InsetsSourceConsumerProto insets_source_consumer = 1;
     reserved 2; // focused_editor = 2
     optional bool is_requested_visible_awaiting_control = 3;
+    optional bool is_hide_animation_running = 4;
+    optional bool is_show_requested_during_hide_animation = 5;
 }
\ No newline at end of file
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4075c5f..217166c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -377,6 +377,8 @@
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" />
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" />
     <protected-broadcast android:name="com.android.internal.action.EUICC_FACTORY_RESET" />
+    <protected-broadcast
+        android:name="com.android.internal.action.EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS" />
     <protected-broadcast android:name="com.android.server.usb.ACTION_OPEN_IN_APPS" />
     <protected-broadcast android:name="com.android.server.am.DELETE_DUMPHEAP" />
     <protected-broadcast android:name="com.android.server.net.action.SNOOZE_WARNING" />
@@ -6790,7 +6792,7 @@
                   android:excludeFromRecents="true"
                   android:exported="true"
                   android:permission="android.permission.MANAGE_GAME_ACTIVITY"
-                  android:theme="@style/Theme.Translucent.NoTitleBar">
+                  android:theme="@style/Theme.GameSessionTrampoline">
         </activity>
 
         <receiver android:name="com.android.server.BootReceiver"
diff --git a/core/res/res/layout/app_language_picker_current_locale_item.xml b/core/res/res/layout/app_language_picker_current_locale_item.xml
index bf6d963..990e26c 100644
--- a/core/res/res/layout/app_language_picker_current_locale_item.xml
+++ b/core/res/res/layout/app_language_picker_current_locale_item.xml
@@ -39,6 +39,6 @@
             android:layout_width="24dp"
             android:layout_height="24dp"
             android:src="@drawable/ic_check_24dp"
-            app:tint="#0F9D58"/>
+            app:tint="?attr/colorAccentPrimaryVariant"/>
     </LinearLayout>
 </LinearLayout>
diff --git a/core/res/res/layout/app_language_picker_system_current.xml b/core/res/res/layout/app_language_picker_system_current.xml
index 341ee25..300da25 100644
--- a/core/res/res/layout/app_language_picker_system_current.xml
+++ b/core/res/res/layout/app_language_picker_system_current.xml
@@ -40,6 +40,6 @@
             android:layout_width="24dp"
             android:layout_height="24dp"
             android:src="@drawable/ic_check_24dp"
-            app:tint="#0F9D58"/>
+            app:tint="?attr/colorAccentPrimaryVariant"/>
     </LinearLayout>
 </LinearLayout>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 411a22d..d6d1e17 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2966,6 +2966,9 @@
          config_preventImeStartupUnlessTextEditor. -->
     <string-array name="config_nonPreemptibleInputMethods" translatable="false" />
 
+    <!-- Flag indicating that enhanced confirmation mode is enabled. -->
+    <bool name="config_enhancedConfirmationModeEnabled">true</bool>
+
     <!-- The list of classes that should be added to the notification ranking pipeline.
      See {@link com.android.server.notification.NotificationSignalExtractor}
       If you add a new extractor to this list make sure to update
@@ -5778,4 +5781,7 @@
     <string name="safety_protection_display_text"></string>
 
     <!-- End safety protection resources to be overlaid -->
+
+    <!-- List of the labels of requestable device state config values -->
+    <string-array name="config_deviceStatesAvailableForAppRequests"/>
 </resources>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 77500c4..d9ac516 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -109,4 +109,12 @@
     <!-- Telephony qualified networks service class name to bind to by default. -->
     <string name="config_qualified_networks_service_class" translatable="false"></string>
     <java-symbol type="string" name="config_qualified_networks_service_class" />
+
+    <!-- Whether enhanced IWLAN handover check is enabled. If enabled, telephony frameworks
+         will not perform handover if the target transport is out of service, or VoPS not
+         supported. The network will be torn down on the source transport, and will be
+         re-established on the target transport when condition is allowed for bringing up a
+         new network. -->
+    <bool name="config_enhanced_iwlan_handover_check">true</bool>
+    <java-symbol type="bool" name="config_enhanced_iwlan_handover_check" />
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 824dd8b..a4be0b9 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1798,45 +1798,57 @@
     <string name="fingerprint_recalibrate_notification_content">Visit a repair provider.</string>
 
     <!-- Message shown during face acquisition when the face cannot be recognized [CHAR LIMIT=50] -->
-    <string name="face_acquired_insufficient">Couldn\u2019t capture accurate face data. Try again.</string>
+    <string name="face_acquired_insufficient">Can\u2019t create your face model. Try again.</string>
     <!-- Message shown during face acquisition when the image is too bright [CHAR LIMIT=50] -->
     <string name="face_acquired_too_bright">Too bright. Try gentler lighting.</string>
     <!-- Message shown during face acquisition when the image is too dark [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_dark">Too dark. Try brighter lighting.</string>
+    <string name="face_acquired_too_dark">Try brighter lighting</string>
     <!-- Message shown during face acquisition when the user is too close to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_close">Move phone farther away.</string>
+    <string name="face_acquired_too_close">Move phone farther away</string>
     <!-- Message shown during face acquisition when the user is too far from sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_far">Move phone closer.</string>
+    <string name="face_acquired_too_far">Move phone closer</string>
     <!-- Message shown during face acquisition when the user is too high relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_high">Move phone higher.</string>
+    <string name="face_acquired_too_high">Move phone higher</string>
     <!-- Message shown during face acquisition when the user is too low relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_low">Move phone lower.</string>
+    <string name="face_acquired_too_low">Move phone lower</string>
     <!-- Message shown during face acquisition when only the right part of the user's face was detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_right">Move phone to the left.</string>
+    <string name="face_acquired_too_right">Move phone to your left</string>
     <!-- Message shown during face acquisition when only the left part of the user's face was detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_left">Move phone to the right.</string>
+    <string name="face_acquired_too_left">Move phone to your right</string>
     <!-- Message shown during face acquisition when the user is not front facing the sensor [CHAR LIMIT=50] -->
     <string name="face_acquired_poor_gaze">Please look more directly at your device.</string>
-    <!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_not_detected">Position your face directly in front of the phone.</string>
+    <!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=75] -->
+    <string name="face_acquired_not_detected">Can\u2019t see your face. Hold your phone at eye level.</string>
     <!-- Message shown during face acquisition when the device is not steady [CHAR LIMIT=50] -->
     <string name="face_acquired_too_much_motion">Too much motion. Hold phone steady.</string>
     <!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=50] -->
     <string name="face_acquired_recalibrate">Please re-enroll your face.</string>
     <!-- Message shown during face enrollment when a different person's face is detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_different">No longer able to recognize face. Try again.</string>
+    <string name="face_acquired_too_different">Can\u2019t recognize face. Try again.</string>
     <!-- Message shown during face enrollment when the face is too similar to a previous acquisition [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_similar">Too similar, please change your pose.</string>
+    <string name="face_acquired_too_similar">Change the position of your head slightly</string>
     <!-- Message shown during acqusition when the user's face is turned too far left or right [CHAR LIMIT=50] -->
-    <string name="face_acquired_pan_too_extreme">Turn your head a little less.</string>
+    <string name="face_acquired_pan_too_extreme">Look more directly at your phone</string>
     <!-- Message shown during acqusition when the user's face is tilted too high or too low [CHAR LIMIT=50] -->
-    <string name="face_acquired_tilt_too_extreme">Tilt your head a little less.</string>
+    <string name="face_acquired_tilt_too_extreme">Look more directly at your phone</string>
     <!-- Message shown during acquisiton when the user's face is tilted too far left or right [CHAR LIMIT=50] -->
-    <string name="face_acquired_roll_too_extreme">Turn your head a little less.</string>
+    <string name="face_acquired_roll_too_extreme">Look more directly at your phone</string>
     <!-- Message shown during acquisition when the user's face is obscured [CHAR LIMIT=50] -->
     <string name="face_acquired_obscured">Remove anything hiding your face.</string>
     <!-- Message shown during acquisition when the sensor is dirty [CHAR LIMIT=100] -->
     <string name="face_acquired_sensor_dirty">Clean the top of your screen, including the black bar</string>
+    <!-- Message shown during acquisition when dark glasses were detected [CHAR LIMIT=75] -->
+    <string name="face_acquired_dark_glasses_detected">Your face must be fully visible</string>
+    <!-- Message shown during acquisition when a mouth covering was detected [CHAR LIMIT=75] -->
+    <string name="face_acquired_mouth_covering_detected">Your face must be fully visible</string>
+
+    <!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=75] -->
+    <string name="face_acquired_recalibrate_alt">Can\u2019t create your face model. Try again.</string>
+    <!-- Message shown during acquisition when dark glasses were detected [CHAR LIMIT=100] -->
+    <string name="face_acquired_dark_glasses_detected_alt">Dark glasses detected. Your face must be fully visible.</string>
+    <!-- Message shown during acquisition when a mouth covering was detected [CHAR LIMIT=100] -->
+    <string name="face_acquired_mouth_covering_detected_alt">Face covering detected. Your face must be fully visible.</string>
+
     <!-- Array containing custom messages shown during face acquisition from vendor.  Vendor is expected to add and translate these strings -->
     <string-array name="face_acquired_vendor">
     </string-array>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d971add..c3c656a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2257,6 +2257,7 @@
   <java-symbol type="bool" name="config_killableInputMethods" />
   <java-symbol type="bool" name="config_preventImeStartupUnlessTextEditor" />
   <java-symbol type="array" name="config_nonPreemptibleInputMethods" />
+  <java-symbol type="bool" name="config_enhancedConfirmationModeEnabled" />
 
   <java-symbol type="layout" name="resolver_list" />
   <java-symbol type="id" name="resolver_list" />
@@ -2656,6 +2657,11 @@
   <java-symbol type="string" name="face_acquired_roll_too_extreme" />
   <java-symbol type="string" name="face_acquired_obscured" />
   <java-symbol type="string" name="face_acquired_sensor_dirty" />
+  <java-symbol type="string" name="face_acquired_dark_glasses_detected" />
+  <java-symbol type="string" name="face_acquired_mouth_covering_detected" />
+  <java-symbol type="string" name="face_acquired_recalibrate_alt" />
+  <java-symbol type="string" name="face_acquired_dark_glasses_detected_alt" />
+  <java-symbol type="string" name="face_acquired_mouth_covering_detected_alt" />
   <java-symbol type="array" name="face_acquired_vendor" />
   <java-symbol type="string" name="face_name_template" />
   <java-symbol type="string" name="face_app_setting_name" />
@@ -4774,6 +4780,7 @@
   <java-symbol type="bool" name="config_bg_current_drain_high_threshold_by_bg_location" />
   <java-symbol type="drawable" name="ic_swap_horiz" />
   <java-symbol type="bool" name="config_notificationForceUserSetOnUpgrade" />
+  <java-symbol type="array" name="config_deviceStatesAvailableForAppRequests" />
 
   <!-- For app language picker -->
   <java-symbol type="string" name="system_locale_title" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index bf42da0..a60862b 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -894,6 +894,22 @@
     <!-- @hide Special theme for the default system Activity-based Alert dialogs. -->
     <style name="Theme.Dialog.Confirmation" parent="Theme.DeviceDefault.Dialog.Alert.DayNight" />
 
+    <!-- @hide Theme for GameSessionTrampolineActivity that prevents showing UI and activity
+         transitions. -->
+    <style name="Theme.GameSessionTrampoline">
+        <item name="backgroundDimEnabled">false</item>
+        <item name="colorBackgroundCacheHint">@null</item>
+        <item name="navigationBarColor">@color/transparent</item>
+        <item name="statusBarColor">@color/transparent</item>
+        <item name="windowAnimationStyle">@null</item>
+        <item name="windowBackground">@null</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowDrawsSystemBarBackgrounds">true</item>
+        <item name="windowIsFloating">true</item>
+        <item name="windowIsTranslucent">true</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
     <!-- Theme for a window that looks like a toast. -->
     <style name="Theme.Toast" parent="Theme.DeviceDefault.Dialog">
         <item name="windowBackground">?attr/toastFrameBackground</item>
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
index c194989..8587a35 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
@@ -166,7 +166,8 @@
                 new HashSet<ProgramSelector.Identifier>(), true, false);
 
         // Start updates on the clients in order. The HAL filter should get updated after each
-        // client except [2].
+        // client except [2]. Client [2] should update received chunk with an empty program
+        // list
         mTunerSessions[0].startProgramListUpdates(idFilter);
         ProgramFilter halFilter = Convert.programFilterToHal(idFilter);
         verify(mHalTunerSessionMock, times(1)).startProgramListUpdates(halFilter);
@@ -177,6 +178,9 @@
 
         mTunerSessions[2].startProgramListUpdates(typeFilterWithoutModifications);
         verify(mHalTunerSessionMock, times(2)).startProgramListUpdates(any());
+        verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[2], true, Arrays.asList(),
+                null);
+        verify(mAidlTunerCallbackMocks[2], CB_TIMEOUT.times(1)).onProgramListUpdated(any());
 
         mTunerSessions[3].startProgramListUpdates(typeFilterWithModifications);
         halFilter.excludeModifications = false;
@@ -207,7 +211,7 @@
         updateHalProgramInfo(false, Arrays.asList(mDabEnsembleInfo), null);
         verify(mAidlTunerCallbackMocks[0], CB_TIMEOUT.times(1)).onProgramListUpdated(any());
         verify(mAidlTunerCallbackMocks[1], CB_TIMEOUT.times(2)).onProgramListUpdated(any());
-        verify(mAidlTunerCallbackMocks[2], CB_TIMEOUT.times(1)).onProgramListUpdated(any());
+        verify(mAidlTunerCallbackMocks[2], CB_TIMEOUT.times(2)).onProgramListUpdated(any());
         verify(mAidlTunerCallbackMocks[3], CB_TIMEOUT.times(2)).onProgramListUpdated(any());
     }
 
diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java
index e083b0d..3733bfa 100644
--- a/core/tests/coretests/src/android/net/UriTest.java
+++ b/core/tests/coretests/src/android/net/UriTest.java
@@ -48,6 +48,7 @@
     public void testParcelling() {
         parcelAndUnparcel(Uri.parse("foo:bob%20lee"));
         parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment"));
+        parcelAndUnparcel(Uri.fromParts("https", "www.google.com", null));
         parcelAndUnparcel(new Uri.Builder()
             .scheme("http")
             .authority("crazybob.org")
@@ -890,9 +891,62 @@
             Throwable targetException = expected.getTargetException();
             // Check that the exception was thrown for the correct reason.
             assertEquals("Unknown representation: 0", targetException.getMessage());
+        } finally {
+            parcel.recycle();
         }
     }
 
+    private Uri buildUriFromRawParcel(boolean argumentsEncoded,
+                                      String scheme,
+                                      String authority,
+                                      String path,
+                                      String query,
+                                      String fragment) {
+        // Representation value (from AbstractPart.REPRESENTATION_{ENCODED,DECODED}).
+        final int representation = argumentsEncoded ? 1 : 2;
+        Parcel parcel = Parcel.obtain();
+        try {
+            parcel.writeInt(3);  // hierarchical
+            parcel.writeString8(scheme);
+            parcel.writeInt(representation);
+            parcel.writeString8(authority);
+            parcel.writeInt(representation);
+            parcel.writeString8(path);
+            parcel.writeInt(representation);
+            parcel.writeString8(query);
+            parcel.writeInt(representation);
+            parcel.writeString8(fragment);
+            parcel.setDataPosition(0);
+            return Uri.CREATOR.createFromParcel(parcel);
+        } finally {
+            parcel.recycle();
+        }
+    }
+
+    public void testUnparcelMalformedPath() {
+        // Regression tests for b/171966843.
+
+        // Test cases with arguments encoded (covering testing `scheme` * `authority` options).
+        Uri uri0 = buildUriFromRawParcel(true, "https", "google.com", "@evil.com", null, null);
+        assertEquals("https://google.com/@evil.com", uri0.toString());
+        Uri uri1 = buildUriFromRawParcel(true, null, "google.com", "@evil.com", "name=spark", "x");
+        assertEquals("//google.com/@evil.com?name=spark#x", uri1.toString());
+        Uri uri2 = buildUriFromRawParcel(true, "http:", null, "@evil.com", null, null);
+        assertEquals("http::/@evil.com", uri2.toString());
+        Uri uri3 = buildUriFromRawParcel(true, null, null, "@evil.com", null, null);
+        assertEquals("@evil.com", uri3.toString());
+
+        // Test cases with arguments not encoded (covering testing `scheme` * `authority` options).
+        Uri uriA = buildUriFromRawParcel(false, "https", "google.com", "@evil.com", null, null);
+        assertEquals("https://google.com/%40evil.com", uriA.toString());
+        Uri uriB = buildUriFromRawParcel(false, null, "google.com", "@evil.com", null, null);
+        assertEquals("//google.com/%40evil.com", uriB.toString());
+        Uri uriC = buildUriFromRawParcel(false, "http:", null, "@evil.com", null, null);
+        assertEquals("http::/%40evil.com", uriC.toString());
+        Uri uriD = buildUriFromRawParcel(false, null, null, "@evil.com", "name=spark", "y");
+        assertEquals("%40evil.com?name%3Dspark#y", uriD.toString());
+    }
+
     public void testToSafeString() {
         checkToSafeString("tel:xxxxxx", "tel:Google");
         checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890");
diff --git a/core/tests/coretests/src/android/widget/DateTimeViewTest.java b/core/tests/coretests/src/android/widget/DateTimeViewTest.java
index d0bd4b8..14b48ed 100644
--- a/core/tests/coretests/src/android/widget/DateTimeViewTest.java
+++ b/core/tests/coretests/src/android/widget/DateTimeViewTest.java
@@ -16,14 +16,20 @@
 
 package android.widget;
 
+import android.view.View;
+import android.view.ViewGroup;
+
 import androidx.test.InstrumentationRegistry;
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.time.Duration;
+
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class DateTimeViewTest {
@@ -39,7 +45,33 @@
         dateTimeView.detachedFromWindow();
     }
 
+    @UiThreadTest
+    @Test
+    public void noChangeInRelativeText_doesNotTriggerRelayout() {
+        // Week in the future is chosen because it'll result in a stable string during this test
+        // run. This should be improved once the class is refactored to be more testable in
+        // respect of clock retrieval.
+        final long weekInTheFuture = System.currentTimeMillis() + Duration.ofDays(7).toMillis();
+        final TestDateTimeView dateTimeView = new TestDateTimeView();
+        dateTimeView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT));
+        dateTimeView.setShowRelativeTime(true);
+        dateTimeView.setTime(weekInTheFuture);
+        // View needs to be measured to request layout, skipping this would make this test pass
+        // always.
+        dateTimeView.measure(View.MeasureSpec.makeMeasureSpec(200, View.MeasureSpec.UNSPECIFIED),
+                View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.UNSPECIFIED));
+        dateTimeView.reset();
+
+        // This should not change the text content and thus no relayout is expected.
+        dateTimeView.setTime(weekInTheFuture + 1000);
+
+        Assert.assertFalse(dateTimeView.wasLayoutRequested());
+    }
+
     private static class TestDateTimeView extends DateTimeView {
+        private boolean mRequestedLayout = false;
+
         TestDateTimeView() {
             super(InstrumentationRegistry.getContext());
         }
@@ -51,5 +83,18 @@
         void detachedFromWindow() {
             super.onDetachedFromWindow();
         }
+
+        public void requestLayout() {
+            super.requestLayout();
+            mRequestedLayout = true;
+        }
+
+        public boolean wasLayoutRequested() {
+            return mRequestedLayout;
+        }
+
+        public void reset() {
+            mRequestedLayout = false;
+        }
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java b/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java
index 04b8886..3e640c1 100644
--- a/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java
@@ -115,11 +115,6 @@
 
             @Override
             void handleResultMessage(Message message) {}
-
-            @Override
-            List<ComponentName> getTopComponentNames(int topK) {
-                return null;
-            }
         };
         return testComparator;
     }
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index cf78646..b38e1c2 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -81,7 +81,6 @@
 import android.os.UserHandle;
 import android.provider.DeviceConfig;
 import android.service.chooser.ChooserTarget;
-import android.util.Log;
 import android.view.View;
 
 import androidx.annotation.CallSuper;
@@ -623,7 +622,7 @@
         List<ResolvedComponentInfo> stableCopy =
                 createResolvedComponentsForTestWithOtherProfile(2, /* userId= */ 10);
         waitForIdle();
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         onView(first(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)))
                 .perform(click());
@@ -1437,7 +1436,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
                 activity.getAdapter().getCount(), is(3));
@@ -1513,7 +1512,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
                 activity.getAdapter().getCount(), is(3));
@@ -1595,7 +1594,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
                 wrapper.getAdapter().getCount(), is(3));
@@ -1667,7 +1666,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat("Chooser should have 4 targets (2 apps, 2 direct)",
                 wrapper.getAdapter().getCount(), is(4));
@@ -1754,7 +1753,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat(
                 String.format("Chooser should have %d targets (%d apps, 1 direct, 15 A-Z)",
@@ -1879,12 +1878,13 @@
             return true;
         };
 
-        mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
+        final IChooserWrapper activity = (IChooserWrapper)
+                mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
         waitForIdle();
         onView(withTextFromRuntimeResource("resolver_work_tab")).perform(click());
         waitForIdle();
         // wait for the share sheet to expand
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         onView(first(allOf(
                 withText(workResolvedComponentInfos.get(0)
@@ -2023,7 +2023,7 @@
                 .check(matches(isDisplayed()));
     }
 
-    @Test
+    @Test @Ignore("b/222124533")
     public void testAppTargetLogging() throws InterruptedException {
         Intent sendIntent = createSendTextIntent();
         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -2042,6 +2042,10 @@
                 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
         waitForIdle();
 
+        // TODO(b/222124533): other test cases use a timeout to make sure that the UI is fully
+        // populated; without one, this test flakes. Ideally we should address the need for a
+        // timeout everywhere instead of introducing one to fix this particular test.
+
         assertThat(activity.getAdapter().getCount(), is(2));
         onView(withIdFromRuntimeResource("profile_button")).check(doesNotExist());
 
@@ -2143,7 +2147,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
                 activity.getAdapter().getCount(), is(3));
@@ -2324,7 +2328,7 @@
         assertThat(logger.numCalls(), is(6));
     }
 
-    @Test
+    @Test @Ignore("b/222124533")
     public void testSwitchProfileLogging() throws InterruptedException {
         // enable the work tab feature flag
         ResolverActivity.ENABLE_TABBED_VIEW = true;
@@ -3069,8 +3073,15 @@
     // framework code on the device is up-to-date.
     // TODO: is there a better way to do this? (Other than abandoning inheritance-based DI wrapper?)
     private int getRuntimeResourceId(String name, String defType) {
-        int id = mActivityRule.getActivity().getResources().getIdentifier(name, defType, "android");
+        int id = -1;
+        if (ChooserActivityOverrideData.getInstance().resources != null) {
+            id = ChooserActivityOverrideData.getInstance().resources.getIdentifier(
+                  name, defType, "android");
+        } else {
+            id = mActivityRule.getActivity().getResources().getIdentifier(name, defType, "android");
+        }
         assertThat(id, greaterThan(0));
+
         return id;
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/app/FakeResolverComparatorModel.java b/core/tests/coretests/src/com/android/internal/app/FakeResolverComparatorModel.java
new file mode 100644
index 0000000..fbbe57c
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/app/FakeResolverComparatorModel.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.content.ComponentName;
+import android.content.pm.ResolveInfo;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Basic {@link ResolverComparatorModel} implementation that sorts according to a pre-defined (or
+ * default) {@link java.util.Comparator}.
+ */
+public class FakeResolverComparatorModel implements ResolverComparatorModel {
+    private final Comparator<ResolveInfo> mComparator;
+
+    public static FakeResolverComparatorModel makeModelFromComparator(
+            Comparator<ResolveInfo> comparator) {
+        return new FakeResolverComparatorModel(comparator);
+    }
+
+    public static FakeResolverComparatorModel makeDefaultModel() {
+       return makeModelFromComparator(Comparator.comparing(ri -> ri.activityInfo.name));
+    }
+
+    @Override
+    public Comparator<ResolveInfo> getComparator() {
+        return mComparator;
+    }
+
+    @Override
+    public float getScore(ComponentName name) {
+        return 0.0f;  // Models are not required to provide numerical scores.
+    }
+
+    @Override
+    public void notifyOnTargetSelected(ComponentName componentName) {
+        System.out.println(
+                "User selected " + componentName + " under model " + System.identityHashCode(this));
+    }
+
+    private FakeResolverComparatorModel(Comparator<ResolveInfo> comparator) {
+        mComparator = comparator;
+    }
+}
\ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
index 0f48465..09fc7ea 100644
--- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
@@ -162,7 +162,8 @@
                 eq(0L) /* missedFrames */,
                 eq(5000000L) /* maxFrameTimeNanos */,
                 eq(0L) /* missedSfFramesCount */,
-                eq(0L) /* missedAppFramesCount */);
+                eq(0L) /* missedAppFramesCount */,
+                eq(0L) /* maxSuccessiveMissedFramesCount */);
     }
 
     @Test
@@ -196,7 +197,8 @@
                 eq(1L) /* missedFrames */,
                 eq(40000000L) /* maxFrameTimeNanos */,
                 eq(1L) /* missedSfFramesCount */,
-                eq(0L) /* missedAppFramesCount */);
+                eq(0L) /* missedAppFramesCount */,
+                eq(1L) /* maxSuccessiveMissedFramesCount */);
     }
 
     @Test
@@ -230,7 +232,8 @@
                 eq(0L) /* missedFrames */,
                 eq(4000000L) /* maxFrameTimeNanos */,
                 eq(0L) /* missedSfFramesCount */,
-                eq(0L) /* missedAppFramesCount */);
+                eq(0L) /* missedAppFramesCount */,
+                eq(0L) /* maxSuccessiveMissedFramesCount */);
     }
 
     @Test
@@ -264,7 +267,8 @@
                 eq(1L) /* missedFrames */,
                 eq(40000000L) /* maxFrameTimeNanos */,
                 eq(0L) /* missedSfFramesCount */,
-                eq(1L) /* missedAppFramesCount */);
+                eq(1L) /* missedAppFramesCount */,
+                eq(1L) /* maxSuccessiveMissedFramesCount */);
     }
 
     @Test
@@ -301,7 +305,8 @@
                 eq(1L) /* missedFrames */,
                 eq(50000000L) /* maxFrameTimeNanos */,
                 eq(0L) /* missedSfFramesCount */,
-                eq(1L) /* missedAppFramesCount */);
+                eq(1L) /* missedAppFramesCount */,
+                eq(1L) /* maxSuccessiveMissedFramesCount */);
     }
 
     /**
@@ -340,7 +345,8 @@
                 eq(0L) /* missedFrames */,
                 eq(4000000L) /* maxFrameTimeNanos */,
                 eq(0L) /* missedSfFramesCount */,
-                eq(0L) /* missedAppFramesCount */);
+                eq(0L) /* missedAppFramesCount */,
+                eq(0L) /* maxSuccessiveMissedFramesCount */);
     }
 
     @Test
@@ -462,7 +468,8 @@
                 eq(1L) /* missedFrames */,
                 eq(0L) /* maxFrameTimeNanos */,
                 eq(0L) /* missedSfFramesCount */,
-                eq(1L) /* missedAppFramesCount */);
+                eq(1L) /* missedAppFramesCount */,
+                eq(1L) /* maxSuccessiveMissedFramesCount */);
     }
 
     @Test
@@ -496,7 +503,8 @@
                 eq(0L) /* missedFrames */,
                 eq(0L) /* maxFrameTimeNanos */,
                 eq(0L) /* missedSfFramesCount */,
-                eq(0L) /* missedAppFramesCount */);
+                eq(0L) /* missedAppFramesCount */,
+                eq(0L) /* maxSuccessiveMissedFramesCount */);
     }
 
     @Test
@@ -530,7 +538,37 @@
                 eq(0L) /* missedFrames */,
                 eq(0L) /* maxFrameTimeNanos */,
                 eq(0L) /* missedSfFramesCount */,
-                eq(0L) /* missedAppFramesCount */);
+                eq(0L) /* missedAppFramesCount */,
+                eq(0L) /* maxSuccessiveMissedFramesCount */);
+    }
+
+    @Test
+    public void testMaxSuccessiveMissedFramesCount() {
+        FrameTracker tracker = spyFrameTracker(
+                CUJ_WALLPAPER_TRANSITION, CUJ_POSTFIX, /* surfaceOnly= */ true);
+        when(mChoreographer.getVsyncId()).thenReturn(100L);
+        tracker.begin();
+        verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());
+        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 100L);
+        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 101L);
+        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 102L);
+        sendFrame(tracker, JANK_NONE, 103L);
+        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 104L);
+        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 105L);
+        when(mChoreographer.getVsyncId()).thenReturn(106L);
+        tracker.end(FrameTracker.REASON_END_NORMAL);
+        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 106L);
+        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 107L);
+        verify(mSurfaceControlWrapper).removeJankStatsListener(any());
+        verify(tracker).triggerPerfetto();
+        verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
+                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION]),
+                eq(6L) /* totalFrames */,
+                eq(5L) /* missedFrames */,
+                eq(0L) /* maxFrameTimeNanos */,
+                eq(2L) /* missedSfFramesCount */,
+                eq(3L) /* missedAppFramesCount */,
+                eq(3L) /* maxSuccessiveMissedFramesCount */);
     }
 
     private void sendFirstWindowFrame(FrameTracker tracker, long durationMillis,
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 2f021fe..07a3429 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -3031,6 +3031,12 @@
       "group": "WM_DEBUG_FOCUS_LIGHT",
       "at": "com\/android\/server\/wm\/DisplayContent.java"
     },
+    "873160948": {
+      "message": "Activity=%s reparent to taskId=%d",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_ORGANIZER",
+      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
+    },
     "873914452": {
       "message": "goodToGo()",
       "level": "DEBUG",
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index b04b826..a76d74e 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -128,6 +128,7 @@
     // TYPE_RESOURCE: Resources
     // TYPE_DATA: DataBytes
     private Object          mObj1;
+    private boolean mCachedAshmem = false;
 
     // TYPE_RESOURCE: package name
     // TYPE_URI: uri string
@@ -156,6 +157,8 @@
     /**
      * @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} or
      * {@link #TYPE_ADAPTIVE_BITMAP} Icon.
+     *
+     * Note that this will always return an immutable Bitmap.
      * @hide
      */
     @UnsupportedAppUsage
@@ -166,8 +169,20 @@
         return (Bitmap) mObj1;
     }
 
+    /**
+     * Sets the Icon's contents to a particular Bitmap. Note that this may make a copy of the Bitmap
+     * if the supplied Bitmap is mutable. In that case, the value returned by getBitmap() may not
+     * equal the Bitmap passed to setBitmap().
+     *
+     * @hide
+     */
     private void setBitmap(Bitmap b) {
-        mObj1 = b;
+        if (b.isMutable()) {
+            mObj1 = b.copy(b.getConfig(), false);
+        } else {
+            mObj1 = b;
+        }
+        mCachedAshmem = false;
     }
 
     /**
@@ -488,6 +503,7 @@
             getBitmap().getAllocationByteCount() >= MIN_ASHMEM_ICON_SIZE) {
             setBitmap(getBitmap().asShared());
         }
+        mCachedAshmem = true;
     }
 
     /**
@@ -913,7 +929,10 @@
         switch (mType) {
             case TYPE_BITMAP:
             case TYPE_ADAPTIVE_BITMAP:
-                final Bitmap bits = getBitmap();
+                if (!mCachedAshmem) {
+                    mObj1 = ((Bitmap) mObj1).asShared();
+                    mCachedAshmem = true;
+                }
                 getBitmap().writeToParcel(dest, flags);
                 break;
             case TYPE_RESOURCE:
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index f4e91ba..81caf77 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -16,7 +16,6 @@
 
 package androidx.window.extensions.embedding;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 
 import android.app.Activity;
@@ -49,7 +48,8 @@
 class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
 
     /** Mapping from the client assigned unique token to the {@link TaskFragmentInfo}. */
-    private final Map<IBinder, TaskFragmentInfo> mFragmentInfos = new ArrayMap<>();
+    @VisibleForTesting
+    final Map<IBinder, TaskFragmentInfo> mFragmentInfos = new ArrayMap<>();
 
     /**
      * Mapping from the client assigned unique token to the TaskFragment parent
@@ -70,6 +70,8 @@
         void onTaskFragmentVanished(@NonNull TaskFragmentInfo taskFragmentInfo);
         void onTaskFragmentParentInfoChanged(@NonNull IBinder fragmentToken,
                 @NonNull Configuration parentConfig);
+        void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent,
+                @NonNull IBinder activityToken);
     }
 
     /**
@@ -118,25 +120,29 @@
      * @param secondaryFragmentBounds   the initial bounds for the secondary TaskFragment
      * @param activityIntent    Intent to start the secondary Activity with.
      * @param activityOptions   ActivityOptions to start the secondary Activity with.
+     * @param windowingMode     the windowing mode to set for the TaskFragments.
      */
     void startActivityToSide(@NonNull WindowContainerTransaction wct,
             @NonNull IBinder launchingFragmentToken, @NonNull Rect launchingFragmentBounds,
             @NonNull Activity launchingActivity, @NonNull IBinder secondaryFragmentToken,
             @NonNull Rect secondaryFragmentBounds, @NonNull Intent activityIntent,
-            @Nullable Bundle activityOptions, @NonNull SplitRule rule) {
+            @Nullable Bundle activityOptions, @NonNull SplitRule rule,
+            @WindowingMode int windowingMode) {
         final IBinder ownerToken = launchingActivity.getActivityToken();
 
         // Create or resize the launching TaskFragment.
         if (mFragmentInfos.containsKey(launchingFragmentToken)) {
             resizeTaskFragment(wct, launchingFragmentToken, launchingFragmentBounds);
+            wct.setWindowingMode(mFragmentInfos.get(launchingFragmentToken).getToken(),
+                    windowingMode);
         } else {
             createTaskFragmentAndReparentActivity(wct, launchingFragmentToken, ownerToken,
-                    launchingFragmentBounds, WINDOWING_MODE_MULTI_WINDOW, launchingActivity);
+                    launchingFragmentBounds, windowingMode, launchingActivity);
         }
 
         // Create a TaskFragment for the secondary activity.
         createTaskFragmentAndStartActivity(wct, secondaryFragmentToken, ownerToken,
-                secondaryFragmentBounds, WINDOWING_MODE_MULTI_WINDOW, activityIntent,
+                secondaryFragmentBounds, windowingMode, activityIntent,
                 activityOptions);
 
         // Set adjacent to each other so that the containers below will be invisible.
@@ -151,6 +157,7 @@
     void expandTaskFragment(WindowContainerTransaction wct, IBinder fragmentToken) {
         resizeTaskFragment(wct, fragmentToken, new Rect());
         setAdjacentTaskFragments(wct, fragmentToken, null /* secondary */, null /* splitRule */);
+        setWindowingMode(wct, fragmentToken, WINDOWING_MODE_UNDEFINED);
     }
 
     /**
@@ -253,6 +260,15 @@
         wct.setBounds(mFragmentInfos.get(fragmentToken).getToken(), bounds);
     }
 
+    private void setWindowingMode(WindowContainerTransaction wct, IBinder fragmentToken,
+            @WindowingMode int windowingMode) {
+        if (!mFragmentInfos.containsKey(fragmentToken)) {
+            throw new IllegalArgumentException(
+                    "Can't find an existing TaskFragment with fragmentToken=" + fragmentToken);
+        }
+        wct.setWindowingMode(mFragmentInfos.get(fragmentToken).getToken(), windowingMode);
+    }
+
     void deleteTaskFragment(WindowContainerTransaction wct, IBinder fragmentToken) {
         if (!mFragmentInfos.containsKey(fragmentToken)) {
             throw new IllegalArgumentException(
@@ -300,4 +316,12 @@
             mCallback.onTaskFragmentParentInfoChanged(fragmentToken, parentConfig);
         }
     }
+
+    @Override
+    public void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent,
+            @NonNull IBinder activityToken) {
+        if (mCallback != null) {
+            mCallback.onActivityReparentToTask(taskId, activityIntent, activityToken);
+        }
+    }
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index ca420c6..b370e59 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -112,9 +112,10 @@
      */
     public void startActivityToSide(@NonNull Activity launchingActivity, @NonNull Intent intent,
             @Nullable Bundle options, @NonNull SplitRule sideRule,
-            @Nullable Consumer<Exception> failureCallback) {
+            @Nullable Consumer<Exception> failureCallback, boolean isPlaceholder) {
         try {
-            mPresenter.startActivityToSide(launchingActivity, intent, options, sideRule);
+            mPresenter.startActivityToSide(launchingActivity, intent, options, sideRule,
+                    isPlaceholder);
         } catch (Exception e) {
             if (failureCallback != null) {
                 failureCallback.accept(e);
@@ -222,6 +223,19 @@
         }
     }
 
+    @Override
+    public void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent,
+            @NonNull IBinder activityToken) {
+        // If the activity belongs to the current app process, we treat it as a new activity launch.
+        final Activity activity = ActivityThread.currentActivityThread().getActivity(activityToken);
+        if (activity != null) {
+            onActivityCreated(activity);
+            updateCallbackIfNecessary();
+            return;
+        }
+        // TODO: handle for activity in other process.
+    }
+
     /** Called on receiving {@link #onTaskFragmentVanished(TaskFragmentInfo)} for cleanup. */
     private void cleanupTaskFragment(@NonNull IBinder taskFragmentToken) {
         for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
@@ -243,9 +257,9 @@
         if (taskContainer == null) {
             return;
         }
-        final boolean wasInPip = isInPictureInPicture(taskContainer.getConfiguration());
+        final boolean wasInPip = taskContainer.isInPictureInPicture();
         final boolean isInPIp = isInPictureInPicture(config);
-        taskContainer.setConfiguration(config);
+        taskContainer.setWindowingMode(config.windowConfiguration.getWindowingMode());
 
         // We need to check the animation override when enter/exit PIP or has bounds changed.
         boolean shouldUpdateAnimationOverride = wasInPip != isInPIp;
@@ -264,8 +278,9 @@
      * bounds is large enough for at least one split rule.
      */
     private void updateAnimationOverride(@NonNull TaskContainer taskContainer) {
-        if (!taskContainer.isTaskBoundsInitialized()) {
-            // We don't know about the Task bounds yet.
+        if (!taskContainer.isTaskBoundsInitialized()
+                || !taskContainer.isWindowingModeInitialized()) {
+            // We don't know about the Task bounds/windowingMode yet.
             return;
         }
 
@@ -279,7 +294,7 @@
 
     private boolean supportSplit(@NonNull TaskContainer taskContainer) {
         // No split inside PIP.
-        if (isInPictureInPicture(taskContainer.getConfiguration())) {
+        if (taskContainer.isInPictureInPicture()) {
             return false;
         }
         // Check if the parent container bounds can support any split rule.
@@ -447,8 +462,12 @@
             if (!taskContainer.setTaskBounds(taskBounds)) {
                 Log.w(TAG, "Can't find bounds from activity=" + activityInTask);
             }
-            updateAnimationOverride(taskContainer);
         }
+        if (!taskContainer.isWindowingModeInitialized()) {
+            taskContainer.setWindowingMode(activityInTask.getResources().getConfiguration()
+                    .windowConfiguration.getWindowingMode());
+        }
+        updateAnimationOverride(taskContainer);
         return container;
     }
 
@@ -697,8 +716,8 @@
         }
 
         // TODO(b/190433398): Handle failed request
-        startActivityToSide(activity, placeholderRule.getPlaceholderIntent(), null,
-                placeholderRule, null);
+        startActivityToSide(activity, placeholderRule.getPlaceholderIntent(), null /* options */,
+                placeholderRule, null /* failureCallback */, true /* isPlaceholder */);
         return true;
     }
 
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index 716a087..e64e5d1 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -16,10 +16,11 @@
 
 package androidx.window.extensions.embedding;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 
 import android.app.Activity;
 import android.app.WindowConfiguration;
+import android.app.WindowConfiguration.WindowingMode;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Rect;
@@ -111,13 +112,16 @@
                 primaryActivity, primaryRectBounds, null);
 
         // Create new empty task fragment
+        final int taskId = primaryContainer.getTaskId();
         final TaskFragmentContainer secondaryContainer = mController.newContainer(
-                null /* activity */, primaryActivity, primaryContainer.getTaskId());
+                null /* activity */, primaryActivity, taskId);
         final Rect secondaryRectBounds = getBoundsForPosition(POSITION_END, parentBounds,
                 rule, isLtr(primaryActivity, rule));
+        final int windowingMode = mController.getTaskContainer(taskId)
+                .getWindowingModeForSplitTaskFragment(secondaryRectBounds);
         createTaskFragment(wct, secondaryContainer.getTaskFragmentToken(),
                 primaryActivity.getActivityToken(), secondaryRectBounds,
-                WINDOWING_MODE_MULTI_WINDOW);
+                windowingMode);
         secondaryContainer.setLastRequestedBounds(secondaryRectBounds);
 
         // Set adjacent to each other so that the containers below will be invisible.
@@ -173,7 +177,7 @@
 
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         createTaskFragment(wct, newContainer.getTaskFragmentToken(),
-                launchingActivity.getActivityToken(), new Rect(), WINDOWING_MODE_MULTI_WINDOW);
+                launchingActivity.getActivityToken(), new Rect(), WINDOWING_MODE_UNDEFINED);
 
         applyTransaction(wct);
         return newContainer;
@@ -189,15 +193,17 @@
             @NonNull Rect bounds, @Nullable TaskFragmentContainer containerToAvoid) {
         TaskFragmentContainer container = mController.getContainerWithActivity(
                 activity.getActivityToken());
+        final int taskId = container != null ? container.getTaskId() : activity.getTaskId();
+        final int windowingMode = mController.getTaskContainer(taskId)
+                .getWindowingModeForSplitTaskFragment(bounds);
         if (container == null || container == containerToAvoid) {
-            container = mController.newContainer(activity, activity.getTaskId());
-
+            container = mController.newContainer(activity, taskId);
             final TaskFragmentCreationParams fragmentOptions =
                     createFragmentOptions(
                             container.getTaskFragmentToken(),
                             activity.getActivityToken(),
                             bounds,
-                            WINDOWING_MODE_MULTI_WINDOW);
+                            windowingMode);
             wct.createTaskFragment(fragmentOptions);
 
             wct.reparentActivityToTaskFragment(container.getTaskFragmentToken(),
@@ -206,6 +212,7 @@
             container.setLastRequestedBounds(bounds);
         } else {
             resizeTaskFragmentIfRegistered(wct, container, bounds);
+            updateTaskFragmentWindowingModeIfRegistered(wct, container, windowingMode);
         }
 
         return container;
@@ -217,12 +224,13 @@
      * @param launchingActivity An activity that should be in the primary container. If it is not
      *                          currently in an existing container, a new one will be created and
      *                          the activity will be re-parented to it.
-     * @param activityIntent The intent to start the new activity.
-     * @param activityOptions The options to apply to new activity start.
-     * @param rule The split rule to be applied to the container.
+     * @param activityIntent    The intent to start the new activity.
+     * @param activityOptions   The options to apply to new activity start.
+     * @param rule              The split rule to be applied to the container.
+     * @param isPlaceholder     Whether the launch is a placeholder.
      */
     void startActivityToSide(@NonNull Activity launchingActivity, @NonNull Intent activityIntent,
-            @Nullable Bundle activityOptions, @NonNull SplitRule rule) {
+            @Nullable Bundle activityOptions, @NonNull SplitRule rule, boolean isPlaceholder) {
         final Rect parentBounds = getParentContainerBounds(launchingActivity);
         final Rect primaryRectBounds = getBoundsForPosition(POSITION_START, parentBounds, rule,
                 isLtr(launchingActivity, rule));
@@ -236,14 +244,21 @@
                     launchingActivity.getTaskId());
         }
 
+        final int taskId = primaryContainer.getTaskId();
         TaskFragmentContainer secondaryContainer = mController.newContainer(null /* activity */,
-                launchingActivity, primaryContainer.getTaskId());
+                launchingActivity, taskId);
+        final int windowingMode = mController.getTaskContainer(taskId)
+                .getWindowingModeForSplitTaskFragment(primaryRectBounds);
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         mController.registerSplit(wct, primaryContainer, launchingActivity, secondaryContainer,
                 rule);
         startActivityToSide(wct, primaryContainer.getTaskFragmentToken(), primaryRectBounds,
                 launchingActivity, secondaryContainer.getTaskFragmentToken(), secondaryRectBounds,
-                activityIntent, activityOptions, rule);
+                activityIntent, activityOptions, rule, windowingMode);
+        if (isPlaceholder) {
+            // When placeholder is launched in split, we should keep the focus on the primary.
+            wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken());
+        }
         applyTransaction(wct);
 
         primaryContainer.setLastRequestedBounds(primaryRectBounds);
@@ -272,14 +287,27 @@
                 isLtr);
         final Rect secondaryRectBounds = getBoundsForPosition(POSITION_END, parentBounds, rule,
                 isLtr);
+        final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer();
+        // Whether the placeholder is becoming side-by-side with the primary from fullscreen.
+        final boolean isPlaceholderBecomingSplit = splitContainer.isPlaceholderContainer()
+                && secondaryContainer.areLastRequestedBoundsEqual(null /* bounds */)
+                && !secondaryRectBounds.isEmpty();
 
         // If the task fragments are not registered yet, the positions will be updated after they
         // are created again.
         resizeTaskFragmentIfRegistered(wct, primaryContainer, primaryRectBounds);
-        final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer();
         resizeTaskFragmentIfRegistered(wct, secondaryContainer, secondaryRectBounds);
-
         setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule);
+        if (isPlaceholderBecomingSplit) {
+            // When placeholder is shown in split, we should keep the focus on the primary.
+            wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken());
+        }
+        final TaskContainer taskContainer = mController.getTaskContainer(
+                updatedContainer.getTaskId());
+        final int windowingMode = taskContainer.getWindowingModeForSplitTaskFragment(
+                primaryRectBounds);
+        updateTaskFragmentWindowingModeIfRegistered(wct, primaryContainer, windowingMode);
+        updateTaskFragmentWindowingModeIfRegistered(wct, secondaryContainer, windowingMode);
     }
 
     private void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
@@ -311,6 +339,15 @@
         resizeTaskFragment(wct, container.getTaskFragmentToken(), bounds);
     }
 
+    private void updateTaskFragmentWindowingModeIfRegistered(
+            @NonNull WindowContainerTransaction wct,
+            @NonNull TaskFragmentContainer container,
+            @WindowingMode int windowingMode) {
+        if (container.getInfo() != null) {
+            wct.setWindowingMode(container.getInfo().getToken(), windowingMode);
+        }
+    }
+
     @Override
     void resizeTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
             @Nullable Rect bounds) {
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 be79301..3c0762d 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
@@ -16,9 +16,14 @@
 
 package androidx.window.extensions.embedding;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.content.res.Configuration;
+import android.app.WindowConfiguration;
+import android.app.WindowConfiguration.WindowingMode;
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.util.ArraySet;
@@ -37,9 +42,9 @@
     /** Available window bounds of this Task. */
     private final Rect mTaskBounds = new Rect();
 
-    /** Configuration of the Task. */
-    @Nullable
-    private Configuration mConfiguration;
+    /** Windowing mode of this Task. */
+    @WindowingMode
+    private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
 
     /** Active TaskFragments in this Task. */
     final List<TaskFragmentContainer> mContainers = new ArrayList<>();
@@ -81,13 +86,42 @@
         return !mTaskBounds.isEmpty();
     }
 
-    @Nullable
-    Configuration getConfiguration() {
-        return mConfiguration;
+    void setWindowingMode(int windowingMode) {
+        mWindowingMode = windowingMode;
     }
 
-    void setConfiguration(@Nullable Configuration configuration) {
-        mConfiguration = configuration;
+    /** Whether the Task windowing mode has been initialized. */
+    boolean isWindowingModeInitialized() {
+        return mWindowingMode != WINDOWING_MODE_UNDEFINED;
+    }
+
+    /**
+     * Returns the windowing mode for the TaskFragments below this Task, which should be split with
+     * other TaskFragments.
+     *
+     * @param taskFragmentBounds    Requested bounds for the TaskFragment. It will be empty when
+     *                              the pair of TaskFragments are stacked due to the limited space.
+     */
+    @WindowingMode
+    int getWindowingModeForSplitTaskFragment(@Nullable Rect taskFragmentBounds) {
+        // Only set to multi-windowing mode if the pair are showing side-by-side. Otherwise, it
+        // will be set to UNDEFINED which will then inherit the Task windowing mode.
+        if (taskFragmentBounds == null || taskFragmentBounds.isEmpty()) {
+            return WINDOWING_MODE_UNDEFINED;
+        }
+        // We use WINDOWING_MODE_MULTI_WINDOW when the Task is fullscreen.
+        // However, when the Task is in other multi windowing mode, such as Freeform, we need to
+        // have the activity windowing mode to match the Task, otherwise things like
+        // DecorCaptionView won't work correctly. As a result, have the TaskFragment to be in the
+        // Task windowing mode if the Task is in multi window.
+        // TODO we won't need this anymore after we migrate Freeform caption to WM Shell.
+        return WindowConfiguration.inMultiWindowMode(mWindowingMode)
+                ? mWindowingMode
+                : WINDOWING_MODE_MULTI_WINDOW;
+    }
+
+    boolean isInPictureInPicture() {
+        return mWindowingMode == WINDOWING_MODE_PINNED;
     }
 
     /** Whether there is any {@link TaskFragmentContainer} below this Task. */
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
index b06ce4c..1f12c448 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
@@ -16,15 +16,23 @@
 
 package androidx.window.extensions.embedding;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 
+import android.content.res.Configuration;
+import android.graphics.Point;
 import android.platform.test.annotations.Presubmit;
+import android.window.TaskFragmentInfo;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
@@ -35,6 +43,8 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayList;
+
 /**
  * Test class for {@link JetpackTaskFragmentOrganizer}.
  *
@@ -48,6 +58,8 @@
     private static final int TASK_ID = 10;
 
     @Mock
+    private WindowContainerTransaction mTransaction;
+    @Mock
     private JetpackTaskFragmentOrganizer.TaskFragmentCallback mCallback;
     private JetpackTaskFragmentOrganizer mOrganizer;
 
@@ -91,4 +103,24 @@
 
         verify(mOrganizer).unregisterRemoteAnimations(TASK_ID);
     }
+
+    @Test
+    public void testExpandTaskFragment() {
+        final TaskFragmentContainer container = new TaskFragmentContainer(null, TASK_ID);
+        final TaskFragmentInfo info = createMockInfo(container);
+        mOrganizer.mFragmentInfos.put(container.getTaskFragmentToken(), info);
+        container.setInfo(info);
+
+        mOrganizer.expandTaskFragment(mTransaction, container.getTaskFragmentToken());
+
+        verify(mTransaction).setWindowingMode(container.getInfo().getToken(),
+                WINDOWING_MODE_UNDEFINED);
+    }
+
+    private TaskFragmentInfo createMockInfo(TaskFragmentContainer container) {
+        return new TaskFragmentInfo(container.getTaskFragmentToken(),
+                mock(WindowContainerToken.class), new Configuration(), 0 /* runningActivityCount */,
+                false /* isVisible */, new ArrayList<>(), new Point(),
+                false /* isTaskClearedForReuse */, false /* isTaskFragmentClearedForPip */);
+    }
 }
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
index 9fb08df..c7feb7e 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
@@ -16,6 +16,13 @@
 
 package androidx.window.extensions.embedding;
 
+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_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -64,6 +71,56 @@
     }
 
     @Test
+    public void testIsWindowingModeInitialized() {
+        final TaskContainer taskContainer = new TaskContainer(TASK_ID);
+
+        assertFalse(taskContainer.isWindowingModeInitialized());
+
+        taskContainer.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        assertTrue(taskContainer.isWindowingModeInitialized());
+    }
+
+    @Test
+    public void testGetWindowingModeForSplitTaskFragment() {
+        final TaskContainer taskContainer = new TaskContainer(TASK_ID);
+        final Rect splitBounds = new Rect(0, 0, 500, 1000);
+
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW,
+                taskContainer.getWindowingModeForSplitTaskFragment(splitBounds));
+
+        taskContainer.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW,
+                taskContainer.getWindowingModeForSplitTaskFragment(splitBounds));
+
+        taskContainer.setWindowingMode(WINDOWING_MODE_FREEFORM);
+
+        assertEquals(WINDOWING_MODE_FREEFORM,
+                taskContainer.getWindowingModeForSplitTaskFragment(splitBounds));
+
+        // Empty bounds means the split pair are stacked, so it should be UNDEFINED which will then
+        // inherit the Task windowing mode
+        assertEquals(WINDOWING_MODE_UNDEFINED,
+                taskContainer.getWindowingModeForSplitTaskFragment(new Rect()));
+    }
+
+    @Test
+    public void testIsInPictureInPicture() {
+        final TaskContainer taskContainer = new TaskContainer(TASK_ID);
+
+        assertFalse(taskContainer.isInPictureInPicture());
+
+        taskContainer.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        assertFalse(taskContainer.isInPictureInPicture());
+
+        taskContainer.setWindowingMode(WINDOWING_MODE_PINNED);
+
+        assertTrue(taskContainer.isInPictureInPicture());
+    }
+
+    @Test
     public void testIsEmpty() {
         final TaskContainer taskContainer = new TaskContainer(TASK_ID);
 
diff --git a/libs/WindowManager/Shell/res/layout/split_decor.xml b/libs/WindowManager/Shell/res/layout/split_decor.xml
index dfb90af..443ecb2 100644
--- a/libs/WindowManager/Shell/res/layout/split_decor.xml
+++ b/libs/WindowManager/Shell/res/layout/split_decor.xml
@@ -20,8 +20,8 @@
     android:layout_width="match_parent">
 
     <ImageView android:id="@+id/split_resizing_icon"
-               android:layout_height="@*android:dimen/starting_surface_icon_size"
-               android:layout_width="@*android:dimen/starting_surface_icon_size"
+               android:layout_height="@dimen/split_icon_size"
+               android:layout_width="@dimen/split_icon_size"
                android:layout_gravity="center"
                android:scaleType="fitCenter"
                android:padding="0dp"
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 9749607..6f38eca 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -46,10 +46,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Superior 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string>
-    <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Usar Modo una mano"</string>
+    <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Usar modo Una mano"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para salir, desliza el dedo hacia arriba desde la parte inferior de la pantalla o toca cualquier zona que haya encima de la aplicación"</string>
-    <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar Modo una mano"</string>
-    <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Salir del Modo una mano"</string>
+    <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar modo Una mano"</string>
+    <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Salir del modo Una mano"</string>
     <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Ajustes de las burbujas de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Menú adicional"</string>
     <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Volver a añadir a la pila"</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index c21381d..1dac9ca 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -87,6 +87,8 @@
     <!-- How high we lift the divider when touching -->
     <dimen name="docked_stack_divider_lift_elevation">4dp</dimen>
 
+    <!-- Icon size for split screen -->
+    <dimen name="split_icon_size">72dp</dimen>
     <!-- Divider handle size for legacy split screen -->
     <dimen name="docked_divider_handle_width">16dp</dimen>
     <dimen name="docked_divider_handle_height">2dp</dimen>
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 cfd0624..ced36a7 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
@@ -211,7 +211,8 @@
         } else if (action == MotionEvent.ACTION_MOVE) {
             onMove(event, swipeEdge);
         } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
-            ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Finishing gesture with event: %s", event);
+            ProtoLog.d(WM_SHELL_BACK_PREVIEW,
+                    "Finishing gesture with event action: %d", action);
             onGestureFinished();
         }
     }
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 5dc6bd1..de30dbb 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
@@ -73,6 +73,8 @@
     private Rect mBounds = new Rect();
     private ValueAnimator mFadeAnimator;
 
+    private int mIconSize;
+
     public SplitDecorManager(Configuration configuration, IconProvider iconProvider,
             SurfaceSession surfaceSession) {
         super(configuration, null /* rootSurface */, null /* hostInputToken */);
@@ -104,6 +106,7 @@
         mHostLeash = rootLeash;
         mViewHost = new SurfaceControlViewHost(context, context.getDisplay(), this);
 
+        mIconSize = context.getResources().getDimensionPixelSize(R.dimen.split_icon_size);
         final FrameLayout rootLayout = (FrameLayout) LayoutInflater.from(context)
                 .inflate(R.layout.split_decor, null);
         mResizingIconView = rootLayout.findViewById(R.id.split_resizing_icon);
@@ -171,14 +174,14 @@
 
             WindowManager.LayoutParams lp =
                     (WindowManager.LayoutParams) mViewHost.getView().getLayoutParams();
-            lp.width = mIcon.getIntrinsicWidth();
-            lp.height = mIcon.getIntrinsicHeight();
+            lp.width = mIconSize;
+            lp.height = mIconSize;
             mViewHost.relayout(lp);
             t.setLayer(mIconLeash, Integer.MAX_VALUE);
         }
         t.setPosition(mIconLeash,
-                newBounds.width() / 2 - mIcon.getIntrinsicWidth() / 2,
-                newBounds.height() / 2 - mIcon.getIntrinsicWidth() / 2);
+                newBounds.width() / 2 - mIconSize / 2,
+                newBounds.height() / 2 - mIconSize / 2);
 
         boolean show = newBounds.width() > mBounds.width() || newBounds.height() > mBounds.height();
         if (show != mShown) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
index 0cea36e..28f59b5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
@@ -111,8 +111,7 @@
         mColorDrawable = new ColorDrawable();
         setBackgroundDrawable(mColorDrawable);
 
-        final int iconSize = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.starting_surface_icon_size);
+        final int iconSize = context.getResources().getDimensionPixelSize(R.dimen.split_icon_size);
         mSplashScreenView = new ImageView(context);
         mSplashScreenView.setScaleType(ImageView.ScaleType.FIT_CENTER);
         addView(mSplashScreenView,
diff --git a/core/java/com/android/internal/policy/KidsModeSettingsObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java
similarity index 98%
rename from core/java/com/android/internal/policy/KidsModeSettingsObserver.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java
index 8a1d407..f8f9d6b 100644
--- a/core/java/com/android/internal/policy/KidsModeSettingsObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.policy;
+package com.android.wm.shell.kidsmode;
 
 import android.content.ContentResolver;
 import android.content.Context;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
index 4bb5805..dc70358 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
@@ -40,7 +40,6 @@
 import androidx.annotation.NonNull;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.policy.KidsModeSettingsObserver;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayInsetsController;
@@ -225,6 +224,10 @@
 
     @VisibleForTesting
     void enable() {
+        // Needed since many Kids apps aren't optimised to support both orientations and it will be
+        // hard for kids to understand the app compat mode.
+        // TODO(229961548): Remove ignoreOrientationRequest exception for Kids Mode once possible.
+        setIsIgnoreOrientationRequestDisabled(true);
         final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(DEFAULT_DISPLAY);
         if (displayLayout != null) {
             mDisplayWidth = displayLayout.width();
@@ -245,6 +248,7 @@
 
     @VisibleForTesting
     void disable() {
+        setIsIgnoreOrientationRequestDisabled(false);
         mDisplayInsetsController.removeInsetsChangedListener(DEFAULT_DISPLAY,
                 mOnInsetsChangedListener);
         mDisplayController.removeDisplayWindowListener(mOnDisplaysChangedListener);
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 5d17f85b..195923c 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
@@ -225,6 +225,12 @@
         // For transition that we don't animate, but contains the PIP leash, we need to update the
         // PIP surface, otherwise it will be reset after the transition.
         if (currentPipTaskChange != null) {
+            // Set the "end" bounds of pip. The default setup uses the start bounds. Since this is
+            // changing the *finish*Transaction, we need to use the end bounds. This will also
+            // make sure that the fade-in animation (below) uses the end bounds as well.
+            if (!currentPipTaskChange.getEndAbsBounds().isEmpty()) {
+                mPipBoundsState.setBounds(currentPipTaskChange.getEndAbsBounds());
+            }
             updatePipForUnhandledTransition(currentPipTaskChange, startTransaction,
                     finishTransaction);
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 272331b..cc387ed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -524,24 +524,44 @@
             mMenuController.attachPipMenuView();
             // Calculate the snap fraction of the current stack along the old movement bounds
             final PipSnapAlgorithm pipSnapAlgorithm = mPipBoundsAlgorithm.getSnapAlgorithm();
-            final Rect postChangeStackBounds = new Rect(mPipBoundsState.getBounds());
-            final float snapFraction = pipSnapAlgorithm.getSnapFraction(postChangeStackBounds,
-                    mPipBoundsAlgorithm.getMovementBounds(postChangeStackBounds),
+            final Rect postChangeBounds = new Rect(mPipBoundsState.getBounds());
+            final float snapFraction = pipSnapAlgorithm.getSnapFraction(postChangeBounds,
+                    mPipBoundsAlgorithm.getMovementBounds(postChangeBounds),
                     mPipBoundsState.getStashedState());
 
+            // Scale PiP on density dpi change, so it appears to be the same size physically.
+            final boolean densityDpiChanged = mPipBoundsState.getDisplayLayout().densityDpi() != 0
+                    && (mPipBoundsState.getDisplayLayout().densityDpi() != layout.densityDpi());
+            if (densityDpiChanged) {
+                final float scale = (float) layout.densityDpi()
+                        / mPipBoundsState.getDisplayLayout().densityDpi();
+                postChangeBounds.set(0, 0,
+                        (int) (postChangeBounds.width() * scale),
+                        (int) (postChangeBounds.height() * scale));
+            }
+
             updateDisplayLayout.run();
 
-            // Calculate the stack bounds in the new orientation based on same fraction along the
+            // Calculate the PiP bounds in the new orientation based on same fraction along the
             // rotated movement bounds.
             final Rect postChangeMovementBounds = mPipBoundsAlgorithm.getMovementBounds(
-                    postChangeStackBounds, false /* adjustForIme */);
-            pipSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
+                    postChangeBounds, false /* adjustForIme */);
+            pipSnapAlgorithm.applySnapFraction(postChangeBounds, postChangeMovementBounds,
                     snapFraction, mPipBoundsState.getStashedState(),
                     mPipBoundsState.getStashOffset(),
                     mPipBoundsState.getDisplayBounds(),
                     mPipBoundsState.getDisplayLayout().stableInsets());
 
-            mTouchHandler.getMotionHelper().movePip(postChangeStackBounds);
+            if (densityDpiChanged) {
+                // Using PipMotionHelper#movePip directly here may cause race condition since
+                // the app content in PiP mode may or may not be updated for the new density dpi.
+                final int duration = mContext.getResources().getInteger(
+                        R.integer.config_pipEnterAnimationDuration);
+                mPipTaskOrganizer.scheduleAnimateResizePip(
+                        postChangeBounds, duration, null /* updateBoundsCallback */);
+            } else {
+                mTouchHandler.getMotionHelper().movePip(postChangeBounds);
+            }
         } else {
             updateDisplayLayout.run();
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
index 09d202a..07dccd5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
@@ -131,10 +131,10 @@
 
         val pipSizeWithAllDecors = addDecors(pipSize)
         val pipAnchorBoundsWithAllDecors =
-                getNormalPipAnchorBounds(pipSizeWithAllDecors, transformedMovementBounds)
+            getNormalPipAnchorBounds(pipSizeWithAllDecors, transformedMovementBounds)
 
         val pipAnchorBoundsWithPermanentDecors =
-                removeTemporaryDecorsTransformed(pipAnchorBoundsWithAllDecors)
+            removeTemporaryDecorsTransformed(pipAnchorBoundsWithAllDecors)
         val result = calculatePipPositionTransformed(
             pipAnchorBoundsWithPermanentDecors,
             transformedRestrictedAreas,
@@ -150,7 +150,7 @@
         return Placement(
             pipBounds,
             anchorBounds,
-            getStashType(pipBounds, movementBounds),
+            getStashType(pipBounds, unstashedDestBounds),
             unstashedDestBounds,
             result.unstashTime
         )
@@ -185,7 +185,10 @@
         restrictedAreas: Set<Rect>,
         unrestrictedAreas: Set<Rect>
     ): Placement {
-        if (restrictedAreas.isEmpty() && unrestrictedAreas.isEmpty()) {
+        // If PiP is not covered by any keep clear areas, we can leave it at the anchor bounds
+        val keepClearAreas = restrictedAreas + unrestrictedAreas
+        if (keepClearAreas.none { it.intersects(pipAnchorBounds) }) {
+            lastAreasOverlappingUnstashPosition = emptySet()
             return Placement(pipAnchorBounds, pipAnchorBounds)
         }
 
@@ -204,9 +207,8 @@
                 ?: findFreeMovePosition(pipAnchorBounds, emptySet(), unrestrictedAreas)
                 ?: pipAnchorBounds
 
-        val keepClearAreas = restrictedAreas + unrestrictedAreas
         val areasOverlappingUnstashPosition =
-            keepClearAreas.filter { Rect.intersects(it, unstashBounds) }.toSet()
+            keepClearAreas.filterTo(mutableSetOf()) { it.intersects(unstashBounds) }
         val areasOverlappingUnstashPositionChanged =
             !lastAreasOverlappingUnstashPosition.containsAll(areasOverlappingUnstashPosition)
         lastAreasOverlappingUnstashPosition = areasOverlappingUnstashPosition
@@ -228,19 +230,22 @@
         return Placement(
             stashedBounds,
             pipAnchorBounds,
-            getStashType(stashedBounds, transformedMovementBounds),
+            getStashType(stashedBounds, unstashBounds),
             unstashBounds,
             unstashTime
         )
     }
 
     @PipBoundsState.StashType
-    private fun getStashType(stashedBounds: Rect, movementBounds: Rect): Int {
+    private fun getStashType(stashedBounds: Rect, unstashedDestBounds: Rect?): Int {
+        if (unstashedDestBounds == null) {
+            return STASH_TYPE_NONE
+        }
         return when {
-            stashedBounds.left < movementBounds.left -> STASH_TYPE_LEFT
-            stashedBounds.right > movementBounds.right -> STASH_TYPE_RIGHT
-            stashedBounds.top < movementBounds.top -> STASH_TYPE_TOP
-            stashedBounds.bottom > movementBounds.bottom -> STASH_TYPE_BOTTOM
+            stashedBounds.left < unstashedDestBounds.left -> STASH_TYPE_LEFT
+            stashedBounds.right > unstashedDestBounds.right -> STASH_TYPE_RIGHT
+            stashedBounds.top < unstashedDestBounds.top -> STASH_TYPE_TOP
+            stashedBounds.bottom > unstashedDestBounds.bottom -> STASH_TYPE_BOTTOM
             else -> STASH_TYPE_NONE
         }
     }
@@ -368,57 +373,69 @@
         val areasOverlappingPipX = keepClearAreas.filter { it.intersectsX(bounds) }
         val areasOverlappingPipY = keepClearAreas.filter { it.intersectsY(bounds) }
 
-        if (screenBounds.bottom - bounds.bottom <= bounds.top - screenBounds.top) {
-            val fullStashTop = screenBounds.bottom - stashOffset
+        if (areasOverlappingPipX.isNotEmpty()) {
+            if (screenBounds.bottom - bounds.bottom <= bounds.top - screenBounds.top) {
+                val fullStashTop = screenBounds.bottom - stashOffset
 
-            val maxBottom = areasOverlappingPipX.maxByOrNull { it.bottom }!!.bottom
-            val partialStashTop = maxBottom + pipAreaPadding
+                val maxBottom = areasOverlappingPipX.maxByOrNull { it.bottom }!!.bottom
+                val partialStashTop = maxBottom + pipAreaPadding
 
-            val downPosition = Rect(bounds)
-            downPosition.offsetTo(bounds.left, min(fullStashTop, partialStashTop))
-            stashCandidates += downPosition
-        }
-        if (screenBounds.bottom - bounds.bottom >= bounds.top - screenBounds.top) {
-            val fullStashBottom = screenBounds.top - bounds.height() + stashOffset
+                val newTop = min(fullStashTop, partialStashTop)
+                if (newTop > bounds.top) {
+                    val downPosition = Rect(bounds)
+                    downPosition.offsetTo(bounds.left, newTop)
+                    stashCandidates += downPosition
+                }
+            }
+            if (screenBounds.bottom - bounds.bottom >= bounds.top - screenBounds.top) {
+                val fullStashBottom = screenBounds.top - bounds.height() + stashOffset
 
-            val minTop = areasOverlappingPipX.minByOrNull { it.top }!!.top
-            val partialStashBottom = minTop - bounds.height() - pipAreaPadding
+                val minTop = areasOverlappingPipX.minByOrNull { it.top }!!.top
+                val partialStashBottom = minTop - bounds.height() - pipAreaPadding
 
-            val upPosition = Rect(bounds)
-            upPosition.offsetTo(bounds.left, max(fullStashBottom, partialStashBottom))
-            stashCandidates += upPosition
+                val newTop = max(fullStashBottom, partialStashBottom)
+                if (newTop < bounds.top) {
+                    val upPosition = Rect(bounds)
+                    upPosition.offsetTo(bounds.left, newTop)
+                    stashCandidates += upPosition
+                }
+            }
         }
 
-        if (screenBounds.right - bounds.right <= bounds.left - screenBounds.left) {
-            val fullStashRight = screenBounds.right - stashOffset
+        if (areasOverlappingPipY.isNotEmpty()) {
+            if (screenBounds.right - bounds.right <= bounds.left - screenBounds.left) {
+                val fullStashRight = screenBounds.right - stashOffset
 
-            val maxRight = areasOverlappingPipY.maxByOrNull { it.right }!!.right
-            val partialStashRight = maxRight + pipAreaPadding
+                val maxRight = areasOverlappingPipY.maxByOrNull { it.right }!!.right
+                val partialStashRight = maxRight + pipAreaPadding
 
-            val rightPosition = Rect(bounds)
-            rightPosition.offsetTo(min(fullStashRight, partialStashRight), bounds.top)
-            stashCandidates += rightPosition
-        }
-        if (screenBounds.right - bounds.right >= bounds.left - screenBounds.left) {
-            val fullStashLeft = screenBounds.left - bounds.width() + stashOffset
+                val newLeft = min(fullStashRight, partialStashRight)
+                if (newLeft > bounds.left) {
+                    val rightPosition = Rect(bounds)
+                    rightPosition.offsetTo(newLeft, bounds.top)
+                    stashCandidates += rightPosition
+                }
+            }
+            if (screenBounds.right - bounds.right >= bounds.left - screenBounds.left) {
+                val fullStashLeft = screenBounds.left - bounds.width() + stashOffset
 
-            val minLeft = areasOverlappingPipY.minByOrNull { it.left }!!.left
-            val partialStashLeft = minLeft - bounds.width() - pipAreaPadding
+                val minLeft = areasOverlappingPipY.minByOrNull { it.left }!!.left
+                val partialStashLeft = minLeft - bounds.width() - pipAreaPadding
 
-            val leftPosition = Rect(bounds)
-            leftPosition.offsetTo(max(fullStashLeft, partialStashLeft), bounds.top)
-            stashCandidates += leftPosition
-        }
-
-        if (stashCandidates.isEmpty()) {
-            return bounds
+                val newLeft = max(fullStashLeft, partialStashLeft)
+                if (newLeft < bounds.left) {
+                    val leftPosition = Rect(bounds)
+                    leftPosition.offsetTo(newLeft, bounds.top)
+                    stashCandidates += leftPosition
+                }
+            }
         }
 
         return stashCandidates.minByOrNull {
             val dx = abs(it.left - bounds.left)
             val dy = abs(it.top - bounds.top)
             return@minByOrNull dx + dy
-        }!!
+        } ?: bounds
     }
 
     /**
@@ -768,7 +785,7 @@
     }
 
     /**
-     * Adds space around [size] to leave space for decorations that will be drawn around the pip
+     * Adds space around [size] to leave space for decorations that will be drawn around the PiP
      */
     private fun addDecors(size: Size): Size {
         val bounds = Rect(0, 0, size.width, size.height)
@@ -779,7 +796,7 @@
     }
 
     /**
-     * Removes the space that was reserved for permanent decorations around the pip
+     * Removes the space that was reserved for permanent decorations around the PiP
      * @param bounds the bounds (in screen space) to remove the insets from
      */
     private fun removePermanentDecors(bounds: Rect): Rect {
@@ -789,19 +806,20 @@
     }
 
     /**
-     * Removes the space that was reserved for temporary decorations around the pip
+     * Removes the space that was reserved for temporary decorations around the PiP
      * @param bounds the bounds (in base case) to remove the insets from
      */
     private fun removeTemporaryDecorsTransformed(bounds: Rect): Rect {
         if (pipTemporaryDecorInsets == Insets.NONE) return bounds
 
-        var reverseInsets = Insets.subtract(Insets.NONE, pipTemporaryDecorInsets)
-        var boundsInScreenSpace = fromTransformedSpace(bounds)
+        val reverseInsets = Insets.subtract(Insets.NONE, pipTemporaryDecorInsets)
+        val boundsInScreenSpace = fromTransformedSpace(bounds)
         boundsInScreenSpace.inset(reverseInsets)
         return toTransformedSpace(boundsInScreenSpace)
     }
 
     private fun Rect.offsetCopy(dx: Int, dy: Int) = Rect(this).apply { offset(dx, dy) }
-    private fun Rect.intersectsY(other: Rect) = bottom >= other.top && top <= other.bottom
     private fun Rect.intersectsX(other: Rect) = right >= other.left && left <= other.right
+    private fun Rect.intersectsY(other: Rect) = bottom >= other.top && top <= other.bottom
+    private fun Rect.intersects(other: Rect) = intersectsX(other) && intersectsY(other)
 }
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 05a240a..06f7eda 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
@@ -1827,15 +1827,17 @@
         @Override
         public void onNoLongerSupportMultiWindow() {
             if (mMainStage.isActive()) {
+                final boolean isMainStage = mMainStageListener == this;
                 if (!ENABLE_SHELL_TRANSITIONS) {
-                    StageCoordinator.this.exitSplitScreen(null /* childrenToTop */,
+                    StageCoordinator.this.exitSplitScreen(isMainStage ? mMainStage : mSideStage,
                             EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW);
+                    return;
                 }
 
+                final int stageType = isMainStage ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
                 final WindowContainerTransaction wct = new WindowContainerTransaction();
-                prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, wct);
-                mSplitTransitions.startDismissTransition(wct,
-                        StageCoordinator.this, STAGE_TYPE_UNDEFINED,
+                prepareExitSplitScreen(stageType, wct);
+                mSplitTransitions.startDismissTransition(wct,StageCoordinator.this, stageType,
                         EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW);
             }
         }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
index 37e93443..c6a705d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
@@ -80,7 +80,17 @@
     /** {@inheritDoc}  */
     @FlakyTest(bugId = 206753786)
     @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
+    override fun statusBarLayerRotatesScales() {
+        Assume.assumeFalse(isShellTransitionsEnabled)
+        super.statusBarLayerRotatesScales()
+    }
+
+    @Presubmit
+    @Test
+    fun statusBarLayerRotatesScales_ShellTransit() {
+        Assume.assumeTrue(isShellTransitionsEnabled)
+        super.statusBarLayerRotatesScales()
+    }
 
     /** {@inheritDoc}  */
     @FlakyTest(bugId = 197726610)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
index 1a21d32..fe51228 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
@@ -16,7 +16,7 @@
 
 package com.android.wm.shell.flicker.pip
 
-import androidx.test.filters.FlakyTest
+import android.platform.test.annotations.Presubmit
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -35,7 +35,6 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group4
-@FlakyTest(bugId = 217777115)
 class PipKeyboardTestShellTransit(testSpec: FlickerTestParameter) : PipKeyboardTest(testSpec) {
 
     @Before
@@ -43,7 +42,7 @@
         Assume.assumeTrue(isShellTransitionsEnabled)
     }
 
-    @FlakyTest(bugId = 214452854)
+    @Presubmit
     @Test
     override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index c1ee1a7..4618fb3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -27,12 +27,10 @@
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.navBarLayerRotatesAndScales
 import com.android.server.wm.flicker.statusBarLayerRotatesScales
 import com.android.wm.shell.flicker.helpers.FixedAppHelper
-import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -141,14 +139,6 @@
     @Presubmit
     @Test
     fun pipLayerRotates_StartingBounds() {
-        Assume.assumeFalse(isShellTransitionsEnabled)
-        pipLayerRotates_StartingBounds_internal()
-    }
-
-    @FlakyTest(bugId = 228024285)
-    @Test
-    fun pipLayerRotates_StartingBounds_ShellTransit() {
-        Assume.assumeTrue(isShellTransitionsEnabled)
         pipLayerRotates_StartingBounds_internal()
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
index 5526d5b..440a6f8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
@@ -44,7 +44,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.policy.KidsModeSettingsObserver;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.ShellExecutor;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt
index 9919214..46f388d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt
@@ -25,6 +25,7 @@
 import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE
 import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_BOTTOM
 import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT
+import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_TOP
 import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement
 import org.junit.Before
 import org.junit.Test
@@ -434,6 +435,28 @@
     }
 
     @Test
+    fun test_ExpandedPiPHeightExceedsMovementBounds_AtAnchor() {
+        gravity = Gravity.RIGHT or Gravity.CENTER_VERTICAL
+        pipSize = Size(DEFAULT_PIP_SIZE.width, SCREEN_SIZE.height)
+        testAnchorPosition()
+    }
+
+    @Test
+    fun test_ExpandedPiPHeightExceedsMovementBounds_BottomBar_StashedUp() {
+        gravity = Gravity.RIGHT or Gravity.CENTER_VERTICAL
+        pipSize = Size(DEFAULT_PIP_SIZE.width, SCREEN_SIZE.height)
+        val bottomBar = makeBottomBar(96)
+        unrestrictedAreas.add(bottomBar)
+
+        val expectedBounds = getExpectedAnchorBounds()
+        expectedBounds.offset(0, -bottomBar.height() - PADDING)
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertEquals(STASH_TYPE_TOP, placement.stashType)
+        assertEquals(getExpectedAnchorBounds(), placement.unstashDestinationBounds)
+    }
+
+    @Test
     fun test_PipInsets() {
         val permInsets = Insets.of(-1, -2, -3, -4)
         algorithm.setPipPermanentDecorInsets(permInsets)
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 4713c5d..9bf0b78 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -24,7 +24,7 @@
     <string name="summary_watch" product="tablet" msgid="7113724443198337683">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> θα επιτρέπεται να αλληλεπιδρά με τις ειδοποιήσεις σας και να έχει πρόσβαση στις άδειες Τηλεφώνου, SMS, Επαφών και Ημερολογίου."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Εφαρμογές"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Μεταδώστε σε ροή τις εφαρμογές του τηλεφώνου σας"</string>
-    <string name="title_app_streaming" msgid="2270331024626446950">"Να επιτρέπεται στην εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; η πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας."</string>
+    <string name="title_app_streaming" msgid="2270331024626446950">"Να επιτρέπεται στο &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; η πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας."</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Υπηρεσίες πολλών συσκευών"</string>
     <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις του τηλεφώνου σας"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index ce58ff6..4c313b2 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -61,6 +61,7 @@
 import java.io.PrintWriter;
 import java.util.Collections;
 import java.util.List;
+import java.util.Locale;
 import java.util.Objects;
 import java.util.UUID;
 
@@ -318,13 +319,19 @@
             }
 
             // Block Download folder from tree
-            if (TextUtils.equals(Environment.DIRECTORY_DOWNLOADS.toLowerCase(),
-                    path.toLowerCase())) {
+            if (TextUtils.equals(Environment.DIRECTORY_DOWNLOADS.toLowerCase(Locale.ROOT),
+                    path.toLowerCase(Locale.ROOT))) {
                 return true;
             }
 
-            if (TextUtils.equals(Environment.DIRECTORY_ANDROID.toLowerCase(),
-                    path.toLowerCase())) {
+            // Block /Android
+            if (TextUtils.equals(Environment.DIRECTORY_ANDROID.toLowerCase(Locale.ROOT),
+                    path.toLowerCase(Locale.ROOT))) {
+                return true;
+            }
+
+            // Block /Android/data, /Android/obb, /Android/sandbox and sub dirs
+            if (shouldHide(dir)) {
                 return true;
             }
 
@@ -420,19 +427,21 @@
     }
 
     @VisibleForTesting
-    static String getPathFromDocId(String docId) {
+    static String getPathFromDocId(String docId) throws IOException {
         final int splitIndex = docId.indexOf(':', 1);
-        final String path = docId.substring(splitIndex + 1);
+        final String docIdPath = docId.substring(splitIndex + 1);
+        // Get CanonicalPath and remove the first "/"
+        final String canonicalPath = new File(docIdPath).getCanonicalPath().substring(1);
 
-        if (path.isEmpty()) {
-            return path;
+        if (canonicalPath.isEmpty()) {
+            return canonicalPath;
         }
 
         // remove trailing "/"
-        if (path.charAt(path.length() - 1) == '/') {
-            return path.substring(0, path.length() - 1);
+        if (canonicalPath.charAt(canonicalPath.length() - 1) == '/') {
+            return canonicalPath.substring(0, canonicalPath.length() - 1);
         } else {
-            return path;
+            return canonicalPath;
         }
     }
 
@@ -463,7 +472,12 @@
         if (!target.exists()) {
             target.mkdirs();
         }
-        target = new File(target, path);
+        try {
+            target = new File(target, path).getCanonicalFile();
+        } catch (IOException e) {
+            throw new FileNotFoundException("Failed to canonicalize path " + path);
+        }
+
         if (mustExist && !target.exists()) {
             throw new FileNotFoundException("Missing file for " + docId + " at " + target);
         }
diff --git a/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java b/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java
index ed8320f..18a8edc 100644
--- a/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java
+++ b/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java
@@ -67,5 +67,16 @@
 
         docId = root + ":";
         assertTrue(getPathFromDocId(docId).isEmpty());
+
+        docId = root + ":./" + path;
+        assertEquals(getPathFromDocId(docId), path);
+
+        final String dotPath = "abc/./def/ghi";
+        docId = root + ":" + dotPath;
+        assertEquals(getPathFromDocId(docId), path);
+
+        final String twoDotPath = "abc/../abc/def/ghi";
+        docId = root + ":" + twoDotPath;
+        assertEquals(getPathFromDocId(docId), path);
     }
 }
diff --git a/packages/PackageInstaller/res/values-et/strings.xml b/packages/PackageInstaller/res/values-et/strings.xml
index 0138219..2324806 100644
--- a/packages/PackageInstaller/res/values-et/strings.xml
+++ b/packages/PackageInstaller/res/values-et/strings.xml
@@ -65,7 +65,7 @@
     <string name="uninstalling" msgid="8709566347688966845">"Desinstallimine …"</string>
     <string name="uninstalling_app" msgid="8866082646836981397">"Paketi <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine …"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Desinstallimine on lõpetatud."</string>
-    <string name="uninstall_done_app" msgid="4588850984473605768">"Üksus <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on desinstallitud"</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on desinstallitud"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Desinstallimine ebaõnnestus."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine ebaõnnestus."</string>
     <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Aktiivset seadme administraatori rakendust ei saa desinstallida"</string>
diff --git a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
index 5f0322f..07615ae 100644
--- a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
+++ b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
@@ -66,7 +66,7 @@
     <string name="notification_channel_failure" msgid="9042250774797916414">"Neuspeli zadaci štampanja"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"Pravljenje datoteke nije uspelo"</string>
     <string name="print_services_disabled_toast" msgid="9089060734685174685">"Neke usluge štampanja su onemogućene"</string>
-    <string name="print_searching_for_printers" msgid="6550424555079932867">"Pretraga štampača"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Traženje štampača"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Nijedna usluga štampanja nije omogućena"</string>
     <string name="print_no_printers" msgid="4869403323900054866">"Nije pronađen nijedan štampač"</string>
     <string name="cannot_add_printer" msgid="7840348733668023106">"Nije moguće dodati štampače"</string>
diff --git a/packages/PrintSpooler/res/values-it/strings.xml b/packages/PrintSpooler/res/values-it/strings.xml
index d898b1e..96751ea 100644
--- a/packages/PrintSpooler/res/values-it/strings.xml
+++ b/packages/PrintSpooler/res/values-it/strings.xml
@@ -65,7 +65,7 @@
     <string name="notification_channel_failure" msgid="9042250774797916414">"Processi di stampa non riusciti"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"Impossibile creare il file"</string>
     <string name="print_services_disabled_toast" msgid="9089060734685174685">"Alcuni servizi di stampa sono disattivati"</string>
-    <string name="print_searching_for_printers" msgid="6550424555079932867">"Ricerca di stampanti"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Ricerca di stampanti..."</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Non è stato attivato alcun servizio di stampa"</string>
     <string name="print_no_printers" msgid="4869403323900054866">"Nessuna stampante trovata"</string>
     <string name="cannot_add_printer" msgid="7840348733668023106">"Impossibile aggiungere stampanti"</string>
diff --git a/packages/PrintSpooler/res/values-mk/strings.xml b/packages/PrintSpooler/res/values-mk/strings.xml
index 3fd32b1..d96330c 100644
--- a/packages/PrintSpooler/res/values-mk/strings.xml
+++ b/packages/PrintSpooler/res/values-mk/strings.xml
@@ -52,7 +52,7 @@
     <string name="add_print_service_label" msgid="5356702546188981940">"Додајте услуга"</string>
     <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Полето за пребарување е прикажано"</string>
     <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Полето за пребарување е скриено"</string>
-    <string name="print_add_printer" msgid="1088656468360653455">"Додај печатач"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Додајте печатач"</string>
     <string name="print_select_printer" msgid="7388760939873368698">"Избери печатач"</string>
     <string name="print_forget_printer" msgid="5035287497291910766">"Заборави го печатачот"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml
index c2f99d9..bc29999 100644
--- a/packages/PrintSpooler/res/values-sr/strings.xml
+++ b/packages/PrintSpooler/res/values-sr/strings.xml
@@ -66,7 +66,7 @@
     <string name="notification_channel_failure" msgid="9042250774797916414">"Неуспели задаци штампања"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"Прављење датотеке није успело"</string>
     <string name="print_services_disabled_toast" msgid="9089060734685174685">"Неке услуге штампања су онемогућене"</string>
-    <string name="print_searching_for_printers" msgid="6550424555079932867">"Претрага штампача"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Тражење штампача"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Ниједна услуга штампања није омогућена"</string>
     <string name="print_no_printers" msgid="4869403323900054866">"Није пронађен ниједан штампач"</string>
     <string name="cannot_add_printer" msgid="7840348733668023106">"Није могуће додати штампаче"</string>
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
index 7c9a045..fc0e05f 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
@@ -122,9 +122,10 @@
      * Adds a listener for switch changes
      */
     public void addOnSwitchChangeListener(OnMainSwitchChangeListener listener) {
-        if (mMainSwitchBar == null) {
+        if (!mSwitchChangeListeners.contains(listener)) {
             mSwitchChangeListeners.add(listener);
-        } else {
+        }
+        if (mMainSwitchBar != null) {
             mMainSwitchBar.addOnSwitchChangeListener(listener);
         }
     }
@@ -133,9 +134,8 @@
      * Remove a listener for switch changes
      */
     public void removeOnSwitchChangeListener(OnMainSwitchChangeListener listener) {
-        if (mMainSwitchBar == null) {
-            mSwitchChangeListeners.remove(listener);
-        } else {
+        mSwitchChangeListeners.remove(listener);
+        if (mMainSwitchBar != null) {
             mMainSwitchBar.removeOnSwitchChangeListener(listener);
         }
     }
diff --git a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/WorkPolicyUtils.java b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/WorkPolicyUtils.java
new file mode 100644
index 0000000..b038d59
--- /dev/null
+++ b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/WorkPolicyUtils.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.utils;
+
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import java.util.List;
+
+/**
+ * Utility class for find out when to show WorkPolicyInfo
+ */
+public class WorkPolicyUtils {
+
+    Context mContext;
+    PackageManager mPackageManager;
+    UserManager mUserManager;
+    DevicePolicyManager mDevicePolicyManager;
+
+    private static final int USER_NULL = -10000;
+
+    public WorkPolicyUtils(
+            Context applicationContext,
+            PackageManager mPm,
+            UserManager mUm,
+            DevicePolicyManager mDpm
+    ) {
+        mContext = applicationContext;
+        mPackageManager = mPm;
+        mUserManager = mUm;
+        mDevicePolicyManager = mDpm;
+    }
+
+    /**
+     * Returns {@code true} if it is possilbe to resolve an Intent to launch the "Your work policy
+     * info" page provided by the active Device Owner or Profile Owner app if it exists, {@code
+     * false} otherwise.
+     */
+    public boolean hasWorkPolicy() {
+        return getWorkPolicyInfoIntentDO() != null || getWorkPolicyInfoIntentPO() != null;
+    }
+
+    /**
+     * Launches the Device Owner or Profile Owner's activity that displays the "Your work policy
+     * info" page. Returns {@code true} if the activity has indeed been launched.
+     */
+    public boolean showWorkPolicyInfo(Context activityContext) {
+        Intent intent = getWorkPolicyInfoIntentDO();
+        if (intent != null) {
+            activityContext.startActivity(intent);
+            return true;
+        }
+
+        intent = getWorkPolicyInfoIntentPO();
+        final int userId = getManagedProfileUserId();
+        if (intent != null && userId != USER_NULL) {
+            activityContext.startActivityAsUser(intent, UserHandle.of(userId));
+            return true;
+        }
+
+        return false;
+    }
+
+    private Intent getWorkPolicyInfoIntentDO() {
+        final ComponentName ownerComponent = getDeviceOwnerComponent();
+        if (ownerComponent == null) {
+            return null;
+        }
+
+        // Only search for the required action in the Device Owner's package
+        final Intent intent =
+                new Intent(Settings.ACTION_SHOW_WORK_POLICY_INFO)
+                        .setPackage(ownerComponent.getPackageName());
+        final List<ResolveInfo> activities = mPackageManager.queryIntentActivities(intent, 0);
+        if (activities.size() != 0) {
+            return intent;
+        }
+
+        return null;
+    }
+
+    private Intent getWorkPolicyInfoIntentPO() {
+        try {
+            final int managedUserId = getManagedProfileUserId();
+            if (managedUserId == USER_NULL) {
+                return null;
+            }
+
+            Context managedProfileContext =
+                    mContext.createPackageContextAsUser(
+                            mContext.getPackageName(), 0, UserHandle.of(managedUserId)
+                    );
+
+            DevicePolicyManager managedProfileDevicePolicyManager =
+                    (DevicePolicyManager)
+                            managedProfileContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+            ComponentName ownerComponent = managedProfileDevicePolicyManager.getProfileOwner();
+            if (ownerComponent == null) {
+                return null;
+            }
+
+            // Only search for the required action in the Profile Owner's package
+            final Intent intent =
+                    new Intent(Settings.ACTION_SHOW_WORK_POLICY_INFO)
+                            .setPackage(ownerComponent.getPackageName());
+            final List<ResolveInfo> activities =
+                    mPackageManager.queryIntentActivitiesAsUser(
+                            intent, 0, UserHandle.of(managedUserId));
+            if (activities.size() != 0) {
+                return intent;
+            }
+
+            return null;
+        } catch (PackageManager.NameNotFoundException e) {
+            return null;
+        }
+    }
+
+    private ComponentName getDeviceOwnerComponent() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
+            return null;
+        }
+        return mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser();
+    }
+
+    private int getManagedProfileUserId() {
+        List<UserHandle> allProfiles = mUserManager.getAllProfiles();
+        for (UserHandle uh : allProfiles) {
+            int id = uh.getIdentifier();
+            if (mUserManager.isManagedProfile(id)) {
+                return id;
+            }
+        }
+        return USER_NULL;
+    }
+
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index 091e322..bdeb474 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -230,7 +230,9 @@
         final int mode = mAppOpsManager.noteOpNoThrow(
                 AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
                 uid, packageName);
-        final boolean appOpsAllowed = mode == AppOpsManager.MODE_ALLOWED;
+        final boolean ecmEnabled = getContext().getResources().getBoolean(
+                com.android.internal.R.bool.config_enhancedConfirmationModeEnabled);
+        final boolean appOpsAllowed = !ecmEnabled || mode == AppOpsManager.MODE_ALLOWED;
         if (appOpsAllowed || isEnabled) {
             setEnabled(true);
         } else {
diff --git a/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationUtils.java b/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationUtils.java
index 43ec1e2..d194695 100644
--- a/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationUtils.java
@@ -181,10 +181,12 @@
     public void createAnimation(final View view, long delay, long duration, float translationY,
             boolean appearing, Interpolator interpolator, final Runnable endRunnable) {
         if (view != null) {
-            view.setAlpha(appearing ? 0f : 1.0f);
-            view.setTranslationY(appearing ? translationY : 0);
+            float targetAlpha = appearing ? 1f : 0f;
+            float targetTranslationY = appearing ? 0 : translationY;
+            view.setAlpha(1.0f - targetAlpha);
+            view.setTranslationY(translationY - targetTranslationY);
             Animator alphaAnim;
-            float targetAlpha =  appearing ? 1f : 0f;
+
             if (view.isHardwareAccelerated()) {
                 RenderNodeAnimator alphaAnimRt = new RenderNodeAnimator(RenderNodeAnimator.ALPHA,
                         targetAlpha);
@@ -205,14 +207,21 @@
                     }
                 });
             }
-            if (endRunnable != null) {
-                alphaAnim.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
+            alphaAnim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    // If Animation is canceled, we want to ensure UI is reset.
+                    view.setAlpha(targetAlpha);
+                    view.setTranslationY(targetTranslationY);
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (endRunnable != null) {
                         endRunnable.run();
                     }
-                });
-            }
+                }
+            });
             alphaAnim.start();
             startTranslationYAnimation(view, delay, duration, appearing ? 0 : translationY,
                     interpolator);
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index 2fb534d..440a544 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -250,6 +250,15 @@
     }
 
     /**
+     * Check if the device is Bluetooth LE Audio device.
+     *
+     * @return true if the RouteInfo equals TYPE_BLE_HEADSET.
+     */
+    public boolean isBLEDevice() {
+        return mRouteInfo.getType() == TYPE_BLE_HEADSET;
+    }
+
+    /**
      * Get application label from MediaDevice.
      *
      * @return application label.
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiPermissionChecker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiPermissionChecker.java
new file mode 100644
index 0000000..2fe6e46
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiPermissionChecker.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.wifi;
+
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+import static android.Manifest.permission.ACCESS_WIFI_STATE;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.IActivityManager;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Helper class to check Wi-Fi permissions.
+ */
+public class WifiPermissionChecker {
+
+    private static final String TAG = "WifiPermChecker";
+
+    private IActivityManager mActivityManager;
+    private PackageManager mPackageManager;
+    private String mLaunchedPackage;
+
+    public WifiPermissionChecker(Activity activity) {
+        this(activity, ActivityManager.getService());
+    }
+
+    public WifiPermissionChecker(Activity activity, IActivityManager activityManager) {
+        mActivityManager = activityManager;
+        mPackageManager = activity.getPackageManager();
+        mLaunchedPackage = getLaunchedFromPackage(activity);
+    }
+
+    /**
+     * Returns the launched package name
+     */
+    public String getLaunchedPackage() {
+        return mLaunchedPackage;
+    }
+
+    /**
+     * Returns whether the launched package can access Wi-Fi information
+     */
+    public boolean canAccessWifiState() {
+        return checkPermission(ACCESS_WIFI_STATE);
+    }
+
+    /**
+     * Returns whether the launched package can access precise location
+     */
+    public boolean canAccessFineLocation() {
+        return checkPermission(ACCESS_FINE_LOCATION);
+    }
+
+    private boolean checkPermission(String permission) {
+        if (mPackageManager == null || TextUtils.isEmpty(mLaunchedPackage)) {
+            Log.e(TAG, "Failed to check package permission!"
+                    + " {PackageManager:" + mPackageManager
+                    + ", LaunchedPackage:" + mLaunchedPackage + "}");
+            return false;
+        }
+
+        if (mPackageManager.checkPermission(permission, mLaunchedPackage) == PERMISSION_GRANTED) {
+            return true;
+        }
+
+        Log.w(TAG, "The launched package does not have the required permission!"
+                + " {LaunchedPackage:" + mLaunchedPackage + ", Permission:" + permission + "}");
+        return false;
+    }
+
+    private String getLaunchedFromPackage(Activity activity) {
+        try {
+            return mActivityManager.getLaunchedFromPackage(activity.getActivityToken());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Can not get the launched package from activity manager!");
+            return null;
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiPermissionCheckerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiPermissionCheckerTest.java
new file mode 100644
index 0000000..ec84141
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiPermissionCheckerTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.wifi;
+
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+import static android.Manifest.permission.ACCESS_WIFI_STATE;
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.IActivityManager;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class WifiPermissionCheckerTest {
+
+    static final String LAUNCHED_PACKAGE = "TestPackage";
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Mock
+    PackageManager mPackageManager;
+    @Mock
+    IActivityManager mActivityManager;
+    @Mock
+    Activity mActivity;
+
+    WifiPermissionChecker mWifiPermissionChecker;
+
+    @Before
+    public void setUp() {
+        when(mActivity.getPackageManager()).thenReturn(mPackageManager);
+        fakeGetLaunchedFromPackage(LAUNCHED_PACKAGE);
+
+        mWifiPermissionChecker = new WifiPermissionChecker(mActivity, mActivityManager);
+    }
+
+    @Test
+    public void getLaunchedPackage_returnLaunchedFromPackage() {
+        assertThat(mWifiPermissionChecker.getLaunchedPackage()).isEqualTo(LAUNCHED_PACKAGE);
+    }
+
+    @Test
+    public void canAccessWifiState_noPermission_returnFalse() {
+        when(mPackageManager.checkPermission(ACCESS_WIFI_STATE, LAUNCHED_PACKAGE))
+                .thenReturn(PERMISSION_DENIED);
+
+        assertThat(mWifiPermissionChecker.canAccessWifiState()).isFalse();
+    }
+
+    @Test
+    public void canAccessWifiState_hasPermission_returnTrue() {
+        when(mPackageManager.checkPermission(ACCESS_WIFI_STATE, LAUNCHED_PACKAGE))
+                .thenReturn(PERMISSION_GRANTED);
+
+        assertThat(mWifiPermissionChecker.canAccessWifiState()).isTrue();
+    }
+
+    @Test
+    public void canAccessFineLocation_noPermission_returnFalse() {
+        when(mPackageManager.checkPermission(ACCESS_FINE_LOCATION, LAUNCHED_PACKAGE))
+                .thenReturn(PERMISSION_DENIED);
+
+        assertThat(mWifiPermissionChecker.canAccessFineLocation()).isFalse();
+    }
+
+    @Test
+    public void canAccessFineLocation_hasPermission_returnTrue() {
+        when(mPackageManager.checkPermission(ACCESS_FINE_LOCATION, LAUNCHED_PACKAGE))
+                .thenReturn(PERMISSION_GRANTED);
+
+        assertThat(mWifiPermissionChecker.canAccessFineLocation()).isTrue();
+    }
+
+    void fakeGetLaunchedFromPackage(String packageName) {
+        try {
+            when(mActivityManager.getLaunchedFromPackage(any())).thenReturn(packageName);
+        } catch (RemoteException e) {
+            // Do nothing
+        }
+    }
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
index ca55779..093589f 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
@@ -20,6 +20,7 @@
 import android.animation.AnimatorListenerAdapter
 import android.animation.ObjectAnimator
 import android.animation.PropertyValuesHolder
+import android.animation.ValueAnimator
 import android.util.IntProperty
 import android.view.View
 import android.view.ViewGroup
@@ -37,6 +38,7 @@
         private const val DEFAULT_DURATION = 500L
         private val DEFAULT_INTERPOLATOR = Interpolators.STANDARD
         private val DEFAULT_ADDITION_INTERPOLATOR = Interpolators.STANDARD_DECELERATE
+        private val DEFAULT_REMOVAL_INTERPOLATOR = Interpolators.STANDARD_ACCELERATE
 
         /** The properties used to animate the view bounds. */
         private val PROPERTIES = mapOf(
@@ -113,7 +115,7 @@
             }
 
             val listener = createUpdateListener(interpolator, duration, ephemeral)
-            recursivelyAddListener(rootView, listener)
+            addListener(rootView, listener, recursive = true)
             return true
         }
 
@@ -183,7 +185,7 @@
             val listener = createAdditionListener(
                 origin, interpolator, duration, ignorePreviousValues = !includeMargins
             )
-            recursivelyAddListener(rootView, listener)
+            addListener(rootView, listener, recursive = true)
             return true
         }
 
@@ -298,6 +300,183 @@
         }
 
         /**
+         * Animates the removal of [rootView] and its children from the hierarchy. It uses the given
+         * [interpolator] and [duration].
+         *
+         * The end state of the animation is controlled by [destination]. This value can be any of
+         * the four corners, any of the four edges, or the center of the view.
+         */
+        @JvmOverloads
+        fun animateRemoval(
+            rootView: View,
+            destination: Hotspot = Hotspot.CENTER,
+            interpolator: Interpolator = DEFAULT_REMOVAL_INTERPOLATOR,
+            duration: Long = DEFAULT_DURATION
+        ): Boolean {
+            if (!isVisible(
+                    rootView.visibility,
+                    rootView.left,
+                    rootView.top,
+                    rootView.right,
+                    rootView.bottom
+                )
+            ) {
+                return false
+            }
+
+            val parent = rootView.parent as ViewGroup
+
+            // Ensure that rootView's siblings animate nicely around the removal.
+            val listener = createUpdateListener(
+                interpolator,
+                duration,
+                ephemeral = true
+            )
+            for (i in 0 until parent.childCount) {
+                val child = parent.getChildAt(i)
+                if (child == rootView) continue
+                addListener(child, listener, recursive = false)
+            }
+
+            // Remove the view so that a layout update is triggered for the siblings and they
+            // animate to their next position while the view's removal is also animating.
+            parent.removeView(rootView)
+            // By adding the view to the overlay, we can animate it while it isn't part of the view
+            // hierarchy. It is correctly positioned because we have its previous bounds, and we set
+            // them manually during the animation.
+            parent.overlay.add(rootView)
+
+            val startValues = mapOf(
+                Bound.LEFT to rootView.left,
+                Bound.TOP to rootView.top,
+                Bound.RIGHT to rootView.right,
+                Bound.BOTTOM to rootView.bottom
+            )
+            val endValues = processEndValuesForRemoval(
+                destination,
+                rootView.left,
+                rootView.top,
+                rootView.right,
+                rootView.bottom
+            )
+
+            val boundsToAnimate = mutableSetOf<Bound>()
+            if (rootView.left != endValues.getValue(Bound.LEFT)) boundsToAnimate.add(Bound.LEFT)
+            if (rootView.top != endValues.getValue(Bound.TOP)) boundsToAnimate.add(Bound.TOP)
+            if (rootView.right != endValues.getValue(Bound.RIGHT)) boundsToAnimate.add(Bound.RIGHT)
+            if (rootView.bottom != endValues.getValue(Bound.BOTTOM)) {
+                boundsToAnimate.add(Bound.BOTTOM)
+            }
+
+            startAnimation(
+                rootView,
+                boundsToAnimate,
+                startValues,
+                endValues,
+                interpolator,
+                duration,
+                ephemeral = true
+            )
+
+            if (rootView is ViewGroup) {
+                // Shift the children so they maintain a consistent position within the shrinking
+                // view.
+                shiftChildrenForRemoval(rootView, destination, endValues, interpolator, duration)
+
+                // Fade out the children during the first half of the removal, so they don't clutter
+                // too much once the view becomes very small. Then we fade out the view itself, in
+                // case it has its own content and/or background.
+                val startAlphas = FloatArray(rootView.childCount)
+                for (i in 0 until rootView.childCount) {
+                    startAlphas[i] = rootView.getChildAt(i).alpha
+                }
+
+                val animator = ValueAnimator.ofFloat(1f, 0f)
+                animator.interpolator = Interpolators.ALPHA_OUT
+                animator.duration = duration / 2
+                animator.addUpdateListener { animation ->
+                    for (i in 0 until rootView.childCount) {
+                        rootView.getChildAt(i).alpha =
+                            (animation.animatedValue as Float) * startAlphas[i]
+                    }
+                }
+                animator.addListener(object : AnimatorListenerAdapter() {
+                    override fun onAnimationEnd(animation: Animator) {
+                        rootView.animate()
+                            .alpha(0f)
+                            .setInterpolator(Interpolators.ALPHA_OUT)
+                            .setDuration(duration / 2)
+                            .withEndAction { parent.overlay.remove(rootView) }
+                            .start()
+                    }
+                })
+                animator.start()
+            } else {
+                // Fade out the view during the second half of the removal.
+                rootView.animate()
+                    .alpha(0f)
+                    .setInterpolator(Interpolators.ALPHA_OUT)
+                    .setDuration(duration / 2)
+                    .setStartDelay(duration / 2)
+                    .withEndAction { parent.overlay.remove(rootView) }
+                    .start()
+            }
+
+            return true
+        }
+
+        /**
+         * Animates the children of [rootView] so that its layout remains internally consistent as
+         * it shrinks towards [destination] and changes its bounds to [endValues].
+         *
+         * Uses [interpolator] and [duration], which should match those of the removal animation.
+         */
+        private fun shiftChildrenForRemoval(
+            rootView: ViewGroup,
+            destination: Hotspot,
+            endValues: Map<Bound, Int>,
+            interpolator: Interpolator,
+            duration: Long
+        ) {
+            for (i in 0 until rootView.childCount) {
+                val child = rootView.getChildAt(i)
+                val childStartValues = mapOf(
+                    Bound.LEFT to child.left,
+                    Bound.TOP to child.top,
+                    Bound.RIGHT to child.right,
+                    Bound.BOTTOM to child.bottom
+                )
+                val childEndValues = processChildEndValuesForRemoval(
+                    destination,
+                    child.left,
+                    child.top,
+                    child.right,
+                    child.bottom,
+                    endValues.getValue(Bound.RIGHT) - endValues.getValue(Bound.LEFT),
+                    endValues.getValue(Bound.BOTTOM) - endValues.getValue(Bound.TOP)
+                )
+
+                val boundsToAnimate = mutableSetOf<Bound>()
+                if (child.left != endValues.getValue(Bound.LEFT)) boundsToAnimate.add(Bound.LEFT)
+                if (child.top != endValues.getValue(Bound.TOP)) boundsToAnimate.add(Bound.TOP)
+                if (child.right != endValues.getValue(Bound.RIGHT)) boundsToAnimate.add(Bound.RIGHT)
+                if (child.bottom != endValues.getValue(Bound.BOTTOM)) {
+                    boundsToAnimate.add(Bound.BOTTOM)
+                }
+
+                startAnimation(
+                    child,
+                    boundsToAnimate,
+                    childStartValues,
+                    childEndValues,
+                    interpolator,
+                    duration,
+                    ephemeral = true
+                )
+            }
+        }
+
+        /**
          * Returns whether the given [visibility] and bounds are consistent with a view being
          * currently visible on screen.
          */
@@ -312,7 +491,7 @@
         }
 
         /**
-         * Compute the actual starting values based on the requested [origin] and on
+         * Computes the actual starting values based on the requested [origin] and on
          * [ignorePreviousValues].
          *
          * If [origin] is null, the resolved start values will be the same as those passed in, or
@@ -422,7 +601,140 @@
             )
         }
 
-        private fun recursivelyAddListener(view: View, listener: View.OnLayoutChangeListener) {
+        /**
+         * Computes a removal animation's end values based on the requested [destination] and the
+         * view's starting bounds.
+         *
+         * Examples:
+         *     1) destination=TOP
+         *         x---------x    x---------x    x---------x    x---------x    x---------x
+         *         |         |    |         |    |         |    x---------x
+         *         |         | -> |         | -> x---------x ->             ->
+         *         |         |    x---------x
+         *         x---------x
+         *      2) destination=BOTTOM_LEFT
+         *         x---------x
+         *         |         |    x-------x
+         *         |         | -> |       |   -> x----x      ->             ->
+         *         |         |    |       |      |    |         x--x
+         *         x---------x    x-------x      x----x         x--x           x
+         *     3) destination=CENTER
+         *         x---------x
+         *         |         |     x-------x       x-----x
+         *         |         | ->  |       |  ->   |     |   ->    x---x    ->      x
+         *         |         |     x-------x       x-----x
+         *         x---------x
+         */
+        private fun processEndValuesForRemoval(
+            destination: Hotspot,
+            left: Int,
+            top: Int,
+            right: Int,
+            bottom: Int
+        ): Map<Bound, Int> {
+            val endLeft = when (destination) {
+                Hotspot.CENTER -> (left + right) / 2
+                Hotspot.BOTTOM, Hotspot.BOTTOM_LEFT, Hotspot.LEFT, Hotspot.TOP_LEFT, Hotspot.TOP ->
+                    left
+                Hotspot.TOP_RIGHT, Hotspot.RIGHT, Hotspot.BOTTOM_RIGHT -> right
+            }
+            val endTop = when (destination) {
+                Hotspot.CENTER -> (top + bottom) / 2
+                Hotspot.LEFT, Hotspot.TOP_LEFT, Hotspot.TOP, Hotspot.TOP_RIGHT, Hotspot.RIGHT ->
+                    top
+                Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM, Hotspot.BOTTOM_LEFT -> bottom
+            }
+            val endRight = when (destination) {
+                Hotspot.CENTER -> (left + right) / 2
+                Hotspot.TOP, Hotspot.TOP_RIGHT, Hotspot.RIGHT,
+                Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM ->
+                    right
+                Hotspot.BOTTOM_LEFT, Hotspot.LEFT, Hotspot.TOP_LEFT -> left
+            }
+            val endBottom = when (destination) {
+                Hotspot.CENTER -> (top + bottom) / 2
+                Hotspot.RIGHT, Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM,
+                Hotspot.BOTTOM_LEFT, Hotspot.LEFT ->
+                    bottom
+                Hotspot.TOP_LEFT, Hotspot.TOP, Hotspot.TOP_RIGHT -> top
+            }
+
+            return mapOf(
+                Bound.LEFT to endLeft,
+                Bound.TOP to endTop,
+                Bound.RIGHT to endRight,
+                Bound.BOTTOM to endBottom
+            )
+        }
+
+        /**
+         * Computes the end values for the child of a view being removed, based on the child's
+         * starting bounds, the removal's [destination], and the [parentWidth] and [parentHeight].
+         *
+         * The end values always represent the child's position after it has been translated so that
+         * its center is at the [destination].
+         *
+         * Examples:
+         *     1) destination=TOP
+         *         The child maintains its left and right positions, but is shifted up so that its
+         *         center is on the parent's end top edge.
+         *     2) destination=BOTTOM_LEFT
+         *         The child shifts so that its center is on the parent's end bottom left corner.
+         *     3) destination=CENTER
+         *         The child shifts so that its own center is on the parent's end center.
+         */
+        private fun processChildEndValuesForRemoval(
+            destination: Hotspot,
+            left: Int,
+            top: Int,
+            right: Int,
+            bottom: Int,
+            parentWidth: Int,
+            parentHeight: Int
+        ): Map<Bound, Int> {
+            val halfWidth = (right - left) / 2
+            val halfHeight = (bottom - top) / 2
+
+            val endLeft = when (destination) {
+                Hotspot.CENTER -> (parentWidth / 2) - halfWidth
+                Hotspot.BOTTOM_LEFT, Hotspot.LEFT, Hotspot.TOP_LEFT -> -halfWidth
+                Hotspot.TOP_RIGHT, Hotspot.RIGHT, Hotspot.BOTTOM_RIGHT -> parentWidth - halfWidth
+                Hotspot.TOP, Hotspot.BOTTOM -> left
+            }
+            val endTop = when (destination) {
+                Hotspot.CENTER -> (parentHeight / 2) - halfHeight
+                Hotspot.TOP_LEFT, Hotspot.TOP, Hotspot.TOP_RIGHT -> -halfHeight
+                Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM, Hotspot.BOTTOM_LEFT ->
+                    parentHeight - halfHeight
+                Hotspot.LEFT, Hotspot.RIGHT -> top
+            }
+            val endRight = when (destination) {
+                Hotspot.CENTER -> (parentWidth / 2) + halfWidth
+                Hotspot.TOP_RIGHT, Hotspot.RIGHT, Hotspot.BOTTOM_RIGHT -> parentWidth + halfWidth
+                Hotspot.BOTTOM_LEFT, Hotspot.LEFT, Hotspot.TOP_LEFT -> halfWidth
+                Hotspot.TOP, Hotspot.BOTTOM -> right
+            }
+            val endBottom = when (destination) {
+                Hotspot.CENTER -> (parentHeight / 2) + halfHeight
+                Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM, Hotspot.BOTTOM_LEFT ->
+                    parentHeight + halfHeight
+                Hotspot.TOP_LEFT, Hotspot.TOP, Hotspot.TOP_RIGHT -> halfHeight
+                Hotspot.LEFT, Hotspot.RIGHT -> bottom
+            }
+
+            return mapOf(
+                Bound.LEFT to endLeft,
+                Bound.TOP to endTop,
+                Bound.RIGHT to endRight,
+                Bound.BOTTOM to endBottom
+            )
+        }
+
+        private fun addListener(
+            view: View,
+            listener: View.OnLayoutChangeListener,
+            recursive: Boolean = false
+        ) {
             // Make sure that only one listener is active at a time.
             val previousListener = view.getTag(R.id.tag_layout_listener)
             if (previousListener != null && previousListener is View.OnLayoutChangeListener) {
@@ -431,9 +743,9 @@
 
             view.addOnLayoutChangeListener(listener)
             view.setTag(R.id.tag_layout_listener, listener)
-            if (view is ViewGroup) {
+            if (view is ViewGroup && recursive) {
                 for (i in 0 until view.childCount) {
-                    recursivelyAddListener(view.getChildAt(i), listener)
+                    addListener(view.getChildAt(i), listener, recursive = true)
                 }
             }
         }
@@ -490,6 +802,8 @@
                 }
             }.toTypedArray()
 
+            (view.getTag(R.id.tag_animator) as? ObjectAnimator)?.cancel()
+
             val animator = ObjectAnimator.ofPropertyValuesHolder(view, *propertyValuesHolders)
             animator.interpolator = interpolator
             animator.duration = duration
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 d4b4a74..f492c06 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
@@ -94,6 +94,12 @@
         void setPrimaryTextColor(int color);
 
         /**
+         * When the view is displayed on Dream, set the flag to true, immediately after the view is
+         * created.
+         */
+        void setIsDreaming(boolean isDreaming);
+
+        /**
          * Range [0.0 - 1.0] when transitioning from Lockscreen to/from AOD
          */
         void setDozeAmount(float amount);
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index 3702be2..84016da 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -80,7 +80,7 @@
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"No se ha podido desbloquear la tarjeta SIM con el código PIN."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"No se ha podido desbloquear la tarjeta SIM con el código PUK."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambiar método de introducción"</string>
-    <string name="airplane_mode" msgid="2528005343938497866">"Modo avión"</string>
+    <string name="airplane_mode" msgid="2528005343938497866">"Modo Avión"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Debes introducir el patrón después de reiniciar el dispositivo"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Debes introducir el PIN después de reiniciar el dispositivo"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Debes introducir la contraseña después de reiniciar el dispositivo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index b312706..c8d6b71 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -53,7 +53,7 @@
     <string name="kg_wrong_pattern" msgid="5907301342430102842">"Feil mønster"</string>
     <string name="kg_wrong_password" msgid="4143127991071670512">"Feil passord"</string>
     <string name="kg_wrong_pin" msgid="4160978845968732624">"Feil PIN-kode"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Prøv igjen om # sekund.}other{Prøv igjen om # sekunder.}}"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Prøv på nytt om # sekund.}other{Prøv på nytt om # sekunder.}}"</string>
     <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Skriv inn PIN-koden for SIM-kortet."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Skriv inn PIN-koden for SIM-kortet «<xliff:g id="CARRIER">%1$s</xliff:g>»."</string>
     <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Deaktiver e-SIM-kortet for å bruke enheten uten mobiltjeneste."</string>
diff --git a/packages/SystemUI/res/drawable/keyguard_framed_avatar_background.xml b/packages/SystemUI/res/drawable/keyguard_framed_avatar_background.xml
new file mode 100644
index 0000000..a461bf8
--- /dev/null
+++ b/packages/SystemUI/res/drawable/keyguard_framed_avatar_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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
+  -->
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <corners android:radius="@dimen/kg_framed_avatar_size"/>
+    <solid android:color="@color/kg_user_avatar_frame"/>
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/keyguard_qs_user_switch.xml b/packages/SystemUI/res/layout/keyguard_qs_user_switch.xml
index 9cf09ff..6f33623 100644
--- a/packages/SystemUI/res/layout/keyguard_qs_user_switch.xml
+++ b/packages/SystemUI/res/layout/keyguard_qs_user_switch.xml
@@ -22,18 +22,25 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_gravity="end">
-    <com.android.systemui.statusbar.phone.UserAvatarView
-        android:id="@+id/kg_multi_user_avatar"
-        android:layout_width="@dimen/kg_framed_avatar_size"
-        android:layout_height="@dimen/kg_framed_avatar_size"
-        android:layout_centerHorizontal="true"
+    <!-- We add a background behind the UserAvatarView with the same color and with a circular shape
+         so that this view can be expanded into a Dialog or an Activity. -->
+    <FrameLayout
+        android:id="@+id/kg_multi_user_avatar_with_background"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         android:layout_gravity="top|end"
         android:layout_marginEnd="16dp"
-        systemui:avatarPadding="0dp"
-        systemui:badgeDiameter="18dp"
-        systemui:badgeMargin="1dp"
-        systemui:frameColor="@color/kg_user_avatar_frame"
-        systemui:framePadding="0dp"
-        systemui:frameWidth="0dp">
-    </com.android.systemui.statusbar.phone.UserAvatarView>
+        android:background="@drawable/keyguard_framed_avatar_background">
+        <com.android.systemui.statusbar.phone.UserAvatarView
+            android:id="@+id/kg_multi_user_avatar"
+            android:layout_width="@dimen/kg_framed_avatar_size"
+            android:layout_height="@dimen/kg_framed_avatar_size"
+            systemui:avatarPadding="0dp"
+            systemui:badgeDiameter="18dp"
+            systemui:badgeMargin="1dp"
+            systemui:frameColor="@color/kg_user_avatar_frame"
+            systemui:framePadding="0dp"
+            systemui:frameWidth="0dp">
+        </com.android.systemui.statusbar.phone.UserAvatarView>
+    </FrameLayout>
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 7962e22..534c80d 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -80,7 +80,7 @@
         android:background="@drawable/qs_media_light_source"
         android:forceHasOverlappingRendering="false"
         android:layout_width="wrap_content"
-        android:layout_height="48dp"
+        android:layout_height="@dimen/min_clickable_item_size"
         android:layout_marginStart="@dimen/qs_center_guideline_padding"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintTop_toTopOf="parent"
@@ -92,8 +92,9 @@
         <LinearLayout
             android:id="@+id/media_seamless_button"
             android:layout_width="wrap_content"
-            android:layout_height="@dimen/qs_seamless_height"
+            android:layout_height="wrap_content"
             android:minHeight="@dimen/qs_seamless_height"
+            android:maxHeight="@dimen/min_clickable_item_size"
             android:theme="@style/MediaPlayer.SolidButton"
             android:background="@drawable/qs_media_seamless_background"
             android:orientation="horizontal"
diff --git a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
index 659a578..79ba7ead 100644
--- a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
+++ b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
@@ -16,6 +16,8 @@
   -->
 
 <!-- Layout for media recommendations inside QSPanel carousel -->
+<!-- See media_recommendation_expanded.xml and media_recommendation_collapsed.xml for the
+     constraints. -->
 <com.android.systemui.util.animation.TransitionLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -46,14 +48,6 @@
     <FrameLayout
         android:id="@+id/media_cover1_container"
         style="@style/MediaPlayer.Recommendation.AlbumContainer"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toTopOf="@+id/media_title1"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/media_cover2_container"
-        android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
-        app:layout_constraintHorizontal_chainStyle="packed"
-        app:layout_constraintHorizontal_bias="1.0"
-        app:layout_constraintVertical_bias="0.5"
         >
         <ImageView
             android:id="@+id/media_cover1"
@@ -71,31 +65,16 @@
     <TextView
         android:id="@+id/media_title1"
         style="@style/MediaPlayer.Recommendation.Text.Title"
-        app:layout_constraintStart_toStartOf="@+id/media_cover1_container"
-        app:layout_constraintEnd_toEndOf="@+id/media_cover1_container"
-        app:layout_constraintTop_toBottomOf="@+id/media_cover1_container"
-        app:layout_constraintBottom_toTopOf="@+id/media_subtitle1"
         />
 
     <TextView
         android:id="@+id/media_subtitle1"
         style="@style/MediaPlayer.Recommendation.Text.Subtitle"
-        app:layout_constraintStart_toStartOf="@+id/media_cover1_container"
-        app:layout_constraintEnd_toEndOf="@+id/media_cover1_container"
-        app:layout_constraintTop_toBottomOf="@+id/media_title1"
-        app:layout_constraintBottom_toBottomOf="parent"
-        android:layout_marginBottom="@dimen/qs_media_padding"
         />
 
     <FrameLayout
         android:id="@+id/media_cover2_container"
         style="@style/MediaPlayer.Recommendation.AlbumContainer"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toTopOf="@id/media_title2"
-        app:layout_constraintStart_toEndOf="@id/media_cover1_container"
-        app:layout_constraintEnd_toStartOf="@id/media_cover3_container"
-        android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
-        app:layout_constraintVertical_bias="0.5"
         >
         <ImageView
             android:id="@+id/media_cover2"
@@ -111,31 +90,16 @@
     <TextView
         android:id="@+id/media_title2"
         style="@style/MediaPlayer.Recommendation.Text.Title"
-        app:layout_constraintStart_toStartOf="@+id/media_cover2_container"
-        app:layout_constraintEnd_toEndOf="@+id/media_cover2_container"
-        app:layout_constraintTop_toBottomOf="@+id/media_cover2_container"
-        app:layout_constraintBottom_toTopOf="@+id/media_subtitle2"
         />
 
     <TextView
         android:id="@+id/media_subtitle2"
         style="@style/MediaPlayer.Recommendation.Text.Subtitle"
-        app:layout_constraintStart_toStartOf="@+id/media_cover2_container"
-        app:layout_constraintEnd_toEndOf="@+id/media_cover2_container"
-        app:layout_constraintTop_toBottomOf="@+id/media_title2"
-        app:layout_constraintBottom_toBottomOf="parent"
-        android:layout_marginBottom="@dimen/qs_media_padding"
         />
 
     <FrameLayout
         android:id="@+id/media_cover3_container"
         style="@style/MediaPlayer.Recommendation.AlbumContainer"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toTopOf="@id/media_title3"
-        app:layout_constraintStart_toEndOf="@id/media_cover2_container"
-        app:layout_constraintEnd_toEndOf="parent"
-        android:layout_marginEnd="@dimen/qs_media_padding"
-        app:layout_constraintVertical_bias="0.5"
         >
         <ImageView
             android:id="@+id/media_cover3"
@@ -151,20 +115,11 @@
     <TextView
         android:id="@+id/media_title3"
         style="@style/MediaPlayer.Recommendation.Text.Title"
-        app:layout_constraintStart_toStartOf="@+id/media_cover3_container"
-        app:layout_constraintEnd_toEndOf="@+id/media_cover3_container"
-        app:layout_constraintTop_toBottomOf="@+id/media_cover3_container"
-        app:layout_constraintBottom_toTopOf="@+id/media_subtitle3"
         />
 
     <TextView
         android:id="@+id/media_subtitle3"
         style="@style/MediaPlayer.Recommendation.Text.Subtitle"
-        app:layout_constraintStart_toStartOf="@+id/media_cover3_container"
-        app:layout_constraintEnd_toEndOf="@+id/media_cover3_container"
-        app:layout_constraintTop_toBottomOf="@+id/media_title3"
-        app:layout_constraintBottom_toBottomOf="parent"
-        android:layout_marginBottom="@dimen/qs_media_padding"
         />
 
     <include
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index f101b7c..b83b4b7 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Wiil jy jou sessie voortsit?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Begin van voor af"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, gaan voort"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gasmodus"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Jy is in gasmodus"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Voeg nuwe gebruiker by?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Wanneer jy \'n nuwe gebruiker byvoeg, moet daardie persoon hul spasie opstel.\n\nEnige gebruiker kan programme vir al die ander gebruikers opdateer."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"As ’n nuwe gebruiker bygevoeg word, sal gasmodus verlaat word en sal alle programme en data in die huidige gastesessie uitgevee word."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Gebruikerlimiet is bereik"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Jy kan tot <xliff:g id="COUNT">%d</xliff:g> gebruikers byvoeg.</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Voeg teël by"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Moenie teël byvoeg nie"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Kies gebruiker"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> programme is aktief</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> program is aktief</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nuwe inligting"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiewe programme"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Hierdie programme is steeds aktief en beïnvloed dalk batterylewe, selfs al gebruik jy hulle nie"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Gestop"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Klaar"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 5838dbf..e33f579 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ክፍለ-ጊዜዎን መቀጠል ይፈልጋሉ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"እንደገና ጀምር"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"አዎ፣ ቀጥል"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"የእንግዳ ሁነታ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"በእንግዳ ሁኔታ ውስጥ ነዎት"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"አዲስ ተጠቃሚ ይታከል?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"እርስዎ አንድ አዲስ ተጠቃሚ ሲያክሉ ያ ሰው የራሱ ቦታ ማዘጋጀት አለበት።\n\nማንኛውም ተጠቃሚ መተግበሪያዎችን ለሌሎች ተጠቃሚዎች ሁሉ ሊያዘምን ይችላል።"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"አዲስ ተጠቃሚ ማከል ከእንግዳ ሁነታ ወጥቶ ሁሉንም መተግበሪያዎች እና ውሂብ አሁን ካለው የእንግዳ ክፍለ ጊዜ ይሰርዛል።"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"የተጠቃሚ ገደብ ላይ ተደርሷል"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> ተጠቃሚዎች ብቻ ናቸው ሊፈጠሩ የሚችሉት።</item>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> መተግበሪያዎች ንቁ ናቸው</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> መተግበሪያዎች ንቁ ናቸው</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"አዲስ መረጃ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ገቢር መተግበሪያዎች"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"እነዚህን መተግበሪያዎች እየተጠቀሙ ባይሆኑ እንኳ፣ አሁኑም ንቁ ናቸው እናም የባትሪው ጤና ላይ ተፅዕኖ ሊያሳድሩ ይችላሉ"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"መቆሚያ"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ቆሟል"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"ተከናውኗል"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index d711d59..a0c909c 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -352,6 +352,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"هل تريد متابعة جلستك؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"البدء من جديد"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"نعم، متابعة"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"وضع الضيف"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"أنت تستخدِم وضع الضيف."</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"هل تريد إضافة مستخدم جديد؟"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"عند إضافة مستخدم جديد، عليه إعداد مساحته.\n\nويُمكن لأي مستخدم تحديث التطبيقات لجميع المستخدمين الآخرين."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ستؤدي إضافة مُستخدِم جديد إلى الخروج من وضع الضيف وحذف كل التطبيقات والبيانات من جلسة الضيف الحالية."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"تم الوصول إلى أقصى عدد للمستخدمين"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="zero">يمكنك إضافة ما يصل إلى <xliff:g id="COUNT">%d</xliff:g> مستخدم.</item>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 68728a7..e6fd51a 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপুনি আপোনাৰ ছেশ্বন অব্যাহত ৰাখিব বিচাৰেনে?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আকৌ আৰম্ভ কৰক"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"হয়, অব্যাহত ৰাখক"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"অতিথি ম’ড"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"আপুনি অতিথি ম’ডত আছে"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"নতুন ব্যৱহাৰকাৰী যোগ কৰিবনে?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"আপুনি যেতিয়া এজন নতুন ব্যৱহাৰকাৰী যোগ কৰে, তেওঁ নিজৰ স্থান ছেট আপ কৰা প্ৰয়োজন।\n\nযিকোনো ব্যৱহাৰকাৰীয়ে নিজৰ লগতে আন ব্যৱহাৰকাৰীৰো এপ্ আপডে’ট কৰিব পাৰে।"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"এগৰাকী নতুন ব্যৱহাৰকাৰীক যোগ দিয়াটোৱে অতিথি ম’ডৰ পৰা বাহিৰ কৰিব আৰু বৰ্তমানৰ অতিথিৰ ছেশ্বনটোৰ পৰা আটাইবোৰ এপ্ আৰু ডেটা মচিব।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"অধিকতম ব্যৱহাৰকাৰী সৃষ্টি কৰা হ’ল"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">আপুনি <xliff:g id="COUNT">%d</xliff:g> জনলৈকে ব্যৱহাৰকাৰী যোগ কৰিব পাৰে।</item>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> টা এপ্‌ সক্ৰিয় হৈ আছে</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> টা এপ্‌ সক্ৰিয় হৈ আছে</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"নতুন তথ্য"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"সক্ৰিয় এপ্‌"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"আপুনি এই এপ্‌সমূহ ব্যৱহাৰ কৰি নাথাকিলেও, সেইসমূহ এতিয়াও সক্ৰিয় হৈ আছে আৰু সেইসমূহে বেটাৰিৰ জীৱনকাল প্ৰভাৱিত কৰিব পাৰে"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"বন্ধ কৰক"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"বন্ধ হ’ল"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"হ’ল"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index e4ab386..042a162 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -33,14 +33,14 @@
     <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Xeyr, təşəkkür"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Ekranın avtomatik dönməsi"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına giriş icazəsi verilsin?"</string>
-    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına giriş icazəsi verilsin?\nBu tətbiqə qeydə almaq icazəsi verilməyib lakin, bu USB vasitəsilə səs yaza bilər."</string>
+    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına giriş verilsin?\nTətbiqə qeydə almaq icazəsi verilməsə də, bu USB vasitəsilə səsi qeydə ala bilər."</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına giriş icazəsi verilsin?"</string>
     <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazını idarə etmək üçün <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqi açılsın?"</string>
-    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Bu tətbiqə yazmaq icazəsi verilməyib, lakin, bu USB vasitəsilə səs yaza bilər. <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqindən bu cihazla istifadə etsəniz zənglər, bildirişlər və siqnallar eşidilməyə bilər."</string>
+    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Tətbiqə qeydə almaq icazəsi verilməsə də, bu USB vasitəsilə səsi qeydə ala bilər. <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinin bu cihazla istifadəsi zənglərin və bildirişlərin eşidilməməsinə səbəb ola bilər."</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqindən bu cihazla istifadə etsəniz zənglər, bildirişlər və siqnallar eşidilməyə bilər."</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> cihazına giriş icazəsi verilsin?"</string>
     <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazını idarə etmək üçün <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqi açılsın?"</string>
-    <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazını idarə etmək üçün <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqi açılsın?\nBu tətbiqə yazmaq icazəsi verilməyib, lakin, bu USB vasitəsilə səs yaza bilər."</string>
+    <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına giriş verilsin?\nTətbiqə qeydə almaq icazəsi verilməsə də, bu USB vasitəsilə səsi qeydə ala bilər."</string>
     <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> cihazını idarə etmək üçün <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqi açılsın?"</string>
     <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Heç bir quraşdırılmış tətbiq bu USB aksesuar ilə işləmir. Bu aksesuar haqqında daha ətraflı məlumatı <xliff:g id="URL">%1$s</xliff:g> adresindən öyrənin"</string>
     <string name="title_usb_accessory" msgid="1236358027511638648">"USB aksesuar"</string>
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Sessiya davam etsin?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Yenidən başlayın"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Bəli, davam edin"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Qonaq rejimi"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Qonaq rejimindəsiniz"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Yeni istifadəçi əlavə edilsin?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Yeni istifadəçi əlavə etdiyiniz zaman həmin şəxs öz yerini quraşdırmalıdır. \n\n İstənilən istifadəçi bütün digər istifadəçilərdən olan tətbiqləri güncəlləşdirə bilər."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Yeni istifadəçi əlavə edildikdə qonaq rejimindən çıxılacaq və cari qonaq sessiyasındakı bütün tətbiqlər və data silinəcək."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"İstifadəçi limitinə çatmısınız"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Maksimum <xliff:g id="COUNT">%d</xliff:g> istifadəçi əlavə edə bilərsiniz.</item>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index ac7b219..a004497 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -346,6 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li da nastavite sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni iz početka"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Režim gosta"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Koristite režim gosta"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Dodajete novog korisnika?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kada dodate novog korisnika, ta osoba treba da podesi svoj prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Dodavanjem novog korisnika izaći ćete iz režima gosta i izbrisaćete sve aplikacije i podatke iz aktuelne sesije gosta."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dostignut maksimalni broj korisnika"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Možete da dodate najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
@@ -923,11 +928,14 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj pločicu"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne dodaj pločicu"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Izaberite korisnika"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivna</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikacije su aktivne</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivno</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Čak i ako ne koristite ove aplikacije, one su i dalje aktivne i mogu da utiču na trajanje baterije"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zaustavi"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zaustavljeno"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Gotovo"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 7f006f4..2085b28 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -348,6 +348,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Хочаце працягнуць сеанс?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Пачаць зноў"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Так, працягнуць"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Гасцявы рэжым"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Вы знаходзіцеся ў гасцявым рэжыме"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Дадаць новага карыстальніка?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Пасля стварэння профілю яго трэба наладзіць.\n\nЛюбы карыстальнік прылады можа абнаўляць праграмы ўсіх іншых карыстальнікаў."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Дадаванне новага карыстальніка закрые гасцявы рэжым. Будуць выдалены ўсе праграмы і даныя бягучага гасцявога сеанса."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Дасягнуты ліміт карыстальнікаў"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Можна дадаць <xliff:g id="COUNT">%d</xliff:g> карыстальніка.</item>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 901572d..66efaa1 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Искате ли да продължите сесията си?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Започване отначало"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продължавам"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Режим на гост"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Вие сте в режим на гост"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Да се добави ли нов потребител?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Когато добавите нов потребител, той трябва да настрои работното си пространство.\n\nВсеки потребител може да актуализира приложенията за всички останали потребители."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"С добавянето на нов потребител ще излезете от режима на гост и ще изтриете всички приложения и данни от текущата сесия като гост."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнахте огранич. за потребители"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Можете да добавите до <xliff:g id="COUNT">%d</xliff:g> потребители.</item>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> приложения са активни</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> приложение е активно</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нова информация"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активни приложения"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Дори и да не използвате тези приложения, те са активни и може да окажат влияние върху живота на батерията"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Спиране"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Спряно"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Готово"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 180d80b..2fc0364 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"কনফার্ম করা হয়েছে"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"সম্পূর্ণ করতে \'কনফার্ম করুন\' বোতামে ট্যাপ করুন"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যাওয়ার জন্য আনলক আইকনে প্রেস করুন।"</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে আনলক আইকন প্রেস করুন।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"প্রমাণীকৃত"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"পিন ব্যবহার করুন"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"প্যাটার্ন ব্যবহার করুন"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"খোলার জন্য উপরে সোয়াইপ করুন"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"খোলার জন্য আনলক আইকন প্রেস করুন"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ফেসের সাহায্যে আনলক করা হয়েছে। খোলার জন্য আনলক আইকন প্রেস করুন।"</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ফেসের সাহায্যে আনলক করা হয়েছে। খোলার জন্য প্রেস করুন।"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ফেস শনাক্ত করা হয়েছে। খোলার জন্য প্রেস করুন।"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ফেস শনাক্ত করা হয়েছে। খোলার জন্য আনলক আইকন প্রেস করুন।"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"আবার চেষ্টা করতে উপরের দিকে সোয়াইপ করুন"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যবহার করতে আনলক করুন"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপনি কি আপনার সেশনটি চালিয়ে যেতে চান?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আবার শুরু করুন"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"হ্যাঁ, চালিয়ে যান"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"অতিথি মোড"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"আপনি \'অতিথি মোড\' ব্যবহার করছেন"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"নতুন ব্যবহারকারীকে যোগ করবেন?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"আপনি একজন নতুন ব্যবহারকারী যোগ করলে তাকে তার জায়গা সেট-আপ করে নিতে হবে৷\n\nযেকোনও ব্যবহারকারী অন্য সব ব্যবহারকারীর জন্য অ্যাপ আপডেট করতে পারবেন৷"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"নতুন ব্যবহারকারী যোগ করার মাধ্যমে \'অতিথি মোড\' ছেড়ে বেরিয়ে আসতে পারবেন এবং বর্তমান অতিথি সেশন থেকে সব অ্যাপ ও ডেটা মুছে যাবে।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"আর কোনও প্রোফাইল যোগ করা যাবে না"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">আপনি <xliff:g id="COUNT">%d</xliff:g> জন পর্যন্ত ব্যবহারকারীর প্রোফাইল যোগ করতে পারেন।</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"অগ্রাধিকার"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এ কথোপকথন ফিচার কাজ করে না"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"এই বিজ্ঞপ্তিগুলি পরিবর্তন করা যাবে না।"</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"কল বিজ্ঞপ্তি পরিবর্তন করা যাবে না।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"এই সমস্ত বিজ্ঞপ্তিকে এখানে কনফিগার করা যাবে না"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"প্রক্সি করা বিজ্ঞপ্তি"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"<xliff:g id="APP_NAME">%1$s</xliff:g> সংক্রান্ত সমস্ত বিজ্ঞপ্তি"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index b1edfd9..4000c20 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -346,6 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Način rada za gosta"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Nalazite se u načinu rada za gosta"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Dodati novog korisnika?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kada dodate novog korisnika, ta osoba treba postaviti svoj prostor.\n\nSvaki korisnik može ažurirati aplikacije za sve ostale korisnike."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Dodavanjem novog korisnika napustit ćete način rada za gosta i izbrisati sve aplikacije i podatke iz trenutne sesije gosta."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dostignut limit za broj korisnika"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
@@ -923,11 +928,14 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj karticu"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nemoj dodati karticu"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Odaberite korisnika"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivna</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikacije su aktivne</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivno</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Čak i ako ne korististite te aplikacije, one su i dalje aktivne i mogu utjecati na trajanje baterije"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zaustavi"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zaustavljeno"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Gotovo"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 20e5a5a..e66ac1b 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmat"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirma per completar"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"S\'ha desbloquejat amb la cara. Prem la icona per continuar."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S\'ha desbloquejat amb la cara. Prem per continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"S\'ha reconegut la cara. Prem per continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"S\'ha reconegut la cara. Prem la icona per continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticat"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilitza el PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utilitza el patró"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Llisca cap amunt per obrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Prem la icona de desbloqueig per obrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"S\'ha desbloquejat amb la cara. Prem la icona per obrir."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"S\'ha desbloquejat amb la cara. Prem per obrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"S\'ha reconegut la cara. Prem per obrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"S\'ha reconegut la cara. Prem la icona per obrir."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Llisca cap a dalt per tornar-ho a provar"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueja per utilitzar l\'NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Aquest dispositiu pertany a la teva organització"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vols continuar amb la sessió?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Torna a començar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continua"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mode de convidat"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Estàs en mode de convidat"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Vols afegir un usuari nou?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar-se l\'espai.\n\nQualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"En afegir un usuari nou, se sortirà del mode de convidat i se suprimiran totes les aplicacions i dades de la sessió de convidat actual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"S\'ha assolit el límit d\'usuaris"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Pots afegir fins a <xliff:g id="COUNT">%d</xliff:g> usuaris.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritat"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admet les funcions de converses"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Aquestes notificacions no es poden modificar."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Les notificacions de trucades no es poden modificar."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Aquest grup de notificacions no es pot configurar aquí"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notificació mitjançant aplicació intermediària"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Totes les notificacions de l\'aplicació <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -531,7 +529,7 @@
     <string name="feedback_prompt" msgid="3656728972307896379">"Fes saber els teus suggeriments al desenvolupador. La informació ha estat correcta?"</string>
     <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"S\'han obert els controls de notificació per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"S\'han tancat els controls de notificació per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="notification_more_settings" msgid="4936228656989201793">"Més opcions"</string>
+    <string name="notification_more_settings" msgid="4936228656989201793">"Més opcions de configuració"</string>
     <string name="notification_app_settings" msgid="8963648463858039377">"Personalitza"</string>
     <string name="notification_conversation_bubble" msgid="2242180995373949022">"Mostra com a bombolla"</string>
     <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Suprimeix les bombolles"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 14749b5..9ba3cb8 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -348,6 +348,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relaci pokračovat?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začít znovu"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ano, pokračovat"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Režim hosta"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Jste v režimu hosta"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Přidat nového uživatele?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Když přidáte nového uživatele, musí si nastavit vlastní prostor.\n\nJakýkoli uživatel může aktualizovat aplikace všech ostatních uživatelů."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Přidáním nového uživatele ukončíte režim hosta a smažete všechny aplikace a data z aktuální relace hosta."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Bylo dosaženo limitu uživatelů"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="few">Lze přidat až <xliff:g id="COUNT">%d</xliff:g> uživatele.</item>
@@ -425,7 +430,7 @@
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikace je připnutá"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Obsah bude připnut v zobrazení, dokud jej neuvolníte. Uvolníte jej stisknutím a podržením tlačítek Zpět a Přehled."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Obsah bude připnut v zobrazení, dokud ho neuvolníte. Uvolníte ho podržením tlačítek Zpět a Plocha."</string>
-    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Díky připnutí bude vidět, dokud ji neodepnete. Odepnout ji můžete přejetím nahoru a podržením."</string>
+    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Díky připnutí bude aplikace vidět, dokud ji neodepnete. Odepnout ji můžete přejetím prstem nahoru a podržením."</string>
     <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Obsah bude připnut v zobrazení, dokud jej neuvolníte. Uvolníte jej stisknutím a podržením tlačítka Přehled."</string>
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Obsah bude připnut v zobrazení, dokud ho neuvolníte. Uvolníte ho podržením tlačítka Plocha."</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Může mít přístup k soukromým datům (například kontaktům a obsahu e-mailů)."</string>
@@ -929,11 +934,15 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Přidat dlaždici"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nepřidávat dlaždici"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Zvolte uživatele"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikace jsou aktivní</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> aplikace je aktivních</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikací je aktivních</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikace je aktivní</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nové informace"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivní aplikace"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"I když tyto aplikace nepoužíváte, jsou stále aktivní a mohou mít vliv na výdrž baterie"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Konec"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zastaveno"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Hotovo"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 8e5095b..2d40469 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsætte din session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start forfra"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsæt"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gæstetilstand"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Gæstetilstand er aktiveret"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Vil du tilføje en ny bruger?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Når du tilføjer en ny bruger, skal personen konfigurere sit område.\n\nAlle brugere kan opdatere apps for alle de andre brugere."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Hvis du tilføjer en ny bruger, deaktiveres gæstetilstanden, og alle apps og data slettes fra den aktuelle gæstesession."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Grænsen for antal brugere er nået"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Du kan tilføje op til <xliff:g id="COUNT">%d</xliff:g> bruger.</item>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index e0a3eac..4190ab7 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bestätigt"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Zum Abschließen auf \"Bestätigen\" tippen"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Gerät mit dem Gesicht entsperrt. Tippe auf das Symbol „Entsperren“, um fortzufahren."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Gerät mit dem Gesicht entsperrt. Tippe, um fortzufahren."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesicht erkannt. Tippe, um fortzufahren."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesicht erkannt. Tippe zum Fortfahren auf das Symbol „Entsperren“."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifiziert"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN verwenden"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Muster verwenden"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Zum Öffnen nach oben wischen"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tippe zum Öffnen auf das Symbol „Entsperren“"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Gerät mit dem Gesicht entsperrt. Tippe zum Öffnen auf das Symbol „Entsperren“."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Gerät mit dem Gesicht entsperrt. Tippe zum Öffnen."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gesicht erkannt. Tippe zum Öffnen."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Gesicht erkannt. Tippe zum Öffnen auf das Symbol „Entsperren“."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Zum Wiederholen nach oben wischen"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Zur Verwendung von NFC entsperren"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Dieses Gerät gehört deiner Organisation"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Möchtest du deine Sitzung fortsetzen?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Neu starten"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, weiter"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gastmodus"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Du befindest dich im Gastmodus"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Neuen Nutzer hinzufügen?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Wenn du einen neuen Nutzer hinzufügst, muss dieser seinen Bereich einrichten.\n\nJeder Nutzer kann Apps für alle anderen Nutzer aktualisieren."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Durch Hinzufügen eines neuen Nutzers wird der Gastmodus beendet und alle Apps und Daten der aktuellen Gastsitzung werden gelöscht."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Nutzerlimit erreicht"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Du kannst bis zu <xliff:g id="COUNT">%d</xliff:g> Nutzer hinzufügen.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorität"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> unterstützt keine Funktionen für Unterhaltungen"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Diese Benachrichtigungen können nicht geändert werden."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Anrufbenachrichtigungen können nicht geändert werden."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Die Benachrichtigungsgruppe kann hier nicht konfiguriert werden"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Weitergeleitete Benachrichtigung"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Alle Benachrichtigungen von <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -924,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Hinzufügen"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nicht hinzufügen"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Nutzer auswählen"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> Apps sind aktiv</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> App ist aktiv</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Neue Informationen"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive Apps"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Auch wenn du diese Apps nicht verwendest, sind sie trotzdem aktiv und können sich auf die Akkulaufzeit auswirken"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Beenden"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Beendet"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Fertig"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index bb29f6f..62b76292 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -33,8 +33,8 @@
     <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Όχι, ευχαριστώ"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Αυτόματη περιστροφή οθόνης"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Να επιτρέπεται η πρόσβαση της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> στη συσκευή <xliff:g id="USB_DEVICE">%2$s</xliff:g>;"</string>
-    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> να έχει πρόσβαση στη συσκευή <xliff:g id="USB_DEVICE">%2$s</xliff:g>;\nΔεν έχει εκχωρηθεί άδεια εγγραφής σε αυτήν την εφαρμογή, αλλά μέσω αυτής της συσκευής USB θα μπορεί να εγγράφει ήχο."</string>
-    <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή <xliff:g id="USB_DEVICE">%2$s</xliff:g>;"</string>
+    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Να επιτρέπεται στο <xliff:g id="APPLICATION">%1$s</xliff:g> να έχει πρόσβαση στη συσκευή <xliff:g id="USB_DEVICE">%2$s</xliff:g>;\nΔεν έχει εκχωρηθεί άδεια εγγραφής σε αυτήν την εφαρμογή, αλλά μέσω αυτής της συσκευής USB θα μπορεί να εγγράφει ήχο."</string>
+    <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Να επιτρέπεται στο <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή <xliff:g id="USB_DEVICE">%2$s</xliff:g>;"</string>
     <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Άνοιγμα <xliff:g id="APPLICATION">%1$s</xliff:g> για διαχείριση συσκευής <xliff:g id="USB_DEVICE">%2$s</xliff:g>;"</string>
     <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Δεν έχει εκχωρηθεί άδεια εγγραφής σε αυτήν την εφαρμογή, αλλά μέσω αυτής της συσκευής USB θα μπορεί να εγγράφει ήχο. Η χρήση της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> με αυτήν τη συσκευή μπορεί να σας εμποδίσει να ακούσετε κλήσεις, ειδοποιήσεις και ξυπνητήρια."</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Η χρήση της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> με αυτήν τη συσκευή μπορεί να σας εμποδίσει να ακούσετε κλήσεις, ειδοποιήσεις και ξυπνητήρια."</string>
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Θέλετε να συνεχίσετε την περίοδο σύνδεσής σας;"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Έναρξη από την αρχή"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ναι, συνέχεια"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Λειτουργία επισκέπτη"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Βρίσκεστε σε λειτουργία επισκέπτη"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Προσθήκη νέου χρήστη;"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει τον χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Με την προσθήκη νέου χρήστη θα γίνει έξοδος από τη λειτουργία επισκέπτη και θα διαγραφούν όλες οι εφαρμογές και τα δεδομένα από την τρέχουσα περίοδο σύνδεσης επισκέπτη."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Συμπληρώθηκε το όριο χρηστών"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Μπορείτε να προσθέσετε έως <xliff:g id="COUNT">%d</xliff:g> χρήστες.</item>
@@ -714,10 +719,10 @@
     <string name="mobile_data_disable_message" msgid="8604966027899770415">"Δεν θα έχετε πρόσβαση σε δεδομένα ή στο διαδίκτυο μέσω της εταιρείας κινητής τηλεφωνίας <xliff:g id="CARRIER">%s</xliff:g>. Θα έχετε πρόσβαση στο διαδίκτυο μόνο μέσω Wi-Fi."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"η εταιρεία κινητής τηλεφωνίας"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Επειδή μια εφαρμογή αποκρύπτει ένα αίτημα άδειας, δεν είναι δυνατή η επαλήθευση της απάντησής σας από τις Ρυθμίσεις."</string>
-    <string name="slice_permission_title" msgid="3262615140094151017">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APP_0">%1$s</xliff:g> να εμφανίζει τμήματα της εφαρμογής <xliff:g id="APP_2">%2$s</xliff:g>;"</string>
+    <string name="slice_permission_title" msgid="3262615140094151017">"Να επιτρέπεται στο <xliff:g id="APP_0">%1$s</xliff:g> να εμφανίζει τμήματα της εφαρμογής <xliff:g id="APP_2">%2$s</xliff:g>;"</string>
     <string name="slice_permission_text_1" msgid="6675965177075443714">"- Μπορεί να διαβάζει πληροφορίες από την εφαρμογή <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="slice_permission_text_2" msgid="6758906940360746983">"- Μπορεί να εκτελεί ενέργειες εντός της εφαρμογής <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="slice_permission_checkbox" msgid="4242888137592298523">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g> να εμφανίζει τμήματα από οποιαδήποτε εφαρμογή"</string>
+    <string name="slice_permission_checkbox" msgid="4242888137592298523">"Να επιτρέπεται στο <xliff:g id="APP">%1$s</xliff:g> να εμφανίζει τμήματα από οποιαδήποτε εφαρμογή"</string>
     <string name="slice_permission_allow" msgid="6340449521277951123">"Επιτρέπεται"</string>
     <string name="slice_permission_deny" msgid="6870256451658176895">"Δεν επιτρέπεται"</string>
     <string name="auto_saver_title" msgid="6873691178754086596">"Πατήστε για προγραμματισμό της Εξοικονόμησης μπαταρίας"</string>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> εφαρμογές είναι ενεργές</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> εφαρμογή είναι ενεργή</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Νέες πληροφορίες"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ενεργές εφαρμογές"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Ακόμη και αν δεν χρησιμοποιείτε αυτές τις εφαρμογές, εξακολουθούν να είναι ενεργές και ενδέχεται να επηρεάζουν τη διάρκεια ζωής της μπαταρίας"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Διακοπή"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Διακόπηκε"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Τέλος"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 790bf3f..b776ce0 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Select user"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps are active</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app is active</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Even if you’re not using these apps, they’re still active and might affect battery life"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Done"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index ce76459..b93c8f1 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Select user"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps are active</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app is active</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Even if you’re not using these apps, they’re still active and might affect battery life"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Done"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 790bf3f..b776ce0 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Select user"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps are active</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app is active</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Even if you’re not using these apps, they’re still active and might affect battery life"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Done"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 790bf3f..b776ce0 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Select user"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps are active</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app is active</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Even if you’re not using these apps, they’re still active and might affect battery life"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stop"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stopped"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Done"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 30240d4..a4e0df1 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎Do you want to continue your session?‎‏‎‎‏‎"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‎Start over‎‏‎‎‏‎"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎Yes, continue‎‏‎‎‏‎"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎Guest mode‎‏‎‎‏‎"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎You are in guest mode‎‏‎‎‏‎"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎Add new user?‎‏‎‎‏‎"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‏‎When you add a new user, that person needs to set up their space.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Any user can update apps for all other users.‎‏‎‎‏‎"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Adding a new user will exit guest mode and delete all apps and data from the current guest session.‎‏‎‎‏‎"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎User limit reached‎‏‎‎‏‎"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎You can add up to ‎‏‎‎‏‏‎<xliff:g id="COUNT">%d</xliff:g>‎‏‎‎‏‏‏‎ users.‎‏‎‎‏‎</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‎Add tile‎‏‎‎‏‎"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‎Do not add tile‎‏‎‎‏‎"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎Select user‎‏‎‎‏‎"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%s</xliff:g>‎‏‎‎‏‏‏‎ apps are active‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%s</xliff:g>‎‏‎‎‏‏‏‎ app is active‎‏‎‎‏‎</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎New information‎‏‎‎‏‎"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎Active apps‎‏‎‎‏‎"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‏‎‎‏‎‏‎‎‎Even if you’re not using these apps, they’re still active and might affect battery life‎‏‎‎‏‎"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‎Stop‎‏‎‎‏‎"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‎‎Stopped‎‏‎‎‏‎"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎Done‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index f2c7236..4e01b79 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres retomar la sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo de Invitado"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Estás en el modo de invitado"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"¿Agregar usuario nuevo?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Cuando agregas un nuevo usuario, esa persona debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si agregas un usuario nuevo, se desactivará el modo de invitado y se borrarán todas las apps y los datos de la sesión de invitado actual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Alcanzaste el límite de usuarios"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Puedes agregar hasta <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index f394e00..48024fb 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -33,15 +33,15 @@
     <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, gracias"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Girar pantalla automáticamente"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"¿Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"¿Quieres que <xliff:g id="APPLICATION">%1$s</xliff:g> pueda acceder a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsta aplicación no tiene permisos para grabar, pero podría captar audio a través de este dispositivo USB."</string>
+    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"¿Quieres que <xliff:g id="APPLICATION">%1$s</xliff:g> pueda acceder a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsta aplicación no tiene permisos para grabar, pero podría capturar audio a través de este dispositivo USB."</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"¿Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"¿Abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para gestionar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Esta aplicación no tiene permiso para grabar, pero podría registrar audio con este dispositivo USB. Si usas <xliff:g id="APPLICATION">%1$s</xliff:g> en este dispositivo, puede que no oigas llamadas, notificaciones ni alarmas."</string>
+    <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"¿Abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para controlar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Esta aplicación no tiene permiso para grabar, pero podría capturar audio con este dispositivo USB. Si usas <xliff:g id="APPLICATION">%1$s</xliff:g> en este dispositivo, puede que no oigas llamadas, notificaciones ni alarmas."</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Si usas <xliff:g id="APPLICATION">%1$s</xliff:g> en este dispositivo, puede que no oigas llamadas, notificaciones ni alarmas."</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"¿Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
-    <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"¿Quieres abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para utilizar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"¿Quieres abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para gestionar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsta aplicación no tiene permisos para grabar, pero puede capturar audio mediante este dispositivo USB."</string>
-    <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"¿Quieres abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para utilizar <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
+    <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"¿Abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para usar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+    <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"¿Abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para controlar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsta aplicación no tiene permisos para grabar, pero puede capturar audio mediante este dispositivo USB."</string>
+    <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"¿Abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para usar <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
     <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Ninguna aplicación instalada funciona con este accesorio USB. Más información: <xliff:g id="URL">%1$s</xliff:g>"</string>
     <string name="title_usb_accessory" msgid="1236358027511638648">"Accesorio USB"</string>
     <string name="label_view" msgid="6815442985276363364">"Ver"</string>
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirmar para completar la acción"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado con datos faciales. Pulsa el icono desbloquear para continuar."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado con la cara. Pulsa para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Cara reconocida. Pulsa para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Cara reconocida. Pulsa el icono de desbloquear para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Se ha autenticado"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar patrón"</string>
@@ -173,7 +170,7 @@
     <string name="accessibility_not_connected" msgid="4061305616351042142">"No conectado"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Desactivados"</string>
-    <string name="accessibility_airplane_mode" msgid="1899529214045998505">"Modo avión"</string>
+    <string name="accessibility_airplane_mode" msgid="1899529214045998505">"Modo Avión"</string>
     <string name="accessibility_vpn_on" msgid="8037549696057288731">"La red VPN está activada."</string>
     <string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> por ciento de batería"</string>
     <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Queda un <xliff:g id="PERCENTAGE">%1$s</xliff:g> por ciento de batería (<xliff:g id="TIME">%2$s</xliff:g> aproximadamente según tu uso)"</string>
@@ -181,7 +178,7 @@
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"Ver todas las notificaciones"</string>
     <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletipo habilitado"</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Modo vibración"</string>
-    <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Modo silencio"</string>
+    <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Modo Silencio"</string>
     <!-- no translation found for accessibility_casting (8708751252897282313) -->
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Pantalla de notificaciones"</string>
@@ -290,7 +287,7 @@
     <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Grabar pantalla"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Detener"</string>
-    <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modo una mano"</string>
+    <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modo Una mano"</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>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pulsa el icono desbloquear para abrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado con datos faciales. Pulsa el icono desbloquear para abrir."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado con la cara. Pulsa para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Cara reconocida. Pulsa para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Cara reconocida. Pulsa el icono de desbloquear para abrir."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volverlo a intentar"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea para usar el NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres continuar con la sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo Invitados"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Estás en modo Invitados"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"¿Añadir nuevo usuario?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Al añadir un nuevo usuario, debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de usuarios."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si añades un usuario nuevo, saldrás del modo Invitados y se eliminarán todas las aplicaciones y datos de la sesión de invitado actual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Has alcanzado el límite de usuarios"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Puedes añadir hasta <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
@@ -462,9 +461,9 @@
     <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Las llamadas y las notificaciones sonarán (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Configurador de UI del sistema"</string>
     <string name="status_bar" msgid="4357390266055077437">"Barra de estado"</string>
-    <string name="demo_mode" msgid="263484519766901593">"Modo de demostración de UI del sistema"</string>
-    <string name="enable_demo_mode" msgid="3180345364745966431">"Habilitar modo demo"</string>
-    <string name="show_demo_mode" msgid="3677956462273059726">"Mostrar modo demo"</string>
+    <string name="demo_mode" msgid="263484519766901593">"Modo Demo de UI del sistema"</string>
+    <string name="enable_demo_mode" msgid="3180345364745966431">"Habilitar modo Demo"</string>
+    <string name="show_demo_mode" msgid="3677956462273059726">"Mostrar modo Demo"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
     <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
@@ -477,7 +476,7 @@
     <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Ajustes de pantalla de bloqueo"</string>
     <string name="qr_code_scanner_title" msgid="5290201053875420785">"Escanear código QR"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
-    <string name="status_bar_airplane" msgid="4848702508684541009">"Modo avión"</string>
+    <string name="status_bar_airplane" msgid="4848702508684541009">"Modo Avión"</string>
     <string name="zen_alarm_warning" msgid="7844303238486849503">"No oirás la próxima alarma (<xliff:g id="WHEN">%1$s</xliff:g>)"</string>
     <string name="alarm_template" msgid="2234991538018805736">"a las <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioridad"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admite funciones de conversación"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificaciones no se pueden modificar."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Las notificaciones de llamada no se pueden modificar."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Este grupo de notificaciones no se puede configurar aquí"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notificación mediante proxy"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Todas las notificaciones de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -593,7 +591,7 @@
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendario"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"No molestar"</string>
-    <string name="volume_dnd_silent" msgid="4154597281458298093">"Combinación de teclas para los botones de volumen"</string>
+    <string name="volume_dnd_silent" msgid="4154597281458298093">"Acceso directo de los botones de volumen"</string>
     <string name="battery" msgid="769686279459897127">"Batería"</string>
     <string name="headset" msgid="4485892374984466437">"Auriculares"</string>
     <string name="accessibility_long_click_tile" msgid="210472753156768705">"Abrir ajustes"</string>
@@ -919,11 +917,11 @@
     <string name="see_all_networks" msgid="3773666844913168122">"Ver todo"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Para cambiar de red, desconecta el cable Ethernet"</string>
     <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para mejorar la experiencia con el dispositivo, las aplicaciones y los servicios podrán buscar redes Wi-Fi en cualquier momento, aunque la conexión Wi-Fi esté desactivada. Puedes cambiar esto en los ajustes de búsqueda de redes Wi-Fi. "<annotation id="link">"Cambiar"</annotation></string>
-    <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Desactivar modo avión"</string>
+    <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Desactivar modo Avión"</string>
     <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> quiere añadir el siguiente recuadro a ajustes rápidos"</string>
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Añadir recuadro"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"No añadir recuadro"</string>
-    <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Seleccionar usuario"</string>
+    <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Selecciona un usuario"</string>
     <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Información nueva"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicaciones activas"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 8a47781..4ea3786 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Kinnitatud"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Lõpuleviimiseks puudutage nuppu Kinnita"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Avati näoga. Jätkamiseks vajutage avamise ikooni."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avati näoga. Vajutage jätkamiseks."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nägu tuvastati. Vajutage jätkamiseks."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nägu tuvastati. Jätkamiseks vajutage avamise ikooni."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenditud"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Kasuta PIN-koodi"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Kasuta mustrit"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Pühkige avamiseks üles"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Avamiseks vajutage avamise ikooni"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Avati näoga. Avamiseks vajutage avamise ikooni."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Avati näoga. Avamiseks vajutage."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Nägu tuvastati. Avamiseks vajutage."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Nägu tuvastati. Avamiseks vajutage avamise ikooni."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Uuesti proovimiseks pühkige üles"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC kasutamiseks avage."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"See seade kuulub teie organisatsioonile"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Kas soovite seansiga jätkata?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Alusta uuesti"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Jah, jätka"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Külalisrežiim"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Olete külalisrežiimis"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Kas lisada uus kasutaja?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kui lisate uue kasutaja, siis peab ta seadistama oma ruumi.\n\nIga kasutaja saab värskendada rakendusi kõigi kasutajate jaoks."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Uue kasutaja lisamisel suletakse külalisrežiim ning praeguse külastajaseansi rakendused ja andmed kustutatakse."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Kasutajate limiit on täis"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Võite lisada kuni <xliff:g id="COUNT">%d</xliff:g> kasutajat.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteetne"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei toeta vestlusfunktsioone"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Neid märguandeid ei saa muuta."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Kõnemärguandeid ei saa muuta."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Seda märguannete rühma ei saa siin seadistada"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Puhvriga märguanne"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Kõik rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> märguanded"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index d832aac..28100aa 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Berretsita"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Amaitzeko, sakatu \"Berretsi\""</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Aurpegiaren bidez desblokeatu da. Aurrera egiteko, sakatu desblokeatzeko ikonoa."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Aurpegiaren bidez desblokeatu da. Sakatu aurrera egiteko."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ezagutu da aurpegia. Sakatu aurrera egiteko."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ezagutu da aurpegia. Aurrera egiteko, sakatu desblokeatzeko ikonoa."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikatuta"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Erabili PINa"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Erabili eredua"</string>
@@ -284,7 +281,7 @@
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Desaktibatze-ordua: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Aktibatuta lo egiteko garaian"</string>
     <string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"Lo egiteko garaia amaitzen den arte"</string>
-    <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
+    <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFCa"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Desgaituta dago NFC"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Gaituta dago NFC"</string>
     <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Pantaila-grabaketa"</string>
@@ -318,14 +315,11 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Pasatu hatza gora irekitzeko"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Irekitzeko, sakatu desblokeatzeko ikonoa"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Aurpegiaren bidez desblokeatu da. Irekitzeko, sakatu desblokeatzeko ikonoa."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Aurpegiaren bidez desblokeatu da. Sakatu irekitzeko."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ezagutu da aurpegia. Sakatu irekitzeko."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ezagutu da aurpegia. Irekitzeko, sakatu desblokeatzeko ikonoa."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Berriro saiatzeko, pasatu hatza gora"</string>
-    <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desblokea ezazu NFC erabiltzeko"</string>
+    <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desblokea ezazu NFCa erabiltzeko"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Gailu hau zure erakundearena da"</string>
     <string name="do_disclosure_with_name" msgid="2091641464065004091">"Gailu hau <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundearena da"</string>
     <string name="do_financed_disclosure_with_name" msgid="6723004643314467864">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundeak eman du gailu hau"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Saioarekin jarraitu nahi duzu?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Hasi berriro"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Bai, jarraitu"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gonbidatu modua"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Gonbidatu moduan zaude"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Beste erabiltzaile bat gehitu?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Erabiltzaile bat gehitzen duzunean, erabiltzaile horrek bere eremua konfiguratu beharko du.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Beste erabiltzaile bat gehituz gero, gonbidatu modua itxiko da eta oraingo gonbidatuentzako saioko aplikazio eta datu guztiak ezabatuko dira."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Erabiltzaile-mugara iritsi zara"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Gehienez, <xliff:g id="COUNT">%d</xliff:g> erabiltzaile gehi ditzakezu.</item>
@@ -436,7 +435,7 @@
     <string name="screen_pinning_positive" msgid="3285785989665266984">"Ados"</string>
     <string name="screen_pinning_negative" msgid="6882816864569211666">"Ez, eskerrik asko"</string>
     <string name="screen_pinning_start" msgid="7483998671383371313">"Ainguratu da aplikazioa"</string>
-    <string name="screen_pinning_exit" msgid="4553787518387346893">"Kendu da aplikazioaren aingura"</string>
+    <string name="screen_pinning_exit" msgid="4553787518387346893">"Kendu zaio aingura aplikazioari"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"Deia"</string>
     <string name="stream_system" msgid="7663148785370565134">"Sistema"</string>
     <string name="stream_ring" msgid="7550670036738697526">"Jo tonua"</string>
@@ -503,7 +502,7 @@
     <string name="notification_alert_title" msgid="3656229781017543655">"Lehenetsia"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatikoa"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ez du tonurik jotzen edo dar-dar egiten"</string>
-    <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ez du tonurik jotzen edo dar-dar egiten, eta elkarrizketaren atalaren behealdean agertzen da"</string>
+    <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ez du tonurik jotzen edo dar-dar egiten, eta elkarrizketen atalaren behealdean agertzen da"</string>
     <string name="notification_channel_summary_default" msgid="3282930979307248890">"Tonua jo edo dar-dar egin dezake, telefonoaren ezarpenen arabera"</string>
     <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Tonua jo edo dar-dar egin dezake, telefonoaren ezarpenen arabera. Modu lehenetsian, <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioko elkarrizketak burbuila gisa agertzen dira."</string>
     <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Ezarri sistemak zehaztu dezala jakinarazpen honek soinua edo dardara egin behar duen ala ez"</string>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Lehentasuna"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak ez ditu onartzen elkarrizketetarako eginbideak"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Jakinarazpen horiek ezin dira aldatu."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Deien jakinarazpenak ezin dira aldatu."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Jakinarazpen talde hau ezin da konfiguratu hemen"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Proxy bidezko jakinarazpena"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren jakinarazpen guztiak"</string>
@@ -848,7 +846,7 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parekatu beste gailu batekin"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Saioa ireki nahi baduzu, ireki aplikazioa."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikazio ezezaguna"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Utzi igortzeari"</string>
+    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Gelditu igorpena"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Nola funtzionatzen dute iragarpenek?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Iragarri"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth bidezko gailu bateragarriak dituzten inguruko pertsonek iragartzen ari zaren multimedia-edukia entzun dezakete"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 93b0b66..95e8f0c 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4811759950673118541">"میانای کاربر سیستم"</string>
+    <string name="app_label" msgid="4811759950673118541">"واسط کاربری سیستم"</string>
     <string name="battery_low_title" msgid="5319680173344341779">"«بهینه‌سازی باتری» روشن شود؟"</string>
     <string name="battery_low_description" msgid="3282977755476423966">"<xliff:g id="PERCENTAGE">%s</xliff:g> از باتری‌تان باقی مانده است. «بهینه‌سازی باتری» زمینه تیره را روشن می‌کند، فعالیت‌های پس‌زمینه را محدود می‌کند، و اعلان‌ها را به‌تأخیر می‌اندازد."</string>
     <string name="battery_low_intro" msgid="5148725009653088790">"«بهینه‌سازی باتری» زمینه «تیره» را روشن می‌کند، فعالیت‌های پس‌زمینه را محدود می‌کند، و اعلان‌ها را به‌تأخیر می‌اندازد."</string>
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"آیا می‌خواهید جلسه‌تان را ادامه دهید؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"شروع مجدد"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"بله، ادامه داده شود"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"حالت مهمان"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"در حالت مهمان هستید"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"کاربر جدیدی اضافه می‌کنید؟"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"وقتی کاربر جدیدی اضافه می‌کنید آن فرد باید فضای خودش را تنظیم کند.\n\nهر کاربری می‌تواند برنامه‌ها را برای همه کاربران دیگر به‌روزرسانی کند."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"با افزودن کاربر جدید، از حالت مهمان خارج خواهید شد و همه برنامه‌ها و داده‌ها از جلسه مهمان کنونی حذف خواهند شد."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"به تعداد مجاز تعداد کاربر رسیده‌اید"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">می‌توانید حداکثر <xliff:g id="COUNT">%d</xliff:g> کاربر اضافه کنید.</item>
@@ -454,9 +459,9 @@
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"لرزش"</string>
     <string name="volume_dialog_title" msgid="6502703403483577940">"‏%s کنترل‌های میزان صدا"</string>
     <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"تماس‌ها و اعلان‌ها زنگ می‌خورند (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
-    <string name="system_ui_tuner" msgid="1471348823289954729">"تنظیم‌کننده میانای کاربری سیستم"</string>
+    <string name="system_ui_tuner" msgid="1471348823289954729">"تنظیم‌کننده واسط کاربری سیستم"</string>
     <string name="status_bar" msgid="4357390266055077437">"نوار وضعیت"</string>
-    <string name="demo_mode" msgid="263484519766901593">"حالت نمایشی میانای کاربر سیستم"</string>
+    <string name="demo_mode" msgid="263484519766901593">"حالت نمایشی واسط کاربری سیستم"</string>
     <string name="enable_demo_mode" msgid="3180345364745966431">"فعال کردن حالت نمایشی"</string>
     <string name="show_demo_mode" msgid="3677956462273059726">"نمایش حالت نمایشی"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"اترنت"</string>
@@ -478,12 +483,12 @@
     <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"نقطه اتصال"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"نمایه کاری"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"برای بعضی افراد سرگرم‌کننده است اما نه برای همه"</string>
-    <string name="tuner_warning" msgid="1861736288458481650">"‏«تنظیم‌کننده میانای کاربری سیستم» روش‌های بیشتری برای تنظیم دقیق و سفارشی کردن واسط کاربری Android در اختیار شما قرار می‌دهد. ممکن است این ویژگی‌های آزمایشی تغییر کنند، خراب شوند یا در نسخه‌های آینده جود نداشته باشند. با احتیاط ادامه دهید."</string>
+    <string name="tuner_warning" msgid="1861736288458481650">"‏«تنظیم‌کننده واسط کاربری سیستم» روش‌های بیشتری برای تنظیم دقیق و سفارشی کردن واسط کاربری Android در اختیار شما قرار می‌دهد. ممکن است این ویژگی‌های آزمایشی تغییر کنند، خراب شوند یا در نسخه‌های آینده جود نداشته باشند. با احتیاط ادامه دهید."</string>
     <string name="tuner_persistent_warning" msgid="230466285569307806">"ممکن است این قابلیت‌های آزمایشی تغییر کنند، خراب شوند یا در نسخه‌های آینده وجود نداشته باشد. بااحتیاط ادامه دهید."</string>
     <string name="got_it" msgid="477119182261892069">"متوجه شدم"</string>
-    <string name="tuner_toast" msgid="3812684836514766951">"تبریک می‌گوییم! «تنظیم‌کننده میانای کاربری سیستم» به «تنظیمات» اضافه شد"</string>
+    <string name="tuner_toast" msgid="3812684836514766951">"تبریک! «تنظیم‌کننده واسط کاربری سیستم» به «تنظیمات» اضافه شد"</string>
     <string name="remove_from_settings" msgid="633775561782209994">"حذف از تنظیمات"</string>
-    <string name="remove_from_settings_prompt" msgid="551565437265615426">"«تنظیم‌کننده میانای کاربری سیستم» از تنظیمات حذف شود و همه ویژگی‌های آن متوقف شوند؟"</string>
+    <string name="remove_from_settings_prompt" msgid="551565437265615426">"«تنظیم‌کننده واسط کاربری سیستم» از «تنظیمات» حذف شود و استفاده از همه ویژگی‌های آن متوقف شود؟"</string>
     <string name="enable_bluetooth_title" msgid="866883307336662596">"بلوتوث روشن شود؟"</string>
     <string name="enable_bluetooth_message" msgid="6740938333772779717">"برای مرتبط کردن صفحه‌کلید با رایانه لوحی، ابتدا باید بلوتوث را روشن کنید."</string>
     <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"روشن کردن"</string>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> برنامه فعال است</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> برنامه فعال است</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"اطلاعات جدید"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"برنامه‌های فعال"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"حتی اگر از این برنامه‌ها استفاده نمی‌کنید، این برنامه‌ها همچنان فعال هستند و ممکن است بر عمر باتری تأثیر بگذارند"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"متوقف کردن"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"متوقف شده"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"تمام"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index b9b0071..b9f665b 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Haluatko jatkaa istuntoa?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Aloita alusta"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Kyllä, haluan jatkaa"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Vierastila"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Olet vierastilassa"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Lisätäänkö uusi käyttäjä?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Uuden käyttäjän lisääminen poistaa sinut vierastilasta. Kaikki sovellukset ja data poistetaan myös samalla nykyisestä vierailija-käyttökerrasta."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Käyttäjäraja saavutettu"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Voit lisätä korkeintaan <xliff:g id="COUNT">%d</xliff:g> käyttäjää.</item>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 071b445..7ec735b 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmé"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Touchez Confirmer pour terminer"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Déverrouillé avec le visage. Appuyez Déverrouiller pour cont."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverrouillé avec le visage. Appuyez pour continuer."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur Déverrouiller pour continuer."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utiliser un NIP"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utiliser un schéma"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Balayez l\'écran vers le haut pour ouvrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Appuyez sur l\'icône Déverrouiller pour ouvrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Déverrouillé avec le visage. Appuyez Déverrouiller pour ouvrir"</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Déverrouillé avec le visage. Appuyez pour ouvrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Visage reconnu. Appuyez pour ouvrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Visage reconnu. Appuyez sur Déverrouiller pour ouvrir."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour utiliser la CCP"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recommencer"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oui, continuer"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mode Invité"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Vous êtes en mode Invité"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Ajouter un utilisateur?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nTout utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"L\'ajout d\'un nouvel utilisateur aura pour effet de quitter le mode Invité ainsi que de supprimer toutes les applications et données de la session d\'invité en cours."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite d\'utilisateurs atteinte"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Vous pouvez ajouter jusqu\'à <xliff:g id="COUNT">%d</xliff:g> utilisateur.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritaire"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne prend pas en charge les fonctionnalités de conversation"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ces notifications ne peuvent pas être modifiées"</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Les notifications d\'appel ne peuvent pas être modifiées."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ce groupe de notifications ne peut pas être configuré ici"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notification par mandataire"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Toutes les notifications de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index c042f4a..e09a5e4 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -319,7 +319,7 @@
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Visage reconnu. Appuyez pour ouvrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Visage reconnu. Appuyez sur l\'icône de déverrouillage pour ouvrir."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
-    <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour pouvoir utiliser NFC"</string>
+    <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour pouvoir utiliser la NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string>
     <string name="do_disclosure_with_name" msgid="2091641464065004091">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="do_financed_disclosure_with_name" msgid="6723004643314467864">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la dernière session ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Non, nouvelle session"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oui, continuer"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mode Invité"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Vous êtes en mode Invité"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Ajouter un utilisateur ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nN\'importe quel utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si vous ajoutez un utilisateur, le mode Invité sera désactivé et toutes les applis et les données de la session Invité actuelle seront supprimées."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite nombre utilisateurs atteinte"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Vous pouvez ajouter <xliff:g id="COUNT">%d</xliff:g> profil utilisateur.</item>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 5b47e52..06221f5 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Queres continuar coa túa sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Comezar de novo"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Si, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo de convidado"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Estás usando o modo de convidado"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Engadir un usuario novo?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Cando engadas un usuario novo, este deberá configurar o seu espazo.\n\nCalquera usuario pode actualizar as aplicacións para todos os demais usuarios."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ao engadir un usuario novo, sairás do modo de convidado e eliminaranse todas as aplicacións e datos da sesión de convidado actual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Alcanzouse o límite de usuarios"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Podes engadir ata <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index aee9c0d..f6f2510 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"પુષ્ટિ કરી"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"પરીક્ષણ પૂર્ણ કરવા કન્ફર્મ કરોને ટૅપ કરો"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ચહેરા દ્વારા અનલૉક કર્યું. આગળ વધવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ચહેરા દ્વારા અનલૉક કર્યું. આગળ વધવા માટે દબાવો."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ચહેરો ઓળખ્યો. આગળ વધવા માટે દબાવો."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ચહેરો ઓળખ્યો. આગળ વધવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"પ્રમાણિત"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"પિનનો ઉપયોગ કરો"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"પૅટર્નનો ઉપયોગ કરો"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ખોલવા માટે \'અનલૉક કરો\' આઇકન દબાવો"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા માટે દબાવો."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ચહેરો ઓળખ્યો. ખોલવા માટે દબાવો."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ચહેરો ઓળખ્યો. ખોલવા માટે \'અનલૉક કરો\' આઇકન દબાવો."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"ફરી પ્રયાસ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCનો ઉપયોગ કરવા માટે અનલૉક કરો"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"શું તમે તમારું સત્ર ચાલુ રાખવા માંગો છો?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"શરૂ કરો"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"હા, ચાલુ રાખો"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"અતિથિ મોડ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"તમે અતિથિ મોડમાં છો"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"નવા વપરાશકર્તાને ઉમેરીએ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમનું સ્થાન સેટ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા બધા અન્ય વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"કોઈ નવા વપરાશકર્તાને ઉમેરવાથી અતિથિ મોડમાંથી નીકળી જવાશે તેમજ હાલના અતિથિ સત્રમાંથી તમામ ઍપ અને ડેટા ડિલીટ થઈ જશે."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"વપરાશકર્તા સંખ્યાની મર્યાદા"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">તમે <xliff:g id="COUNT">%d</xliff:g> વપરાશકર્તા સુધી ઉમેરી શકો છો.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"પ્રાધાન્યતા"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> વાતચીતની સુવિધાઓને સપોર્ટ આપતી નથી"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"આ નોટિફિકેશનમાં કોઈ ફેરફાર થઈ શકશે નહીં."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"કૉલના નોટિફિકેશનમાં કોઈ ફેરફાર કરી શકાતો નથી."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"નોટિફિકેશનના આ ગ્રૂપની ગોઠવણી અહીં કરી શકાશે નહીં"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"પ્રૉક્સી નોટિફિકેશન"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"<xliff:g id="APP_NAME">%1$s</xliff:g>ના બધા નોટિફિકેશન"</string>
@@ -819,8 +817,7 @@
     <string name="controls_media_button_pause" msgid="8614887780950376258">"થોભાવો"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"પહેલાનો ટ્રૅક"</string>
     <string name="controls_media_button_next" msgid="6662636627525947610">"આગલો ટ્રૅક"</string>
-    <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
-    <skip />
+    <string name="controls_media_button_connecting" msgid="3138354625847598095">"કનેક્ટ કરી રહ્યાં છીએ"</string>
     <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"ચલાવો"</string>
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ખોલો"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચલાવો"</string>
@@ -925,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ઍપ સક્રિય છે</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ઍપ સક્રિય છે</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"નવી માહિતી"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"સક્રિય ઍપ"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"ભલે તમે આ બધી ઍપનો ઉપયોગ ન કરી રહ્યાં હો, તેમ છતાં તે સક્રિય રહે છે અને તેને કારણે બૅટરી આવરદા પર અસર થઈ શકે છે"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"રોકો"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"બંધ કરેલી છે"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"થઈ ગયું"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 8f90f62..5fc6e0a8 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि हो गई"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"\'पुष्टि करें\' पर टैप करके पूरा करें"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"चेहरे से अनलॉक किया. जारी रखने के लिए, अनलॉक आइकॉन को दबाएं."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहरे से अनलॉक किया गया. जारी रखने के लिए टैप करें."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरे की पहचान हो गई. जारी रखने के लिए टैप करें."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरे की पहचान हो गई. जारी रखने के लिए अनलॉक आइकॉन को टैप करें."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"पुष्टि हो गई"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"पिन इस्तेमाल करें"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"पैटर्न इस्तेमाल करें"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"खोलने के लिए ऊपर स्वाइप करें"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहरे से अनलॉक किया. डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहरे से अनलॉक किया गया. डिवाइस खोलने के लिए टैप करें."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरे की पहचान हो गई. डिवाइस खोलने के लिए टैप करें."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"चेहरे की पहचान हो गई. डिवाइस खोलने के लिए अनलॉक आइकॉन को टैप करें."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"फिर से कोशिश करने के लिए ऊपर की ओर स्वाइप करें"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"एनएफ़सी इस्तेमाल करने के लिए स्क्रीन को अनलॉक करें"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है"</string>
@@ -345,11 +339,16 @@
     <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • धीरे चार्ज हो रहा है • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> में पूरा चार्ज हो जाएगा"</string>
     <string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • डॉक पर चार्ज हो रहा है • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> में पूरा चार्ज हो जाएगा"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"उपयोगकर्ता बदलें"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सत्र के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सेशन के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"मेहमान, आपका फिर से स्वागत है!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"क्‍या आप अपना सत्र जारी रखना चाहते हैं?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"फिर से शुरू करें"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हां, जारी रखें"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"मेहमान मोड"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"आप मेहमान मोड में हैं"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"नया उपयोगकर्ता जोड़ें?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"कोई नया उपयोगकर्ता जोड़ने पर, उसे अपनी जगह सेट करनी होती है.\n\nकोई भी उपयोगकर्ता बाकी सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"किसी नए उपयोगकर्ता को जोड़ने पर, मेहमान मोड को बंद कर दिया जाएगा. साथ ही, मेहमान के तौर पर ब्राउज़ करने के मौजूदा सेशन से, सभी ऐप्लिकेशन और डेटा को मिटा दिया जाएगा."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"अब और उपयोगकर्ता नहीं जोड़े जा सकते"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">आप ज़्यादा से ज़्यादा <xliff:g id="COUNT">%d</xliff:g> उपयोगकर्ता जोड़ सकते हैं.</item>
@@ -425,7 +424,7 @@
     <string name="screen_pinning_title" msgid="9058007390337841305">"ऐप्लिकेशन पिन किया गया है"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"इससे वह तब तक दिखता रहता है, जब तक कि आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, \'वापस जाएं\' और \'खास जानकारी\' को दबाकर रखें."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"इससे वह तब तक दिखाई देती है जब तक आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, होम और वापस जाएं वाले बटन को दबाकर रखें."</string>
-    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"इससे ऐप्लिकेशन की स्क्रीन तब तक दिखाई देती है, जब तक आप उसे अनपिन नहीं करते. अनपिन करने के लिए ऊपर स्वाइप करें और स्क्रीन दबाकर रखें."</string>
+    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"इससे ऐप्लिकेशन की स्क्रीन तब तक दिखती है, जब तक उसे अनपिन नहीं किया जाता. अनपिन करने के लिए ऊपर स्वाइप करें और स्क्रीन दबाकर रखें."</string>
     <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"इससे वह तब तक दिखता रहता है जब तक कि आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, \'खास जानकारी\' को दबाकर रखें."</string>
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"इससे वह तब तक दिखाई देती है जब तक आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, होम बटन को दबाकर रखें."</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"निजी डेटा ऐक्सेस किया जा सकता है, जैसे कि संपर्क और ईमेल का कॉन्टेंट."</string>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर बातचीत की सुविधाएं काम नहीं करतीं"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ये सूचनाएं नहीं बदली जा सकती हैं."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कॉल से जुड़ी सूचनाओं को ब्लॉक नहीं किया जा सकता."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"सूचनाओं के इस समूह को यहां कॉन्फ़िगर नहीं किया जा सकता"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"प्रॉक्सी सूचना"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"सभी <xliff:g id="APP_NAME">%1$s</xliff:g> सूचनाएं"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index e0cd639..6ac13ab 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -341,11 +341,16 @@
     <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • sporo punjenje • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do napunjenosti"</string>
     <string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Priključna stanica za punjenje • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do napunjenosti"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Promjena korisnika"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji bit će izbrisani."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Izbrisat će se sve aplikacije i podaci u ovoj sesiji."</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli natrag, gostu!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Način rada za goste"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Upotrebljavate način rada za goste"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Dodati novog korisnika?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kada dodate novog korisnika, ta osoba mora postaviti vlastiti prostor.\n\nBilo koji korisnik može ažurirati aplikacije za sve ostale korisnike."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ako dodate novog korisnika, napustit ćete način rada za goste i izbrisat će se svi podaci i aplikacije iz trenutačne gostujuće sesije."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dosegnuto je ograničenje korisnika"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
@@ -577,7 +582,7 @@
     <string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"Ukloni privitak"</string>
     <string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"Sustav"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"Početni zaslon"</string>
-    <string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"Najnovije"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"Nedavno"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"Natrag"</string>
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Obavijesti"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Tipkovni prečaci"</string>
@@ -923,11 +928,14 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj pločicu"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nemoj dodati pločicu"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Odabir korisnika"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivna</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikacije su aktivne</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivno</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Čak i ako ne korististite te aplikacije, one su i dalje aktivne i mogu utjecati na trajanje baterije"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zaustavi"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zaustavljeno"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Gotovo"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index bc8f8ef..b0dbdaa 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Folytatja a munkamenetet?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Újrakezdés"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Igen, folytatom"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Vendég mód"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Vendég módban van"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Új felhasználó hozzáadása?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Ha új felhasználót ad hozzá, az illetőnek be kell állítania saját tárterületét.\n\nBármely felhasználó frissítheti az alkalmazásokat valamennyi felhasználó számára."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Új felhasználó felvételével kilép a vendég módból, és az aktuális vendégmunkamenetből származó összes alkalmazás és adat törlődik majd."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Maximális felhasználószám elérve"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Legfeljebb <xliff:g id="COUNT">%d</xliff:g> felhasználót adhat hozzá.</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Mozaik hozzáadása"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne legyen hozzáadva"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Felhasználóválasztás"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> alkalmazás aktív</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> alkalmazás aktív</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Új információ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktív alkalmazások"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Még ha nem is használja ezeket az alkalmazásokat, továbbra is aktívak maradnak, és hatással lehetnek az akkumulátor élettartamára"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Leállítás"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Leállítva"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Kész"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 8a6949a..e75f204 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -339,11 +339,16 @@
     <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Դանդաղ լիցքավորում • Մնացել է <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Լիցքավորում դոկ-կայանի միջոցով • Մնացել է <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Անջատել օգտվողին"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր ծրագրերն ու տվյալները կջնջվեն:"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն:"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Բարի վերադարձ, հյուր"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Շարունակե՞լ աշխատաշրջանը։"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Վերսկսել"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Այո, շարունակել"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Հյուրի ռեժիմ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Դուք հյուրի ռեժիմում եք"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Ավելացնե՞լ նոր օգտատեր"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Երբ նոր օգտատեր եք ավելացնում, նա պետք է կարգավորի իր պրոֆիլը:\n\nՑանկացած օգտատեր կարող է թարմացնել հավելվածները մյուս բոլոր հաշիվների համար:"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ավելացնելով նոր օգտատեր՝ դուք դուրս կգաք հյուրի ռեժիմից։ Հյուրի ընթացիկ աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն։"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Սահմանաչափը սպառված է"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Հնարավոր է ավելացնել առավելագույնը <xliff:g id="COUNT">%d</xliff:g> օգտատեր։</item>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 59a3ede..915d638 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -266,7 +266,7 @@
     <string name="quick_settings_cellular_detail_over_limit" msgid="4561921367680636235">"Melebihi batas"</string>
     <string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"<xliff:g id="DATA_USED">%s</xliff:g> digunakan"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Batas <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Peringatan <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Peri­ngatan <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Aplikasi kerja"</string>
     <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Cahaya Malam"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Aktif saat malam"</string>
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Lanjutkan sesi Anda?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulai ulang"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ya, lanjutkan"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mode tamu"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Anda sedang menggunakan mode tamu"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Tambahkan pengguna baru?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruangnya sendiri.\n\nPengguna mana pun dapat mengupdate aplikasi untuk semua pengguna lain."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Menambahkan pengguna baru akan membuat Anda keluar dari mode tamu dan menghapus semua aplikasi serta data dari sesi tamu saat ini."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Batas pengguna tercapai"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Anda dapat menambahkan hingga <xliff:g id="COUNT">%d</xliff:g> pengguna.</item>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 779de2d..41ecdfb 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Viltu halda áfram með lotuna?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Byrja upp á nýtt"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Já, halda áfram"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gestastilling"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Þú ert í gestastillingu"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Bæta nýjum notanda við?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Þegar þú bætir nýjum notanda við þarf sá notandi að setja upp svæðið sitt.\n\nHvaða notandi sem er getur uppfært forrit fyrir alla aðra notendur."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Þegar nýjum notanda er bætt við er gestastillingu lokað og öllum forritum og gögnum úr núverandi gestalotu eytt."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Notandahámarki náð"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Þú getur bætt við allt að <xliff:g id="COUNT">%d</xliff:g> notanda.</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Bæta reit við"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ekki bæta reit við"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Velja notanda"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> forrit virkt</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> forrit virk</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nýjar upplýsingar"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Virk forrit"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Forritin eru virk og geta haft áhrif á rafhlöðuendingu jafnvel þótt þú sért ekki að nota þau"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stöðva"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stöðvað"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Lokið"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index c24dd86..a2d1083 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vuoi continuare la sessione?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Ricomincia"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sì, continua"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modalità Ospite"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Sei in modalità Ospite"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Aggiungere un nuovo utente?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Il nuovo utente, una volta aggiunto, deve configurare il proprio spazio.\n\nQualsiasi utente può aggiornare le app per tutti gli altri."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Se aggiungi un nuovo utente, la modalità Ospite viene disattivata e vengono eliminati tutti i dati e le app della sessione Ospite corrente."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite di utenti raggiunto"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Puoi aggiungere fino a <xliff:g id="COUNT">%d</xliff:g> utenti.</item>
@@ -423,7 +428,7 @@
     <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"La schermata rimane visibile finché non viene sganciata. Per sganciarla, tieni premuto Panoramica."</string>
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"La schermata rimane visibile finché non viene disattivato il blocco su schermo. Per disattivarlo, tocca e tieni premuto Home."</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"I dati personali potrebbero essere accessibili (ad esempio i contatti e i contenuti delle email)."</string>
-    <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"L\'app bloccata su schermo potrebbe aprire altre app."</string>
+    <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"L\'app bloccata sullo schermo potrebbe aprire altre app."</string>
     <string name="screen_pinning_toast" msgid="8177286912533744328">"Per sbloccare questa app, tocca e tieni premuti i pulsanti Indietro e Panoramica"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Per sbloccare questa app, tocca e tieni premuti i pulsanti Indietro e Home"</string>
     <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Per sbloccare questa app, scorri verso l\'alto e tieni premuto"</string>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Aggiungi riquadro"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Non aggiungerlo"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Seleziona utente"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other">Ci sono <xliff:g id="COUNT_1">%s</xliff:g> app attive</item>
+      <item quantity="one">C\'è <xliff:g id="COUNT_0">%s</xliff:g> app attiva</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nuove informazioni"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"App attive"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Queste app sono ancora attive anche se non le stai usando e potrebbero incidere sulla durata della batteria"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Interrompi"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Interrotta"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Fine"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 76e6491..2c44732 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"יש אישור"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"יש להקיש על \'אישור\' לסיום התהליך"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"הנעילה בוטלה בזיהוי פנים. להמשך, לוחצים על סמל ביטול הנעילה."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"הנעילה בוטלה באמצעות זיהוי הפנים. יש ללחוץ כדי להמשיך."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"הפנים זוהו. יש ללחוץ כדי להמשיך."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"הפנים זוהו. להמשך יש ללחוץ על סמל ביטול הנעילה."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"מאומת"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"שימוש בקוד אימות"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"שימוש בקו ביטול נעילה"</string>
@@ -322,12 +319,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"לפתיחה, לוחצים על סמל ביטול הנעילה"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"הנעילה בוטלה בזיהוי פנים. פותחים בלחיצה על סמל ביטול הנעילה."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"הנעילה בוטלה באמצעות זיהוי הפנים. יש ללחוץ כדי לפתוח."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"הפנים זוהו. יש ללחוץ כדי לפתוח."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"הפנים זוהו. יש ללחוץ על סמל ביטול הנעילה כדי לפתוח."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"יש להחליק למעלה כדי לנסות שוב"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏יש לבטל את הנעילה כדי להשתמש ב-NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"המכשיר הזה שייך לארגון שלך"</string>
@@ -354,6 +348,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"האם ברצונך להמשיך בפעילות באתר?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"סשן חדש"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"כן, להמשיך"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"מצב אורח"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"התחברת במצב אורח"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"להוסיף משתמש חדש?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"כשמוסיפים משתמש חדש, המשתמש הזה צריך להגדיר את השטח שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"הוספת משתמש חדש תגרום ליציאה ממצב האורח ותמחק את כל האפליקציות והנתונים מהגלישה הנוכחית כאורח."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"הגעת למגבלת המשתמשים שניתן להוסיף"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="two">ניתן להוסיף עד <xliff:g id="COUNT">%d</xliff:g> משתמשים.</item>
@@ -524,8 +523,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"בעדיפות גבוהה"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא תומכת בתכונות השיחה"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"לא ניתן לשנות את ההתראות האלה."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"לא ניתן לשנות את התראות השיחה."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"לא ניתן להגדיר כאן את קבוצת ההתראות הזו"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"‏התראה דרך שרת proxy"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"כל ההתראות של <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index cb459e9..a5de27f4 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"確認しました"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"完了するには [確認] をタップしてください"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"顔でロック解除しました。ロック解除アイコンを押して続行します。"</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"顔でロック解除しました。押して続行してください。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"顔を認識しました。押して続行してください。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"顔を認識しました。ロック解除アイコンを押して続行します。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"認証済み"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN を使用"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"パターンを使用"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"開くには上にスワイプします"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ロック解除アイコンを押して開きます"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"顔でロック解除しました。ロック解除アイコンを押して開きます。"</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"顔でロック解除しました。押すと開きます。"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"顔を認識しました。押すと開きます。"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"顔を認識しました。ロック解除アイコンを押して開きます。"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"上にスワイプしてもう一度お試しください"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC を使用するには、ロックを解除してください"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"これは組織が所有するデバイスです"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"セッションを続行しますか?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"最初から開始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"続行"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ゲストモード"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ゲストモード使用中"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"新しいユーザーを追加しますか?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"新しく追加したユーザーは各自でスペースをセットアップする必要があります。\n\nすべてのユーザーは他のユーザーに代わってアプリを更新できます。"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"新しいユーザーを追加するとゲストモードは終了し、現在のゲスト セッションからすべてのアプリとデータが削除されます。"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ユーザー数が上限に達しました"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">最大 <xliff:g id="COUNT">%d</xliff:g> 人のユーザーを追加できます。</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>は会話機能に対応していません"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"これらの通知は変更できません。"</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"着信通知は変更できません。"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"このグループの通知はここでは設定できません"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"代理通知"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"<xliff:g id="APP_NAME">%1$s</xliff:g> のすべての通知"</string>
@@ -924,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> 個のアプリがアクティブです</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> 個のアプリがアクティブです</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"最新情報"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"実行中のアプリ"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"これらのアプリは、使用していない場合でもアクティブのままになるため、バッテリー駆動時間に影響する可能性があります"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"停止"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"停止中"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"完了"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 70a3ad6..42353fc 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"გსურთ, თქვენი სესიის გაგრძელება?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ხელახლა დაწყება"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"დიახ, გავაგრძელოთ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"სტუმრის რეჟიმი"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"თქვენ სტუმრის რეჟიმში ხართ"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"დაემატოს ახალი მომხმარებელი?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ახალი მომხმარებლის დამატებისას, ამ მომხმარებელს საკუთარი სივრცის შექმნა მოუწევს.\n\nნებისმიერ მომხმარებელს შეუძლია აპები ყველა სხვა მომხმარებლისათვის განაახლოს."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"თუ ახალ მომხმარებელს დაამატებთ, სტუმრის რეჟიმი დაიხურება და სტუმრის რეჟიმის მიმდინარე სესიიდან ყველა აპი და მონაცემი წაიშლება."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"მიღწეულია მომხმარებელთა ლიმიტი"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">შესაძლებელია <xliff:g id="COUNT">%d</xliff:g>-მდე მომხმარებლის დამატება.</item>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other">აქტიურია <xliff:g id="COUNT_1">%s</xliff:g> აპი</item>
+      <item quantity="one">აქტიურია <xliff:g id="COUNT_0">%s</xliff:g> აპი</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ახალი ინფორმაცია"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"აქტიური აპები"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"თუნდაც ამ აპებს არ იყენებდეთ, ისინი მაინც აქტიურია და ბატარეის მუშაობის ხანგრძლივობაზე ზემოქმედება შეუძლია"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"შეწყვეტა"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"შეწყვეტილია"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"მზადაა"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 9dbea98..42aaa0f 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Расталды"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Аяқтау үшін \"Растау\" түймесін түртіңіз."</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Бет үлгісі арқылы ашылды. Жалғастыру үшін құлыпты ашу белгішесін басыңыз."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Бетпен ашылды. Жалғастыру үшін басыңыз."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Бет танылды. Жалғастыру үшін басыңыз."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Бет танылды. Жалғастыру үшін құлыпты ашу белгішесін басыңыз."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификацияланған"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN кодын пайдалану"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Өрнекті пайдалану"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Ашу үшін жоғары қарай сырғытыңыз."</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Бет үлгісі арқылы ашылды. Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Бетпен ашылды. Ашу үшін басыңыз."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Бет танылды. Ашу үшін басыңыз."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Бет танылды. Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Әрекетті қайталау үшін жоғары сырғытыңыз."</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC пайдалану үшін құлыпты ашыңыз."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Бұл құрылғы ұйымыңызға тиесілі."</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансты жалғастыру керек пе?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Қайта бастау"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Иә, жалғастыру"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Қонақ режимі"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Сіз қонақ режиміндесіз"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Жаңа пайдаланушы қосылсын ба?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Жаңа пайдаланушыны қосқанда, сол адам өз кеңістігін реттеуі керек.\n\nКез келген пайдаланушы барлық басқа пайдаланушылар үшін қолданбаларды жаңарта алады."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Жаңа пайдаланушы қосылған кезде, қонақ режимі жабылады, ағымдағы қонақ сеансындағы барлық қолданба мен дерек жойылады."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Пайдаланушылар саны шегіне жетті"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> пайдаланушыға дейін енгізуге болады.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Маңызды"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> әңгіме функцияларын қолдамайды."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Бұл хабарландыруларды өзгерту мүмкін емес."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Қоңырау туралы хабарландыруларды өзгерту мүмкін емес."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Мұндай хабарландырулар бұл жерде конфигурацияланбайды."</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Прокси-сервер арқылы жіберілген хабарландыру"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Барлық <xliff:g id="APP_NAME">%1$s</xliff:g> хабарландырулары"</string>
@@ -924,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> қолданба қосылып тұр.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> қолданба қосылып тұр.</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Жаңа ақпарат"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Істеп тұрған қолданбалар"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Бұл қолданбаларды қолданып жатпасаңыз да, олар қосылып тұр және батарея жұмысының ұзақтығына әсер етуі мүмкін."</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Тоқтату"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Тоқтатылған"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Дайын"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 3d8504e..1b199e0 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"បានបញ្ជាក់"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ចុច \"បញ្ជាក់\" ដើម្បីបញ្ចប់"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"បានដោះសោ​ដោយប្រើមុខ។ សូមចុចរូបដោះសោ ដើម្បីបន្ត។"</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"បានដោះសោដោយប្រើមុខ។ សូមចុច ដើម្បីបន្ត។"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"បានស្គាល់មុខ។ សូមចុច ដើម្បីបន្ត។"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"បានស្គាល់មុខ។ សូមចុចរូបដោះសោ ដើម្បីបន្ត។"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"បាន​ផ្ទៀងផ្ទាត់"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ប្រើកូដ PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ប្រើ​លំនាំ"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"អូសឡើងលើ​ដើម្បីបើក"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ចុចរូបដោះសោ ដើម្បីបើក"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"បានដោះសោ​ដោយប្រើមុខ។ សូមចុចរូបដោះសោ ដើម្បីបើក។"</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"បានដោះសោដោយប្រើមុខ។ សូមចុច ដើម្បីបើក។"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"បានស្គាល់មុខ។ សូមចុច ដើម្បីបើក។"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"បានស្គាល់មុខ។ សូមចុចរូបដោះសោ ដើម្បីបើក។"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"អូសឡើងលើ ដើម្បី​ព្យាយាម​ម្ដងទៀត"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ដោះសោ ដើម្បីប្រើ NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ឧបករណ៍​នេះគឺជា​កម្មសិទ្ធិរបស់​ស្ថាប័ន​អ្នក"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"តើ​អ្នក​ចង់​បន្ត​វគ្គ​របស់​អ្នក​ទេ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ចាប់ផ្ដើមសាជាថ្មី"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"បាទ​/ចាស ​បន្ត"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"មុខងារ​ភ្ញៀវ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"អ្នកស្ថិតនៅក្នុងមុខងារភ្ញៀវ"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"បញ្ចូល​អ្នកប្រើ​ថ្មីឬ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"នៅពេល​អ្នក​បញ្ចូល​អ្នកប្រើ​ថ្មី អ្នកប្រើ​នោះ​ត្រូវ​រៀបចំកន្លែងរបស់​គេ។\n\nអ្នក​ប្រើ​ណា​ក៏​អាច​ដំឡើងកំណែ​កម្មវិធី​សម្រាប់​អ្នកប្រើទាំងអស់ផ្សេងទៀត​បាន​ដែរ។"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ការបញ្ចូលអ្នកប្រើប្រាស់ថ្មីនឹងធ្វើឱ្យចាកចេញពីមុខងារភ្ញៀវ និងលុបកម្មវិធីនិងទិន្នន័យទាំងអស់ចេញពីវគ្គភ្ញៀវបច្ចុប្បន្ន។"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"​បាន​ឈាន​ដល់ចំនួន​កំណត់អ្នកប្រើប្រាស់"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">អ្នកអាចបញ្ចូល​អ្នក​ប្រើប្រាស់បាន​រហូតដល់ <xliff:g id="COUNT">%d</xliff:g> នាក់។</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"អាទិភាព"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនអាចប្រើ​មុខងារ​សន្ទនា​បានទេ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"មិនអាច​កែប្រែ​ការជូនដំណឹង​ទាំងនេះ​បានទេ។"</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"មិនអាច​កែប្រែ​ការជូនដំណឹងអំពីការហៅទូរសព្ទបានទេ។"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"មិនអាច​កំណត់​រចនាសម្ព័ន្ធ​ក្រុមការជូនដំណឹងនេះ​នៅទីនេះ​បានទេ"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ការជូនដំណឹង​ជា​ប្រូកស៊ី"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"ការជូន​ដំណឹងទាំងអស់​ពី​<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -924,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other">កម្មវិធី <xliff:g id="COUNT_1">%s</xliff:g> កំពុងដំណើរការ</item>
+      <item quantity="one">កម្មវិធី <xliff:g id="COUNT_0">%s</xliff:g> កំពុងដំណើរការ</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ព័ត៌មានថ្មី"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"កម្មវិធីសកម្ម"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"ទោះបីជាអ្នក​មិនកំពុងប្រើកម្មវិធីទាំងនេះ​ក៏ដោយ ក៏កម្មវិធី​ទាំងនេះនៅតែ​ដំណើរការ​ដដែល ហើយអាចប៉ះពាល់​ដល់កម្រិតថាមពលថ្ម"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ឈប់"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"បានឈប់"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"រួចរាល់"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 0ce8ff8..c9b6ba3 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ಪೂರ್ಣಗೊಳಿಸಲು ದೃಢೀಕರಿಸಿ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ಪಿನ್ ಬಳಸಿ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ಪ್ಯಾಟರ್ನ್ ಬಳಸಿ"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಒತ್ತಿ."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ತೆರೆಯಲು ಒತ್ತಿ."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ಬಳಸಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ನಿಮ್ಮ ಸೆಷನ್‌ ಮುಂದುವರಿಸಲು ಇಚ್ಚಿಸುವಿರಾ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ಹೌದು, ಮುಂದುವರಿಸಿ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ಅತಿಥಿ ಮೋಡ್"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ನೀವು ಅತಿಥಿ ಮೋಡ್‌ನಲ್ಲಿದ್ದೀರಿ"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸುವುದೇ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಸ್ಥಾಪಿಸಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸುವುದರಿಂದ ಅತಿಥಿ ಮೋಡ್‌ನಿಂದ ನಿರ್ಗಮಿಸುತ್ತದೆ ಮತ್ತು ಪ್ರಸ್ತುತ ಅತಿಥಿ ಸೆಶನ್‌ನಿಂದ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ಬಳಕೆದಾರರ ಮಿತಿ ತಲುಪಿದೆ"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">ನೀವು <xliff:g id="COUNT">%d</xliff:g> ಬಳಕೆದಾರರವರೆಗೆ ಸೇರಿಸಬಹುದು.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"ಆದ್ಯತೆ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"ಸಂವಾದ ಫೀಚರ್‌ಗಳನ್ನು <xliff:g id="APP_NAME">%1$s</xliff:g> ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ಕರೆ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ಈ ಗುಂಪಿನ ಅಧಿಸೂಚನೆಗಳನ್ನು ಇಲ್ಲಿ ಕಾನ್ಫಿಗರ್‌ ಮಾಡಲಾಗಿರುವುದಿಲ್ಲ"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ಪ್ರಾಕ್ಸಿ ಮಾಡಿದ ಅಧಿಸೂಚನೆಗಳು"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳು"</string>
@@ -923,12 +921,14 @@
     <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> ಈ ಕೆಳಗಿನ ಟೈಲ್ ಅನ್ನು ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳಿಗೆ ಸೇರಿಸಲು ಬಯಸುತ್ತದೆ"</string>
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ಬಳಕೆದಾರರನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ಆ್ಯಪ್‌ಗಳು ಸಕ್ರಿಯವಾಗಿವೆ</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ಆ್ಯಪ್‌ಗಳು ಸಕ್ರಿಯವಾಗಿವೆ</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ಹೊಸ ಮಾಹಿತಿ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ಸಕ್ರಿಯ ಆ್ಯಪ್‌ಗಳು"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"ನೀವು ಈ ಆ್ಯಪ್‌ಗಳನ್ನು ಬಳಸದೇ ಇದ್ದರೂ ಸಹ ಅವುಗಳು ಈಗಲೂ ಸಕ್ರಿಯವಾಗಿವೆ ಹಾಗೂ ಅವು ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯ ಮೇಲೆ ಪ್ರಭಾವ ಬೀರಬಹುದು"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ನಿಲ್ಲಿಸಿ"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ನಿಲ್ಲಿಸಲಾಗಿದೆ"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"ಮುಗಿದಿದೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index c0d8279..c1ffeb3 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"확인함"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"완료하려면 확인을 탭하세요."</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 잠금 해제 아이콘을 누르세요."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 누르세요."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"얼굴이 인식되었습니다. 계속하려면 누르세요."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"얼굴이 인식되었습니다. 계속하려면 아이콘을 누르세요."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"인증됨"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN 사용"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"패턴 사용"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"위로 스와이프하여 열기"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"기기를 열려면 잠금 해제 아이콘을 누르세요."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"얼굴 인식으로 잠금 해제되었습니다. 기기를 열려면 잠금 해제 아이콘을 누르세요."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"얼굴 인식으로 잠금 해제되었습니다. 열려면 누르세요."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"얼굴이 인식되었습니다. 열려면 누르세요."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"얼굴이 인식되었습니다. 열려면 잠금 해제 아이콘을 누르세요."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"위로 스와이프하여 다시 시도해 주세요"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"잠금 해제하여 NFC 사용"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"내 조직에 속한 기기입니다."</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"세션을 계속 진행하시겠습니까?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"다시 시작"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"계속 진행"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"게스트 모드"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"게스트 모드 사용 중"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"신규 사용자를 추가할까요?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"추가된 새로운 사용자는 자신의 공간을 설정해야 합니다.\n\n사용자라면 누구든 다른 사용자를 위해 앱을 업데이트할 수 있습니다."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"새로운 사용자를 추가하면 게스트 모드가 종료되고 기존 게스트 세션의 모든 앱과 데이터가 삭제됩니다."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"사용자 제한 도달"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">사용자를 <xliff:g id="COUNT">%d</xliff:g>명까지 추가할 수 있습니다.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"우선순위"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱은 대화 기능을 지원하지 않습니다."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"이 알림은 수정할 수 없습니다."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"전화 알림은 수정할 수 없습니다."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"이 알림 그룹은 여기에서 설정할 수 없습니다."</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"프록시를 통한 알림"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"모든 <xliff:g id="APP_NAME">%1$s</xliff:g> 알림"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 2bef2b3..b493b2b 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -33,14 +33,14 @@
     <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Жок, рахмат"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Экранды авто буруу"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу <xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүн колдоно берсинби?"</string>
-    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу үчүн <xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүнө мүмкүнчүлүк алууга уруксат бересизби?\nБул колдонмонун жаздырууга уруксаты жок, бирок бул USB түзмөгү аркылуу аудиону жаздыра алат."</string>
+    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу <xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүн колдоно берсинби?\nБул колдонмого жаздырууга уруксат берилген эмес, бирок ушул USB түзмөгү аркылуу үндөрдү жаза алат."</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу <xliff:g id="USB_DEVICE">%2$s</xliff:g> кабелин колдоно берсинби?"</string>
     <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүн колдонуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосун ачасызбы?"</string>
-    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Бул колдонмонун жаздырууга уруксаты жок, бирок бул USB түзмөгү аркылуу аудиону жаздыра алат. <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосун бул түзмөктө иштетсеңиз, чалууларды, билдирмелерди жана ойготкучтарды уга албай калышыңыз мүмкүн."</string>
+    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Колдонмо аудио жаздырууга уруксат алган эмес, бирок ушул USB түзмөк аркылуу жаза алат. \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" колдонмосун ушул түзмөк менен колдонуп жатканда, билдирмелердин, чалуулардын жана ойготкучтардын үнүн укпай калышыңыз мүмкүн."</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосун бул түзмөктө иштетсеңиз, чалууларды, билдирмелерди жана ойготкучтарды уга албай калышыңыз мүмкүн."</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> кабелин колдоно берсинби?"</string>
     <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүнө туташуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу ачылсынбы?"</string>
-    <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> кабелине туташуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> ачылсынбы?\nБул колдонмонун жаздырууга уруксаты жок, бирок бул USB түзмөгү аркылуу аудиону жаздыра алат."</string>
+    <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүн колдонуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосун ачасызбы?\nБул колдонмого жаздырууга уруксат берилген эмес, бирок ушул USB түзмөгү аркылуу үндөрдү жаза алат."</string>
     <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> колдонуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосун ачасызбы?"</string>
     <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Эч бир орнотулган колдонмо USB аксессуар м-н иштебейт. Кенен маалыматтар: <xliff:g id="URL">%1$s</xliff:g>"</string>
     <string name="title_usb_accessory" msgid="1236358027511638648">"USB шайманы"</string>
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансыңызды улантасызбы?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Кайра баштоо"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ооба, уланта берели"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Конок режими"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Конок режиминдесиз"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Жаңы колдонуучу кошосузбу?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Жаңы колдонуучу кошулганда, ал өз мейкиндигин түзүп алышы керек.\n\nКолдонмолорду бир колдонуучу жаңыртканда, ал калган бардык колдонуучулар үчүн да жаңырат."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Жаңы колдонуучуну кошсоңуз, конок режими жабылат жана учурдагы конок сеансындагы бардык колдонмолор жана дайындар өчүрүлөт."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Дагы колдонуучу кошууга болбойт"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> колдонуучуга чейин кошууга болот.</item>
@@ -465,7 +470,7 @@
     <string name="wallet_empty_state_label" msgid="7776761245237530394">"Телефонуңуз менен тез жана коопсуз сатып алуу үчүн жөндөңүз"</string>
     <string name="wallet_app_button_label" msgid="7123784239111190992">"Баарын көрсөтүү"</string>
     <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Картаны кошуу"</string>
-    <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Жаңыртылууда"</string>
+    <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Жаңырууда"</string>
     <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Колдонуу үчүн кулпусун ачыңыз"</string>
     <string name="wallet_error_generic" msgid="257704570182963611">"Кыйытмаларды алууда ката кетти. Бир аздан кийин кайталап көрүңүз."</string>
     <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Кулпуланган экран жөндөөлөрү"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 6858395..2402034c 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ທ່ານ​ຕ້ອງ​ການ​ສືບ​ຕໍ່​ເຊດ​ຊັນ​ຂອງ​ທ່ານບໍ່?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ເລີ່ມຕົ້ນໃຫມ່"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"​ຕົກ​ລົງ, ດຳ​ເນີນ​ການ​ຕໍ່"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ໂໝດແຂກ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ທ່ານກຳລັງຢູ່ໃນໂໝດແຂກ"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"ເພີ່ມຜູ້ໃຊ້ໃໝ່ບໍ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ເມື່ອ​ທ່ານ​ເພີ່ມ​ຜູ້ໃຊ້​ໃໝ່, ຜູ້ໃຊ້​ນັ້ນ​ຈະ​ຕ້ອງ​ຕັ້ງ​ຄ່າ​ພື້ນ​ທີ່​ບ່ອນ​ຈັດ​ເກັບ​ຂໍ້​ມູນ​ຂອງ​ລາວ.\n\nຜູ້ໃຊ້​ທຸກ​ຄົນ​ສາ​ມາດ​ອັບ​ເດດ​ແອັບຂອງ​ຜູ້​ໃຊ້​ຄົນ​ອື່ນ​ທັງ​ໝົດ​ໄດ້."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ການເພີ່ມຜູ້ໃຊ້ໃໝ່ຈະອອກຈາກໂໝດແຂກ ແລະ ລຶບແອັບ ແລະ ຂໍ້ມູນທັງໝົດອອກຈາກໄລຍະເວລາຂອງແຂກປັດຈຸບັນ."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ຮອດຂີດຈຳກັດຜູ້ໃຊ້ແລ້ວ"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">ທ່ານສາມາດເພີ່ມໄດ້ສູງສຸດ <xliff:g id="COUNT">%d</xliff:g> ຄົນ.</item>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ແອັບນຳໃຊ້ຢູ່</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ແອັບນຳໃຊ້ຢູ່</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ຂໍ້ມູນໃໝ່"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ແອັບທີ່ນຳໃຊ້ຢູ່"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"ເຖິງແມ່ນວ່າທ່ານຈະບໍ່ໄດ້ກຳລັງໃຊ້ແອັບເຫຼົ່ານີ້, ພວກມັນກໍຍັງຄົງນຳໃຊ້ຢູ່ ແລະ ອາດກະທົບກັບອາຍຸແບັດເຕີຣີໄດ້"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ຢຸດ"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ຢຸດແລ້ວ"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"ແລ້ວໆ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index f596720..d77607b 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Patvirtinta"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Paliesk. „Patvirtinti“, kad užbaigtumėte"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Atrakinta pagal veidą. Pasp. atrak. pikt., kad tęstumėte."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Atrakinta pagal veidą. Paspauskite, jei norite tęsti."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Veidas atpažintas. Paspauskite, jei norite tęsti."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Veidas atpažintas. Tęskite paspaudę atrakinimo piktogramą."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikuota"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Naudoti PIN kodą"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Naudoti atrakinimo piešinį"</string>
@@ -322,12 +319,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Perbraukite aukštyn, kad atidarytumėte"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Paspauskite atrakinimo piktogramą, kad atidarytumėte"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atrakinta pagal veidą. Pasp. atr. pikt., kad atidarytumėte."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Atrakinta pagal veidą. Paspauskite, kad atidarytumėte."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Veidas atpažintas. Paspauskite, kad atidarytumėte."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Veidas atpažintas. Atidarykite paspaudę atrakin. piktogramą."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Jei norite bandyti dar kartą, perbraukite aukštyn"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Norėdami naudoti NFC, atrakinkite"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Šis įrenginys priklauso jūsų organizacijai"</string>
@@ -354,6 +348,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ar norite tęsti sesiją?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Pradėti iš naujo"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Taip, tęsti"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Svečio režimas"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Naudojatės svečio režimu"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Pridėti naują naudotoją?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kai pridedate naują naudotoją, šis asmuo turi nustatyti savo erdvę.\n\nBet kuris naudotojas gali atnaujinti visų kitų naudotojų programas."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Pridėjus naują naudotoją, bus išeita iš svečio režimo ir iš dabartinės svečio sesijos bus ištrintos visos programos ir duomenys."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Pasiekta naudotojų riba"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Galite pridėti iki <xliff:g id="COUNT">%d</xliff:g> naudotojo.</item>
@@ -524,8 +523,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritetiniai"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ nepalaiko pokalbių funkcijų"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Šių pranešimų keisti negalima."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Skambučių pranešimų keisti negalima."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Šios grupės pranešimai čia nekonfigūruojami"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Per tarpinį serverį gautas pranešimas"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Visi „<xliff:g id="APP_NAME">%1$s</xliff:g>“ pranešimai"</string>
@@ -936,11 +934,15 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Pridėti išklotinės elementą"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nepridėti išklotinės elemento"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Naudotojo pasirinkimas"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> programa yra aktyvi</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> programos yra aktyvios</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> programos yra aktyvi</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> programų yra aktyvios</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nauja informacija"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktyvios programos"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Net jei nenaudojate šių programų, jos vis tiek yra aktyvios ir gali paveikti akumuliatoriaus veikimo laiką"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Sustabdyti"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Sustabdyta"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Atlikta"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 7f98fed..fd2b93c 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Apstiprināts"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Lai pabeigtu, pieskarieties Apstiprināt"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Atbloķēta ar seju. Turpināt: nospiediet atbloķēšanas ikonu."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ierīce atbloķēta ar seju. Nospiediet, lai turpinātu."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Seja atpazīta. Nospiediet, lai turpinātu."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Seja atpazīta. Lai turpinātu, nospiediet atbloķēšanas ikonu."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikācija veikta"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Izmantot PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Izmantot kombināciju"</string>
@@ -320,12 +317,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Velciet augšup, lai atvērtu"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Lai atvērtu, nospiediet atbloķēšanas ikonu"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atbloķēta ar seju. Atvērt: nospiediet atbloķēšanas ikonu."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ierīce atbloķēta ar seju. Nospiediet, lai atvērtu."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Seja atpazīta. Nospiediet, lai atvērtu."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Seja atpazīta. Lai atvērtu, nospiediet atbloķēšanas ikonu."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Velciet augšup, lai mēģinātu vēlreiz"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Atbloķējiet ierīci, lai izmantotu NFC."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Šī ierīce pieder jūsu organizācijai."</string>
@@ -352,6 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vai vēlaties turpināt savu sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Sākt no sākuma"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Jā, turpināt"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Viesa režīms"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Jūs izmantojat viesa režīmu"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Vai pievienot jaunu lietotāju?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kad pievienosiet jaunu lietotāju, viņam būs jāizveido savs profils.\n\nIkviens lietotājs var atjaunināt lietotnes citu lietotāju vietā."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ja pievienosiet jaunu lietotāju, viesa režīms tiks aizvērts un visas pašreizējās viesa sesijas lietotnes un dati tiks dzēsti."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Sasniegts lietotāju ierobežojums"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="zero">Varat pievienot ne vairāk kā <xliff:g id="COUNT">%d</xliff:g> lietotājus.</item>
@@ -521,8 +520,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritārs"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g> netiek atbalstītas sarunu funkcijas."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Šos paziņojumus nevar modificēt."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Paziņojumus par zvaniem nevar modificēt."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Šeit nevar konfigurēt šo paziņojumu grupu."</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Starpniekservera paziņojums"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Visi lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> paziņojumi"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 060e964..e6c5aab 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврдено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Допрете „Потврди“ за да се заврши"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Отклучено со лице. Притиснете ја иконата за отклучување за да продолжите."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отклучено со лице. Притиснете за да продолжите."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето е препознаено. Притиснете за да продолжите."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето е препознаено. Притиснете ја иконата за отклучување за да продолжите."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Проверена"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Користи PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Користи шема"</string>
@@ -248,7 +245,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Осветленост"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Инверзија на боите"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Корекција на боите"</string>
-    <string name="quick_settings_more_user_settings" msgid="1064187451100861954">"Поставки на корисникот"</string>
+    <string name="quick_settings_more_user_settings" msgid="1064187451100861954">"Кориснички поставки"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Затвори"</string>
     <string name="quick_settings_connected" msgid="3873605509184830379">"Поврзано"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Повлечете за да отворите"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Притиснете ја иконата за отклучување за да отворите"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Отклучено со лице. Притиснете ја иконата за отклучување за да отворите."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Отклучено со лице. Притиснете за да отворите."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицето е препознаено. Притиснете за да отворите."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Лицето е препознаено. Притиснете ја иконата за отклучување за да отворите."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Повлечете нагоре за да се обидете повторно"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отклучете за да користите NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Уредов е во сопственост на организацијата"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Дали сакате да продолжите со сесијата?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни одново"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продолжи"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Режим на гостин"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Користите режим на гостин"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Да се додаде нов корисник?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Кога додавате нов корисник, тоа лице треба да го постави својот простор.\n\nСекој корисник може да ажурира апликации за сите други корисници."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ако додадете нов корисник, ќе излезете од режимот на гостин и ќе ги избришете сите апликации и податоци од тековната гостинска сесија."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнато ограничување на корисник"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Може да додадете најмногу <xliff:g id="COUNT">%d</xliff:g> корисник.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Приоритетно"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддржува функции за разговор"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Овие известувања не може да се изменат"</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Известувањата за повици не може да се изменат."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Оваа група известувања не може да се конфигурира тука"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Известување преку прокси"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Сите известувања од <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -906,7 +904,7 @@
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобилен интернет"</string>
     <string name="preference_summary_default_combination" msgid="8453246369903749670">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="NETWORKMODE">%2$s</xliff:g>"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Поврзано"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Мобилниот интернет не може автоматски да се поврзе"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Мобилниот интернет не може да се поврзе автоматски"</string>
     <string name="mobile_data_no_connection" msgid="1713872434869947377">"Нема интернет-врска"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Нема други достапни мрежи"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"Нема достапни мрежи"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 38a4317..e20eb36 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"നിങ്ങളുടെ സെഷൻ തുടരണോ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"പുനരാംരംഭിക്കുക"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"അതെ, തുടരുക"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"അതിഥി മോഡ്"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"നിങ്ങൾ അതിഥി മോഡിലാണ്"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"പുതിയ ഉപയോക്താവിനെ ചേർക്കണോ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"നിങ്ങൾ പുതിയൊരു ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തിക്ക് അവരുടെ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\nമറ്റ് എല്ലാ ഉപയോക്താക്കൾക്കുമായി ഏതൊരു ഉപയോക്താവിനും ആപ്പുകൾ അപ്‌ഡേറ്റ് ചെയ്യാനാവും."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"പുതിയൊരു ഉപയോക്താവിനെ ചേർത്താൽ അതിഥി മോഡിൽ നിന്ന് പുറത്ത് കടക്കുകയും നിലവിലെ അതിഥി മോഡിലുള്ള എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കുകയും ചെയ്യും."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ഉപയോക്തൃ പരിധി എത്തി"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">നിങ്ങൾക്ക് <xliff:g id="COUNT">%d</xliff:g> ഉപയോക്താക്കളെ വരെ ചേർക്കാനാവും.</item>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ആപ്പുകൾ സജീവമാണ്</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ആപ്പ് സജീവമാണ്</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"പുതിയ വിവരങ്ങൾ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"സജീവമായ ആപ്പുകൾ"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"നിങ്ങൾ ഈ ആപ്പുകൾ ഉപയോഗിക്കുന്നില്ലെങ്കിൽ പോലും അവ ഇപ്പോഴും സജീവമാണ്, ഇത് ബാറ്ററി ലൈഫിനെ ബാധിച്ചേക്കാം"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"നിർത്തുക"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"നിർത്തി"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"പൂർത്തിയായി"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 13aedc7..8ae2896f 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Та үргэлжлүүлэхийг хүсэж байна уу?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Дахин эхлүүлэх"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Тийм, үргэлжлүүлэх"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Зочны горим"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Та зочны горимд байна"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Шинэ хэрэглэгч нэмэх үү?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Та шинэ хэрэглэгч нэмбэл тухайн хүн өөрийн профайлыг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бүх хэрэглэгчийн аппуудыг шинэчлэх боломжтой."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Шинэ хэрэглэгч нэмснээр зочны горимоос гаргах бөгөөд бүх апп болон өгөгдлийг одоогийн зочны харилцан үйлдлээс устгана."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Хэрэглэгчийн хязгаарт хүрсэн"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Та <xliff:g id="COUNT">%d</xliff:g> хүртэлх хэрэглэгч нэмэх боломжтой.</item>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> апп идэвхтэй байна</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> апп идэвхтэй байна</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Шинэ мэдээлэл"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Идэвхтэй аппууд"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Та эдгээр аппыг ашиглаагүй байсан ч тэдгээр нь идэвхтэй хэвээр байгаа бөгөөд батарейн ажиллах хугацаанд нөлөөлж болзошгүй"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Зогсоох"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Зогсоосон"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Болсон"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 1424efc..24c8088 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -36,7 +36,7 @@
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_DEVICE">%2$s</xliff:g> अ‍ॅक्सेस करण्याची अनुमती द्यायची का?\nया अ‍ॅपला रेकॉर्ड करण्याची परवानगी दिलेली नाही पण या USB डिव्हाइसद्वारे ऑडिओ कॅप्चर केला जाऊ शकतो."</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_DEVICE">%2$s</xliff:g> अ‍ॅक्सेस करण्याची अनुमती द्यायची आहे का?"</string>
     <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> हाताळण्यासाठी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडायचे आहे का?"</string>
-    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"या अ‍ॅपला रेकॉर्ड करण्याची परवानगी दिलेली नाही पण या USB डिव्हाइसद्वारे ऑडिओ कॅप्चर केला जाऊ शकतो. <xliff:g id="APPLICATION">%1$s</xliff:g> चा वापर या डिव्हाइससह केल्याने कॉल, सूचना आणि अलार्मचा आवाज कदाचित ऐकू येणार नाही."</string>
+    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"या अ‍ॅपला रेकॉर्ड करण्याची परवानगी दिलेली नाही, पण या USB डिव्हाइसद्वारे ऑडिओ कॅप्चर केला जाऊ शकतो. <xliff:g id="APPLICATION">%1$s</xliff:g> चा वापर या डिव्हाइससह केल्याने कॉल, सूचना आणि अलार्मचा आवाज कदाचित ऐकू येणार नाही."</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> चा वापर या डिव्हाइससह केल्याने कॉल, सूचना आणि अलार्मचा आवाज कदाचित ऐकू येणार नाही."</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> अ‍ॅक्सेस करण्याची अनुमती द्यायची का?"</string>
     <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> हाताळण्यासाठी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडायचे का?"</string>
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"निश्चित केले"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूर्ण करण्यासाठी खात्री करा वर टॅप करा"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"चेहऱ्याने अनलॉक केले. सुरू ठेवण्यासाठी अनलॉक करा आयकन दाबा."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहऱ्याने अनलॉक केले आहे. पुढे सुरू ठेवण्यासाठी दाबा."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी दाबा."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी अनलॉक करा आयकन दाबा."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ऑथेंटिकेशन केलेले"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"पिन वापरा"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"पॅटर्न वापरा"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"उघडण्यासाठी अनलॉक करा आयकन दाबा"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहऱ्याने अनलॉक केले. उघडण्यासाठी अनलॉक करा आयकन दाबा."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहऱ्याने अनलॉक केले आहे. उघडण्यासाठी दाबा."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरा ओळखला आहे. उघडण्यासाठी दाबा."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"चेहरा ओळखला आहे. उघडण्यासाठी अनलॉक करा आयकन दाबा."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"पुन्हा प्रयत्न करण्यासाठी वर स्‍वाइप करा"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC वापरण्यासाठी स्क्रीन अनलॉक करा"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"हे डिव्हाइस तुमच्या संस्थेचे आहे"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"तुम्ही तुमचे सत्र सुरू ठेवू इच्छिता?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"येथून सुरू करा"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"होय, सुरू ठेवा"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"अतिथी मोड"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"तुम्ही अतिथी मोडमध्ये आहात"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"नवीन वापरकर्ता जोडायचा?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"तुम्ही एक नवीन वापरकर्ता जोडता तेव्हा, त्या व्यक्तीने त्यांचे स्थान सेट करणे आवश्यक असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अ‍ॅप्स अपडेट करू शकतो."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"नवीन वापरकर्ता जोडल्याने अतिथी मोडमधून बाहेर पडेल आणि सध्याच्या अतिथी सत्रातील सर्व अ‍ॅप्स व डेटा हटवला जाईल."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"वापरकर्ता मर्यादा गाठली"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">तुम्ही <xliff:g id="COUNT">%d</xliff:g> वापरकर्त्यांपर्यंत जोडू शकता.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"प्राधान्य"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे संभाषण वैशिष्ट्यांना सपोर्ट करत नाही"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"या सूचनांमध्ये सुधारणा केली जाऊ शकत नाही."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कॉलशी संबंधित सूचनांमध्ये फेरबदल केला जाऊ शकत नाही."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"या सूचनांचा संच येथे कॉंफिगर केला जाऊ शकत नाही"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"प्रॉक्सी केलेल्या सूचना"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"सर्व <xliff:g id="APP_NAME">%1$s</xliff:g> वरील सूचना"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 4c90c88..3ea3c9a 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -36,7 +36,7 @@
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Benarkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nApl ini belum diberikan kebenaran merakam tetapi dapat merakam audio melalui peranti USB ini."</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Benarkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk mengendalikan <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Apl ini belum diberikan kebenaran merakam tetapi dapat merakam audio melalui peranti USB ini. Tindakan menggunakan <xliff:g id="APPLICATION">%1$s</xliff:g> dengan peranti ini mungkin menghalang anda daripada mendengar panggilan, pemberitahuan dan penggera."</string>
+    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Apl ini belum diberi kebenaran merakam tetapi dapat merakam audio melalui peranti USB ini. Tindakan menggunakan <xliff:g id="APPLICATION">%1$s</xliff:g> dengan peranti ini mungkin menghalang anda daripada mendengar panggilan, pemberitahuan dan penggera."</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Tindakan menggunakan <xliff:g id="APPLICATION">%1$s</xliff:g> dengan peranti ini mungkin menghalang anda daripada mendengar panggilan, pemberitahuan dan penggera."</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Benarkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
     <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk mengendalikan <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Adakah anda ingin meneruskan sesi anda?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulakan semula"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ya, teruskan"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mod tetamu"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Anda dalam mod tetamu"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Tambah pengguna baharu?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Apabila anda menambah pengguna baharu, orang itu perlu menyediakan ruang mereka.\n\nMana-mana pengguna boleh mengemas kini apl untuk semua pengguna lain."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Tindakan menambahkan pengguna baharu akan menyebabkan anda keluar daripada mod tetamu dan memadamkan semua apl dan data daripada sesi tetamu semasa."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Had pengguna dicapai"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Anda boleh menambah sehingga <xliff:g id="COUNT">%d</xliff:g> pengguna.</item>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 7260936..1840a46 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -34,7 +34,7 @@
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ဖန်သားပြင် အလိုအလျောက်လှည့်ရန်"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> အား ဝင်သုံးရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ခွင့်ပြုပါသလား။"</string>
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> အား <xliff:g id="USB_DEVICE">%2$s</xliff:g> ကို သုံးခွင့်ပြုမလား။\nဤအက်ပ်ကို အသံဖမ်းခွင့် ပေးမထားသော်လည်း ၎င်းသည် ဤ USB စက်ပစ္စည်းမှတစ်ဆင့် အသံများကို ဖမ်းယူနိုင်ပါသည်။"</string>
-    <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ဝင်သုံးရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ခွင့်ပြုမလား။"</string>
+    <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> ကို <xliff:g id="USB_DEVICE">%2$s</xliff:g> ဝင်သုံးခွင့်ပြုမလား။"</string>
     <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ဆောင်ရွက်ရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ဖွင့်လိုပါသလား။"</string>
     <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ဤအက်ပ်ကို အသံဖမ်းခွင့် ပေးမထားသော်လည်း ၎င်းသည် ဤ USB စက်ပစ္စည်းမှတစ်ဆင့် အသံများကို ဖမ်းယူနိုင်ပါသည်။ ဤစက်ဖြင့် <xliff:g id="APPLICATION">%1$s</xliff:g> အသုံးပြုခြင်းက ဖုန်းအဝင်၊ အကြောင်းကြားချက်နှင့် နှိုးစက်သံ မကြားခြင်းများ ဖြစ်စေနိုင်သည်။"</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"ဤစက်ဖြင့် <xliff:g id="APPLICATION">%1$s</xliff:g> အသုံးပြုခြင်းက ဖုန်းအဝင်၊ အကြောင်းကြားချက်နှင့် နှိုးစက်သံ မကြားခြင်းများ ဖြစ်စေနိုင်သည်။"</string>
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"သင်၏ စက်ရှင်ကို ဆက်လုပ်လိုပါသလား။"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ပြန်စပါ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ဆက်လုပ်ပါ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ဧည့်သည်မုဒ်"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"သင်သည် ဧည့်သည်မုဒ်တွင် ဖြစ်သည်"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"အသုံးပြုသူအသစ်ကို ထည့်မလား။"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"သင်ထည့်လိုက်သော အသုံးပြုသူအသစ်သည် ၎င်း၏နေရာကို သတ်မှတ်စီစဉ်ရန် လိုအပ်သည်။\n\nမည်သည့်အသုံးပြုသူမဆို ကျန်သူများအားလုံးအတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်ပေးနိုင်သည်။"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"အသုံးပြုသူ အသစ်ထည့်ခြင်းက ဧည့်သည်မုဒ်မှ ထွက်သွားမည်ဖြစ်ပြီး လက်ရှိဧည့်သည် စက်ရှင်မှ အက်ပ်နှင့် ဒေတာအားလုံးကို ဖျက်လိုက်ပါမည်။"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"အသုံးပြုသူ အကန့်အသတ် ပြည့်သွားပါပြီ"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">အသုံးပြုသူ <xliff:g id="COUNT">%d</xliff:g> ဦးအထိ ထည့်နိုင်သည်။</item>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 8c9a262..fccd411 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -130,7 +130,7 @@
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekreft"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Prøv på nytt"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Trykk for å avbryte autentiseringen"</string>
-    <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"Prøv igjen"</string>
+    <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"Prøv på nytt"</string>
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"Ser etter ansiktet ditt"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansiktet er autentisert"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekreftet"</string>
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsette økten?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start på nytt"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsett"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gjestemodus"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Du er i gjestemodus"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Vil du legge til en ny bruker?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Når du legger til en ny bruker, må vedkommende konfigurere sitt eget område.\n\nAlle brukere kan oppdatere apper for alle andre brukere."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Hvis du legger til en ny bruker, avsluttes gjestemodus, og alle apper og data fra den gjeldende gjesteøkten slettes."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Grensen for antall brukere er nådd"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Du kan legge til opptil <xliff:g id="COUNT">%d</xliff:g> brukere.</item>
@@ -467,7 +472,7 @@
     <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Legg til et kort"</string>
     <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Oppdaterer"</string>
     <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lås opp for å bruke"</string>
-    <string name="wallet_error_generic" msgid="257704570182963611">"Det oppsto et problem med henting av kortene. Prøv igjen senere"</string>
+    <string name="wallet_error_generic" msgid="257704570182963611">"Det oppsto et problem med henting av kortene. Prøv på nytt senere"</string>
     <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Innstillinger for låseskjermen"</string>
     <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skann QR-koden"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Work-profil"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 9fa75a8..42f777f 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि भयो"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूरा गर्नका लागि पुष्टि गर्नुहोस् नामक विकल्पमा ट्याप गर्नुहोस्"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"अनुहार प्रयोग गरी अनलक गरियो। जारी राख्न अनलक आइकनमा थिच्नुहोस्।"</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"अनुहार प्रयोग गरी अनलक गरियो। जारी राख्न थिच्नुहोस्।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"अनुहार पहिचान गरियो। जारी राख्न थिच्नुहोस्।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"अनुहार पहिचान गरियो। जारी राख्न अनलक आइकनमा थिच्नुहोस्।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"प्रमाणीकरण गरियो"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN प्रयोग गर्नुहोस्"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ढाँचा प्रयोग गर्नुहोस्"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"खोल्न अनलक आइकनमा थिच्नुहोस्"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"अनुहार प्रयोग गरी अनलक गरियो। खोल्न अनलक आइकनमा थिच्नुहोस्।"</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"अनुहार प्रयोग गरी अनलक गरियो। डिभाइस खोल्न थिच्नुहोस्।"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"अनुहार पहिचान गरियो। डिभाइस खोल्न थिच्नुहोस्।"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"अनुहार पहिचान गरियो। डिभाइस खोल्न अनलक आइकनमा थिच्नुहोस्।"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"फेरि प्रयास गर्न माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC प्रयोग गर्न स्क्रिन अनलक गर्नुहोस्"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"यो डिभाइस तपाईंको सङ्गठनको स्वामित्वमा छ"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"तपाईं आफ्नो सत्र जारी गर्न चाहनुहुन्छ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"सुरु गर्नुहोस्"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हो, जारी राख्नुहोस्"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"अतिथि मोड"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"तपाईं अतिथि मोड चलाउँदै हुनुहुन्छ"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"नयाँ प्रयोगकर्ता थप्ने हो?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"जब तपाईँले नयाँ प्रयोगकर्ता थप्नुहुन्छ, त्यस प्रयोगकर्ताले आफ्नो स्थान स्थापना गर्न पर्ने छ।\n\nसबै प्रयोगकर्ताले अरू प्रयोगकर्ताका एपहरू अपडेट गर्न सक्छन्।"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"तपाईंले नयाँ प्रयोगकर्ता थप्नुभयो भने तपाईं अतिथि मोडबाट बाहिरिनु हुने छ र हालको अतिथि सत्रका सबै एप तथा डेटा मेटिने छ।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"प्रयोगकर्ताको सीमा पुग्यो"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">तपाईं अधिकतम <xliff:g id="COUNT">%d</xliff:g> प्रयोगहरू मात्र थप्न सक्नुहुन्छ।</item>
@@ -435,7 +434,7 @@
     <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"यो एप अनपिन गर्न माथितिर स्वाइप गरी स्क्रिनमा टच एण्ड होल्ड गर्नुहोस्"</string>
     <string name="screen_pinning_positive" msgid="3285785989665266984">"बुझेँ"</string>
     <string name="screen_pinning_negative" msgid="6882816864569211666">"धन्यवाद पर्दैन"</string>
-    <string name="screen_pinning_start" msgid="7483998671383371313">"एप पिन गरियो"</string>
+    <string name="screen_pinning_start" msgid="7483998671383371313">"पिन गरिएको एप"</string>
     <string name="screen_pinning_exit" msgid="4553787518387346893">"एप अनपिन गरियो"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"कल"</string>
     <string name="stream_system" msgid="7663148785370565134">"प्रणाली"</string>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा वार्तालापसम्बन्धी सुविधा प्रयोग गर्न मिल्दैन"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"यी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कलसम्बन्धी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"यहाँबाट सूचनाहरूको यो समूह कन्फिगर गर्न सकिँदैन"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"प्रोक्सीमार्फत आउने सूचना"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"<xliff:g id="APP_NAME">%1$s</xliff:g> सम्बन्धी सबै सूचनाहरू"</string>
@@ -924,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> वटा एप सक्रिय छन्</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> एप सक्रिय छ</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"नयाँ जानकारी"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"सक्रिय एपहरू"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"तपाईंले यी एपहरू प्रयोग गरिरहनुभएको छैन भने पनि ती एपहरू सक्रिय रहिरहन्छन् र तिनले ब्याट्रीको आयुमा असर गर्न सक्छन्"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"रोक्नुहोस्"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"रोकिएको छ"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"सम्पन्न भयो"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 6235dd5..e56fbd4 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -35,7 +35,7 @@
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nDeze app heeft geen opnamerechten gekregen, maar zou audio kunnen vastleggen via dit USB-apparaat."</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="APPLICATION">%1$s</xliff:g> openen om <xliff:g id="USB_DEVICE">%2$s</xliff:g> te verwerken?"</string>
+    <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="APPLICATION">%1$s</xliff:g> openen om te werken met <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Deze app heeft geen opnamerechten gekregen, maar zou audio kunnen vastleggen via dit USB-apparaat. Als je <xliff:g id="APPLICATION">%1$s</xliff:g> gebruikt met dit apparaat, hoor je misschien geen gesprekken, meldingen en wekkers."</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Als je <xliff:g id="APPLICATION">%1$s</xliff:g> gebruikt met dit apparaat, hoor je misschien geen gesprekken, meldingen en wekkers."</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Wil je doorgaan met je sessie?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Opnieuw starten"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, doorgaan"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gastmodus"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Je gebruikt de gastmodus"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Nieuwe gebruiker toevoegen?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Als je een nieuwe gebruiker toevoegt, moet die persoon zijn eigen profiel instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Als je een nieuwe gebruiker toevoegt, wordt de gastmodus afgesloten en worden alle apps en gegevens van de huidige gastsessie verwijderd."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Gebruikerslimiet bereikt"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Je kunt maximaal <xliff:g id="COUNT">%d</xliff:g> gebruikers toevoegen.</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tegel toevoegen"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Tegel niet toevoegen"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Gebruiker selecteren"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps zijn actief</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app is actief</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nieuwe informatie"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Actieve apps"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Ook als je deze apps niet gebruikt, zijn ze actief en kunnen ze de batterijduur beïnvloeden"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stoppen"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Gestopt"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Klaar"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index a8299a5..ab2498c 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ସୁନିଶ୍ଚିତ କରାଯାଇଛି"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ସୁନିଶ୍ଚିତ କରନ୍ତୁରେ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ପାଟର୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବାକୁ ଦବାନ୍ତୁ।"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଖୋଲିବାକୁ ଦବାନ୍ତୁ।"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"ପୁଣି ଚେଷ୍ଟା କରିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ବ୍ୟବହାର କରିବାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ଆପଣ ନିଜର ସେସନ୍ ଜାରି ରଖିବାକୁ ଚାହାଁନ୍ତି କି?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ହଁ, ଜାରି ରଖନ୍ତୁ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ଅତିଥି ମୋଡ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ଆପଣ ଅତିଥି ମୋଡରେ ଅଛନ୍ତି"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ଯୋଗ କରିବେ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ଆପଣ ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବା ବେଳେ, ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ତାଙ୍କ ସ୍ପେସ ସେଟ ଅପ କରିବାକୁ ପଡ଼ିବ।\n\nଅନ୍ୟ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ, ଆପଗୁଡ଼ିକୁ ଯେ କୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଅପଡେଟ କରିପାରିବେ।"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବା ଦ୍ୱାରା ଅତିଥି ମୋଡରୁ ବାହାରି ଯିବ ଏବଂ ବର୍ତ୍ତମାନର ଅତିଥି ସେସନରୁ ସମସ୍ତ ଆପ ଓ ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ଉପଯୋଗକର୍ତ୍ତା ସୀମାରେ ପହଞ୍ଚିଛି"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">କେବଳ <xliff:g id="COUNT">%d</xliff:g> ଉପଯୋଗକର୍ତ୍ତା ହିଁ ତିଆରି କରିହେବ।</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"ପ୍ରାଥମିକତା"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବାର୍ତ୍ତାଳାପ ଫିଚରଗୁଡ଼ିକୁ ସମର୍ଥନ କରେ ନାହିଁ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପରିବର୍ତ୍ତନ କରିହେବ ନାହିଁ।"</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"କଲ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପରିବର୍ତ୍ତନ କରାଯାଇପାରିବ ନାହିଁ।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ଏଠାରେ ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଗ୍ରୁପ୍ କନଫ୍ୟୁଗର୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ବିଜ୍ଞପ୍ତି ପ୍ରକ୍ସୀ ହୋଇଛି"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"ସମସ୍ତ <xliff:g id="APP_NAME">%1$s</xliff:g>ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index ff40b55..3cacd0b 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ਪੁਸ਼ਟੀ ਕੀਤੀ ਗਈ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ਪੂਰਾ ਕਰਨ ਲਈ ਪੁਸ਼ਟੀ ਕਰੋ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ਪਿੰਨ ਵਰਤੋ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ਪੈਟਰਨ ਵਰਤੋ"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ।"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ।"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਉੱਤੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ਵਰਤਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਸੈਸ਼ਨ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ਹਾਂ, ਜਾਰੀ ਰੱਖੋ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ਮਹਿਮਾਨ ਮੋਡ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ਤੁਸੀਂ ਮਹਿਮਾਨ ਮੋਡ ਵਿੱਚ ਹੋ"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"ਕੀ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਨਾ ਹੈ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ਜਦੋਂ ਤੁਸੀਂ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣੀ ਜਗ੍ਹਾ ਸਥਾਪਤ ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।\n\nਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਹੋਰ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ਨਵੇਂ ਵਰਤੋਂਕਾਰ ਨੂੰ ਸ਼ਾਮਲ ਕਰਨ ਨਾਲ ਮੌਜੂਦਾ ਮਹਿਮਾਨ ਮੋਡ ਚਲਾ ਜਾਵੇਗਾ ਅਤੇ ਮੌਜੂਦਾ ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਦੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਸੀਮਾ ਪੂਰੀ ਹੋਈ"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">ਤੁਸੀਂ <xliff:g id="COUNT">%d</xliff:g> ਤੱਕ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੇ ਹੋ।</item>
@@ -371,7 +370,7 @@
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ਗੱਲਾਂਬਾਤਾਂ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਖਾਮੋਸ਼ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string>
-    <string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾਵਾਂ ਨਹੀਂ"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਕੋਲ ਇਸ ਡੀਵਾਈਸ ਦੀ ਮਲਕੀਅਤ ਹੈ ਅਤੇ ਇਹ ਨੈੱਟਵਰਕ ਟਰੈਫ਼ਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"ਤਰਜੀਹ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਗੱਲਬਾਤ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ਕਾਲ ਸੰਬੰਧੀ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ਇਹ ਸੂਚਨਾਵਾਂ ਦਾ ਗਰੁੱਪ ਇੱਥੇ ਸੰਰੂਪਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ਇੱਕ ਐਪ ਦੀ ਥਾਂ \'ਤੇ ਦੂਜੀ ਐਪ ਰਾਹੀਂ ਦਿੱਤੀ ਗਈ ਸੂਚਨਾ"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"ਸਾਰੀਆਂ <xliff:g id="APP_NAME">%1$s</xliff:g> ਸੂਚਨਾਵਾਂ"</string>
@@ -924,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ਐਪ ਕਿਰਿਆਸ਼ੀਲ ਹੈ</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ਐਪਾਂ ਕਿਰਿਆਸ਼ੀਲ ਹਨ</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ਨਵੀਂ ਜਾਣਕਾਰੀ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ਕਿਰਿਆਸ਼ੀਲ ਐਪਾਂ"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"ਭਾਵੇਂ ਤੁਸੀਂ ਇਨ੍ਹਾਂ ਐਪਾਂ ਦੀ ਵਰਤੋਂ ਨਾ ਵੀ ਕਰ ਰਹੇ ਹੋਵੋ, ਉਹ ਫਿਰ ਵੀ ਕਿਰਿਆਸ਼ੀਲ ਰਹਿੰਦੀਆਂ ਹਨ ਅਤੇ ਬੈਟਰੀ ਲਾਈਫ਼ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕਰ ਸਕਦੀਆਂ ਹਨ"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ਬੰਦ ਕਰੋ"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ਬੰਦ ਹੈ"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"ਹੋ ਗਿਆ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index d439def..c0be251 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potwierdzono"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Aby zakończyć, kliknij Potwierdź"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odblokowano skanem twarzy. Aby kontynuować, kliknij ikonę odblokowywania."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odblokowano rozpoznawaniem twarzy. Kliknij, aby kontynuować."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Twarz rozpoznana. Kliknij, aby kontynuować."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Twarz rozpoznana. Aby kontynuować, kliknij ikonę odblokowywania."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Uwierzytelniono"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Użyj kodu PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Użyj wzoru"</string>
@@ -322,12 +319,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Przesuń w górę, by otworzyć"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Aby otworzyć, kliknij ikonę odblokowywania"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odblokowano skanem twarzy. Aby otworzyć, kliknij ikonę odblokowywania."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odblokowano rozpoznawaniem twarzy. Naciśnij, by otworzyć."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Twarz rozpoznana. Naciśnij, by otworzyć."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Twarz rozpoznana. Aby otworzyć, kliknij ikonę odblokowywania."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Przesuń w górę, by spróbować ponownie"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odblokuj, by użyć komunikacji NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"To urządzenie należy do Twojej organizacji"</string>
@@ -354,6 +348,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcesz kontynuować sesję?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Rozpocznij nową"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Tak, kontynuuj"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Tryb gościa"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Jesteś w trybie gościa"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Dodać nowego użytkownika?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Gdy dodasz nowego użytkownika, musi on skonfigurować swój profil.\n\nKażdy użytkownik może aktualizować aplikacje wszystkich innych użytkowników."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Dodanie nowego użytkownika spowoduje zamknięcie trybu gościa. Wszystkie aplikacje i dane z obecnej sesji gościa zostaną usunięte."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Osiągnięto limit użytkowników"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="few">Możesz dodać maksymalnie <xliff:g id="COUNT">%d</xliff:g> użytkowników.</item>
@@ -434,7 +433,7 @@
     <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Ekran będzie widoczny, dopóki go nie odepniesz. Przesuń palcem w górę i przytrzymaj, by odpiąć."</string>
     <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, kliknij i przytrzymaj Przegląd."</string>
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, naciśnij i przytrzymaj Ekran główny."</string>
-    <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Dostępne mogą być dane osobiste (np. kontakty czy treść e-maili)."</string>
+    <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Dostępne mogą być dane prywatne (np. kontakty czy treść e-maili)."</string>
     <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Przypięta aplikacja może otwierać inne aplikacje."</string>
     <string name="screen_pinning_toast" msgid="8177286912533744328">"Aby odpiąć tę aplikację, naciśnij i przytrzymaj przyciski Wstecz oraz Przegląd"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Aby odpiąć tę aplikację, naciśnij i przytrzymaj przyciski Wstecz oraz Ekran główny"</string>
@@ -524,8 +523,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorytetowe"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje funkcji rozmów"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Tych powiadomień nie można zmodyfikować."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Powiadomień o połączeniach nie można modyfikować."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Tej grupy powiadomień nie można tu skonfigurować"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Powiadomienie w zastępstwie"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Wszystkie powiadomienia z aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -936,11 +934,15 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj kafelek"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nie dodawaj kafelka"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Wybierz użytkownika"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikacje są aktywne</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> aplikacji jest aktywnych</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacji jest aktywne</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikacja jest aktywna</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nowa informacja"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktywne aplikacje"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Nawet jeśli nie korzystasz z tych aplikacji, są one wciąż aktywne i mogą mieć wpływ na żywotność baterii"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Zatrzymaj"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zatrzymano"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Gotowe"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 36ac0d2..97eb716 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo visitante"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Você está no modo visitante"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Adicionar novo usuário?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Quando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para os demais usuários."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ao adicionar um novo usuário, o dispositivo vai sair do modo visitante e excluir todos os apps e dados da Sessão de visitante atual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de usuários atingido"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">É possível adicionar até <xliff:g id="COUNT">%d</xliff:g> usuário.</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adicionar bloco"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Não adicionar bloco"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Selecionar usuário"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app está ativo</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps estão ativos</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nova informação"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativos"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Mesmo que você não esteja usando esses apps, eles ainda ficam ativos e podem afetar a duração da bateria"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Parar"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Parado"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Concluído"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index fc40c5d..e7339dd 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmado"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em Confirmar para concluir."</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado c/ rosto. Prima o ícone de desb. p/ continuar."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado com o rosto. Prima para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Prima para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Prima ícone de desbloqueio para continuar"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilizar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utilizar padrão"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize rapidamente para cima para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Prima o ícone de desbloqueio para abrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado com o rosto. Prima o ícone de desbl. p/ abrir."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado com o rosto. Prima para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Prima para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Rosto reconhecido. Prima o ícone de desbloqueio para abrir."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Deslize rapidamente para cima para tentar novamente."</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquear para utilizar o NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua entidade."</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Pretende continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo convidado"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Está no modo convidado"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Adicionar um novo utilizador?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar apps para todos os outros utilizadores."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ao adicionar um novo utilizador, o modo convidado é fechado e todas as apps e dados da sessão de convidado atual são eliminados."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de utilizadores alcançado"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Pode adicionar até <xliff:g id="COUNT">%d</xliff:g> utilizadores.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> não suporta funcionalidades de conversa."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar estas notificações."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Não é possível modificar as notificações de chamadas."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar este grupo de notificações aqui."</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notificação de app proxy"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Todas as notificações da app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -906,7 +904,7 @@
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dados móveis"</string>
     <string name="preference_summary_default_combination" msgid="8453246369903749670">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="NETWORKMODE">%2$s</xliff:g>"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Ligado"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Não é efetuada ligação de dados móveis automática"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Sem ligação automática com dados móveis"</string>
     <string name="mobile_data_no_connection" msgid="1713872434869947377">"Sem ligação"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Nenhuma outra rede disponível"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"Sem redes disponíveis"</string>
@@ -924,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adicionar mosaico"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Não adicion. mosaico"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Selecione utilizador"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps estão ativas</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app está ativa</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Novas informações"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativas"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Mesmo que não esteja a usar estas apps, continuam ativas e podem afetar a autonomia da bateria"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Parar"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Parada"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Concluir"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 36ac0d2..97eb716 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo visitante"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Você está no modo visitante"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Adicionar novo usuário?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Quando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para os demais usuários."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ao adicionar um novo usuário, o dispositivo vai sair do modo visitante e excluir todos os apps e dados da Sessão de visitante atual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de usuários atingido"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">É possível adicionar até <xliff:g id="COUNT">%d</xliff:g> usuário.</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adicionar bloco"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Não adicionar bloco"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Selecionar usuário"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app está ativo</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps estão ativos</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nova informação"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativos"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Mesmo que você não esteja usando esses apps, eles ainda ficam ativos e podem afetar a duração da bateria"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Parar"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Parado"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Concluído"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 683b395..e4c7dbe 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -346,6 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vreți să continuați sesiunea?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Începeți din nou"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, continuați"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modul pentru invitați"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Folosiți modul pentru invitați"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Adăugați un utilizator nou?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Când adăugați un utilizator nou, acesta trebuie să-și configureze spațiul.\n\nOrice utilizator poate actualiza aplicațiile pentru toți ceilalți utilizatori."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Dacă adăugați un utilizator nou, veți ieși din modul pentru invitați și se vor șterge toate aplicațiile și datele din sesiunea pentru invitați actuală."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Ați atins limita de utilizatori"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="few">Puteți adăuga maximum <xliff:g id="COUNT">%d</xliff:g> utilizatori.</item>
@@ -923,11 +928,14 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adăugați un card"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nu adăugați un card"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Alegeți utilizatorul"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplicații sunt active</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> de aplicații sunt active</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicație este activă</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informații noi"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicații active"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Chiar dacă nu folosiți aceste aplicații, ele sunt active și pot influența autonomia bateriei"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Opriți"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Oprită"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Gata"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 5733352..d0e5f83 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -348,6 +348,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Продолжить сеанс?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Начать заново"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продолжить"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Гостевой режим"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Включен гостевой режим"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Добавить пользователя?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Когда вы добавите пользователя, ему потребуется настроить профиль.\n\nЛюбой пользователь устройства может обновлять приложения для всех аккаунтов."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Добавив нового пользователя, вы выйдете из гостевого режима. Все приложения и данные в текущем гостевом сеансе будут удалены."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнут лимит"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Можно добавить не более <xliff:g id="COUNT">%d</xliff:g> пользователя.</item>
@@ -929,11 +934,15 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> приложение активно</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> приложения активно</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> приложений активно</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> приложения активно</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Новая информация"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активные приложения"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Эти приложения активны и могут влиять на время работы от батареи, даже когда вы ими не пользуетесь."</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Остановить"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Остановлено"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Готово"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 65a07ef..723deb2 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ඔබගේ සැසිය දිගටම කරගෙන යෑමට ඔබට අවශ්‍යද?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"යළි මුල සිට අරඹන්න"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ඔව්, දිගටම කරගෙන යන්න"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ආගන්තුක ප්‍රකාරය"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ඔබ ආගන්තුක ප්‍රකාරයේ සිටී"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"අලුත් පරිශීලකයෙක් එක් කරන්නද?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ඔබ අලුත් පරිශීලකයෙක් එකතු කරන විට, එම පුද්ගලයා ඔහුගේ වැඩ කරන ඉඩ සකසා ගත යුතුය.\n\nසියළුම අනෙක් පරිශීලකයින් සඳහා ඕනෑම පරිශීලකයෙකුට යාවත්කාලීන කළ හැක."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"නව පරිශීලකයෙකු එක් කිරීම ආගන්තුක මාදිලියෙන් පිටවී වත්මන් ආගන්තුක සැසියෙන් සියලුම යෙදුම් සහ දත්ත මකනු ඇත."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"පරිශීලක සීමාවට ළඟා විය"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">ඔබට පරිශීලකයින් <xliff:g id="COUNT">%d</xliff:g>ක් දක්වා එක් කළ හැකිය.</item>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 0b46c88..02e2e20 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -35,7 +35,7 @@
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zariadeniu <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> pristupovať k zariadeniu <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTejto aplikácii nebolo udelené povolenie na nahrávanie, môže však snímať zvuk cez toto zariadenie USB."</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Povoliť apl. <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zar. <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Otvoriť <xliff:g id="APPLICATION">%1$s</xliff:g> na spravovanie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+    <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Otvoriť aplikáciu <xliff:g id="APPLICATION">%1$s</xliff:g> na spravovanie zariadenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Tejto aplikácii nebolo udelené povolenie na nahrávanie, ale môže nahrávať zvuk cez toto zariadenie USB. Ak budete s týmto zariadením používať aplikáciu <xliff:g id="APPLICATION">%1$s</xliff:g>, nemusíte počuť hovory, upozornenia ani budíky."</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ak budete s týmto zariadením používať aplikáciu <xliff:g id="APPLICATION">%1$s</xliff:g>, nemusíte počuť hovory, upozornenia ani budíky."</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zariadeniu <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -348,6 +348,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relácii pokračovať?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začať odznova"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Áno, pokračovať"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Režim pre hostí"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Ste v režime pre hostí"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Pridať nového používateľa?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor.\n\nKtorýkoľvek používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ak pridáte nového používatelia, ukončí sa režim pre hostí a odstránia sa všetky aplikácie a údaje z aktuálnej relácie hosťa."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dosiahnutý limit počtu používateľov"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="few">Môžete pridať maximálne <xliff:g id="COUNT">%d</xliff:g> používateľov.</item>
@@ -425,7 +430,7 @@
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikácia je pripnutá"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho stlačením a podržaním tlačidiel Späť a Prehľad."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho pridržaním tlačidiel Späť a Domov."</string>
-    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Táto možnosť ponechá položku v zobrazení, dokým ju neodopnete. Odpojíte ju potiahnutím nahor a pridržaním."</string>
+    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Táto možnosť ponechá položku v zobrazení, dokým ju neodopnete potiahnutím nahor a pridržaním."</string>
     <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho stlačením a podržaním tlačidla Prehľad."</string>
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho pridržaním tlačidla Domov."</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Môže mať prístup k osobným údajom (napríklad kontaktom a obsahu správ)."</string>
@@ -929,11 +934,15 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Pridať kartu"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nepridať kartu"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Vyberte používateľa"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikácie sú aktívne</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> apps are active</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikácií je aktívnych</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikácia je aktívna</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nové informácie"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktívne aplikácie"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Aj keď tieto aplikácie nepoužívate, stále sú aktívne a môžu ovplyvňovať výdrž batérie"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ukončiť"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Zastavená"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Hotovo"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 8f15cfd..c3669f3 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -348,6 +348,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite nadaljevati sejo?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začni znova"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nadaljuj"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Način za goste"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Ste v načinu za goste"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Dodajanje novega uporabnika?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Ko dodate novega uporabnika, mora ta nastaviti svoj prostor.\n\nVsak uporabnik lahko posodobi aplikacije za vse druge uporabnike."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Če dodate novega uporabnika, se bo način za goste zaprl, aplikacije in podatki v trenutni seji gosta pa bodo izbrisani."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Omejitev uporabnikov je dosežena"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Dodate lahko do <xliff:g id="COUNT">%d</xliff:g> uporabnika.</item>
@@ -929,11 +934,15 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj ploščico"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne dodaj ploščice"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Izberite uporabnika"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivna</item>
+      <item quantity="two"><xliff:g id="COUNT_1">%s</xliff:g> aplikaciji sta aktivni</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikacije so aktivne</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacij je aktivnih</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Tudi če teh aplikacij ne uporabljate, so še vedno aktivne in morda vplivajo na čas delovanja baterije."</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ustavi"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Ustavljeno"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Končano"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 0205062..3d0fcf0 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Dëshiron ta vazhdosh sesionin tënd?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Fillo nga e para"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Po, vazhdo"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modaliteti \"vizitor\""</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Je në modalitetin \"vizitor\""</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Të shtohet përdorues i ri?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kur shton një përdorues të ri, ai person duhet të konfigurojë hapësirën e vet.\n\nÇdo përdorues mund t\'i përditësojë aplikacionet për të gjithë përdoruesit e tjerë."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Shtimi i një përdoruesi të ri do të të nxjerrë nga modaliteti \"vizitor\" dhe do të fshijë të gjitha aplikacionet dhe të dhënat nga sesioni aktual për vizitorë."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"U arrit kufiri i përdoruesve"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Mund të shtosh deri në <xliff:g id="COUNT">%d</xliff:g> përdorues.</item>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 7d85e4c..31104f1 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -346,6 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Желите ли да наставите сесију?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни из почетка"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, настави"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Режим госта"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Користите режим госта"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Додајете новог корисника?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Када додате новог корисника, та особа треба да подеси свој простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Додавањем новог корисника изаћи ћете из режима госта и избрисаћете све апликације и податке из актуелне сесије госта."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнут максимални број корисника"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Можете да додате највише <xliff:g id="COUNT">%d</xliff:g> корисника.</item>
@@ -923,11 +928,14 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> апликација је активна</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> апликације су активне</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> апликација је активно</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нове информације"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активне апликације"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Чак и ако не користите ове апликације, оне су и даље активне и могу да утичу на трајање батерије"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Заустави"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Заустављено"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Готово"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 4ed90a6..76e4f96 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vill du fortsätta sessionen?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Börja om"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsätt"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gästläge"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Du är i gästläge"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Lägga till ny användare?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"När du lägger till en ny användare måste den personen konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användares räkning."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Om du lägger till en ny användare avslutas gästläget och alla appar och all data från den aktuella gästsessionen raderas."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Användargränsen har nåtts"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Det går att lägga till upp till <xliff:g id="COUNT">%d</xliff:g> användare.</item>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 23acb09..cf3ba17 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -36,8 +36,8 @@
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Ungependa kuruhusu <xliff:g id="APPLICATION">%1$s</xliff:g> ifikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nProgramu hii haijapewa ruhusa ya kurekodi lakini inaweza kurekodi sauti kupitia kifaa hiki cha USB."</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Ungependa kuruhusu <xliff:g id="APPLICATION">%1$s</xliff:g> ifikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Ungependa kufungua <xliff:g id="APPLICATION">%1$s</xliff:g> ishughulikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Programu hii haijapewa ruhusa ya kurekodi lakini inaweza kurekodi sauti kupitia kifaa hiki cha USB. Ukitumia <xliff:g id="APPLICATION">%1$s</xliff:g> kwenye kifaa hiki kunaweza kuzuia kusikia simu, arifa na kengele."</string>
-    <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ukitumia <xliff:g id="APPLICATION">%1$s</xliff:g> kwenye kifaa hiki kunaweza kuzuia kusikia simu, arifa na kengele."</string>
+    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Programu hii haijapewa ruhusa ya kurekodi lakini inaweza kurekodi sauti kupitia kifaa hiki cha USB. Ukitumia <xliff:g id="APPLICATION">%1$s</xliff:g> kwenye kifaa hiki huenda usisikie simu, arifa na kengele."</string>
+    <string name="usb_audio_device_prompt" msgid="7944987408206252949">"Ukitumia <xliff:g id="APPLICATION">%1$s</xliff:g> kwenye kifaa hiki huenda usisikie simu, arifa na kengele."</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Ungependa kuruhusu <xliff:g id="APPLICATION">%1$s</xliff:g> ifikie <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
     <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Ungependa kufungua <xliff:g id="APPLICATION">%1$s</xliff:g> ili itumie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Ungependa kufungua <xliff:g id="APPLICATION">%1$s</xliff:g> ishughulikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nProgramu hii haijapewa ruhusa ya kurekodi lakini inaweza kurekodi sauti kupitia kifaa hiki cha USB."</string>
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Je, unataka kuendelea na kipindi chako?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Anza upya"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ndiyo, endelea"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Matumizi ya wageni"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Unatumia hali ya wageni"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Ungependa kuongeza mtumiaji?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Mtumiaji mpya utakayemwongeza atahitaji kuongeza akaunti yake.\n\nMtumiaji yoyote anaweza kusasisha programu kwa niaba ya wengine wote."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Kuongeza mtumiaji mpya kutaondoa matumizi ya wageni yaliyopo na kufuta programu na data kutoka kwenye kipindi cha mgeni cha sasa."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Umefikia kima cha juu cha watumiaji"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Unaruhusiwa kuongeza hadi watumiaji <xliff:g id="COUNT">%d</xliff:g>.</item>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 2264671..008299b 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -60,11 +60,15 @@
 
     <dimen name="global_actions_grid_item_layout_height">80dp</dimen>
 
+    <dimen name="qs_brightness_margin_bottom">16dp</dimen>
+
     <!--  For large screens the security footer appears below the footer,
     same as phones in portrait  -->
     <dimen name="qs_security_footer_single_line_height">48dp</dimen>
     <dimen name="qs_security_footer_background_inset">0dp</dimen>
 
+    <dimen name="qs_panel_padding_top">8dp</dimen>
+
     <!-- The width of large/content heavy dialogs (e.g. Internet, Media output, etc) -->
     <dimen name="large_dialog_width">472dp</dimen>
 
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index a9dec1f..238ba15 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"உறுதிப்படுத்தப்பட்டது"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"முடிக்க \'உறுதிப்படுத்துக\' என்பதை தட்டவும்"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. தொடர, அன்லாக் ஐகானை அழுத்துக."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. தொடர அழுத்தவும்."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அழுத்தவும்."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அன்லாக் ஐகானை அழுத்தவும்."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"அங்கீகரிக்கப்பட்டது"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"பின்னைப் பயன்படுத்து"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"பேட்டர்னைப் பயன்படுத்து"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"திறக்க, அன்லாக் ஐகானை அழுத்தவும்"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. திறக்க, அன்லாக் ஐகானை அழுத்துக."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. திறக்க அழுத்தவும்."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"முகம் அங்கீகரிக்கப்பட்டது. திறக்க அழுத்தவும்."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"முகம் அங்கீகரிக்கப்பட்டது. திறக்க அன்லாக் ஐகானை அழுத்தவும்."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"மீண்டும் முயல மேல்நோக்கி ஸ்வைப் செய்யவும்"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCயைப் பயன்படுத்த அன்லாக் செய்யவும்"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"உங்கள் அமர்வைத் தொடர விருப்பமா?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"மீண்டும் தொடங்கு"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"தொடரவும்"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"கெஸ்ட் பயன்முறை"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"கெஸ்ட் பயன்முறையில் உள்ளீர்கள்"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"புதியவரைச் சேர்க்கவா?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"புதிய பயனரைச் சேர்க்கும்போது, அவர் தனக்கான இடத்தை அமைக்க வேண்டும்.\n\nஎந்தவொரு பயனரும், மற்ற எல்லா பயனர்களுக்காகவும் ஆப்ஸைப் புதுப்பிக்கலாம்."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"புதிய பயனரைச் சேர்த்தால் கெஸ்ட் பயன்முறையில் இருந்து வெளியேற்றப்படுவீர்கள். மேலும் தற்போதைய கெஸ்ட் அமர்வின் ஆப்ஸ் மற்றும் தரவு அனைத்தும் நீக்கப்படும்."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"பயனர் வரம்பை அடைந்துவிட்டீர்கள்"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> பயனர்கள் வரை சேர்க்க முடியும்.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"முன்னுரிமை"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"உரையாடல் அம்சங்களை <xliff:g id="APP_NAME">%1$s</xliff:g> ஆதரிக்காது"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"இந்த அறிவிப்புகளை மாற்ற இயலாது."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"அழைப்பு அறிவிப்புகளை மாற்ற முடியாது."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"இந்த அறிவுப்புக் குழுக்களை இங்கே உள்ளமைக்க இயலாது"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ப்ராக்ஸியான அறிவிப்பு"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"அனைத்து <xliff:g id="APP_NAME">%1$s</xliff:g> அறிவிப்புகளும்"</string>
@@ -924,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ஆப்ஸ் செயலிலுள்ளன</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ஆப்ஸ் செயலிலுள்ளது</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"புதிய தகவல்கள்"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"செயலிலுள்ள ஆப்ஸ்"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"இந்த ஆப்ஸைப் பயன்படுத்தாமல் இருந்தாலும்கூட, அவை செயலிலிருந்துகொண்டு பேட்டரி ஆயுளைப் பாதிக்கக்கூடும்"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"நிறுத்து"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"இயங்கவில்லை"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"முடிந்தது"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 3cc3d26..26ae7bb 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"నిర్ధారించబడింది"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"పూర్తి చేయడానికి \"నిర్ధారించు\" నొక్కండి"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. కొనసాగించడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. కొనసాగించడానికి నొక్కండి."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ముఖం గుర్తించబడింది. కొనసాగించడానికి నొక్కండి."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ముఖం గుర్తించబడింది. కొనసాగడానికి అన్‌లాక్ చిహ్నం నొక్కండి."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ప్రామాణీకరించబడింది"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"పిన్‌ను ఉపయోగించు"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ఆకృతిని ఉపయోగించు"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"తెరవడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. తెరవడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. తెరవడానికి నొక్కండి."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ముఖం గుర్తించబడింది. తెరవడానికి నొక్కండి."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ముఖం గుర్తించబడింది. తెరవడానికి అన్‌లాక్ చిహ్నం నొక్కండి."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"మళ్ళీ ప్రయత్నించడానికి పైకి స్వైప్ చేయండి"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCని ఉపయోగించడానికి అన్‌లాక్ చేయండి"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ఈ పరికరం మీ సంస్థకు చెందినది"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"మీరు మీ సెషన్‌ని కొనసాగించాలనుకుంటున్నారా?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"మొదటి నుండి ప్రారంభించు"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"అవును, కొనసాగించు"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"గెస్ట్ మోడ్"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"మీరు గెస్ట్ మోడ్‌లో ఉన్నారు"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"కొత్త యూజర్‌ను జోడించాలా?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ఒక కొత్త యూజర్‌ను మీరు జోడించినప్పుడు, ఆ వ్యక్తి తన స్పేస్‌ను సెటప్ చేసుకోవాలి.\n\nఏ యూజర్ అయినా మిగతా అందరు యూజర్‌ల కోసం యాప్‌లను అప్‌డేట్ చేయగలరు."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"కొత్త యూజర్‌ను జోడించడం వలన గెస్ట్ మోడ్ నుండి నిష్క్రమించబడుతుంది, ప్రస్తుత గెస్ట్ సెషన్ నుండి అన్ని యాప్‌లు, డేటా తొలగించండి."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"వినియోగదారు పరిమితిని చేరుకున్నారు"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">మీరు <xliff:g id="COUNT">%d</xliff:g> వినియోగదారుల వరకు జోడించవచ్చు.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"ప్రాధాన్యత"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> సంభాషణ ఫీచర్‌లను సపోర్ట్ చేయదు"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ఈ నోటిఫికేషన్‌లను సవరించడం వీలుపడదు."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"కాల్ నోటిఫికేషన్‌లను ఎడిట్ చేయడం సాధ్యం కాదు."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ఈ నోటిఫికేషన్‌ల సమూహాన్ని ఇక్కడ కాన్ఫిగర్ చేయలేము"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ప్రాక్సీ చేయబడిన నోటిఫికేషన్"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"అన్ని <xliff:g id="APP_NAME">%1$s</xliff:g> నోటిఫికేషన్‌లు"</string>
@@ -924,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> యాప్‌లు యాక్టివ్‌గా ఉన్నాయి</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> యాప్ యాక్టివ్‌గా ఉంది</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"కొత్త సమాచారం"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"యాక్టివ్‌గా ఉన్న యాప్‌లు"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"మీరు ఈ యాప్‌లను ఉపయోగించకపోయినా, అవి ఇప్పటికీ యాక్టివ్‌గా ఉంటాయి, బ్యాటరీ జీవితకాలాన్ని ప్రభావితం చేయవచ్చు"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ఆపివేయండి"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ఆపివేయబడింది"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"పూర్తయింది"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 97806ce..6416300 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"คุณต้องการอยู่ในเซสชันต่อไปไหม"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"เริ่มต้นใหม่"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ใช่ ดำเนินการต่อ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"โหมดผู้มาเยือน"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"คุณอยู่ในโหมดผู้มาเยือน"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"ต้องการเพิ่มผู้ใช้ใหม่ใช่ไหม"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"เมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตนเอง\n\nผู้ใช้ทุกคนสามารถอัปเดตแอปสำหรับผู้ใช้รายอื่นทุกคนได้"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"การเพิ่มผู้ใช้ใหม่จะเป็นการออกจากโหมดผู้มาเยือน และจะลบแอปและข้อมูลจากเซสชันผู้มาเยือนในปัจจุบัน"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ถึงขีดจำกัดผู้ใช้แล้ว"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">คุณเพิ่มผู้ใช้ได้สูงสุด <xliff:g id="COUNT">%d</xliff:g> คน</item>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other">ทำงานอยู่ <xliff:g id="COUNT_1">%s</xliff:g> แอป</item>
+      <item quantity="one">ทำงานอยู่ <xliff:g id="COUNT_0">%s</xliff:g> แอป</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ข้อมูลใหม่"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ใช้งานอยู่"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"แม้ว่าคุณจะไม่ได้ใช้งาน แอปเหล่านี้ก็ยังทำงานอยู่และอาจส่งผลต่ออายุการใช้งานแบตเตอรี่"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"หยุด"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"หยุดแล้ว"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"เสร็จ"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 294fa00..4015def 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Gusto mo bang ipagpatuloy ang iyong session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Magsimulang muli"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oo, magpatuloy"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Naka-guest mode ka"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Magdagdag ng bagong user?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kapag nagdagdag ka ng bagong user, kailangang i-set up ng taong iyon ang kanyang espasyo.\n\nAng sinumang user ay maaaring mag-update ng mga app para sa lahat ng iba pang user."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Kapag nagdagdag ka ng bagong user, aalis sa guest mode at made-delete ang lahat ng app at data mula sa kasalukuyang session ng bisita."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Naabot na ang limitasyon sa user"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Maaari kang magdagdag ng hanggang <xliff:g id="COUNT">%d</xliff:g> user.</item>
@@ -917,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Idagdag ang tile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Huwag idagdag"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Pumili ng user"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app ang aktibo</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> na app ang aktibo</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Bagong impormasyon"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Mga aktibong app"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Kahit na hindi mo ginagamit ang mga app na ito, aktibo pa rin ang mga ito at posibleng maapektuhan ng mga ito ang tagal ng baterya"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ihinto"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Inihinto"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Tapos na"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index efa4043..af7f6d7 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Onaylandı"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tamamlamak için Onayla\'ya dokunun"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Kilit, yüzünüzle açıldı. Kilit açma simgesine basın."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Cihazın kilidini yüzünüzle açtınız. Devam etmek için basın."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yüzünüz tanındı. Devam etmek için basın."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yüzünüz tanındı. Kilit açma simgesine basın."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kimliği Doğrulandı"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN kullan"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Deseni kullan"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Açmak için yukarı kaydırın"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Açmak için Kilit açma simgesine basın"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Kilit, yüzünüzle açıldı. Kilit açma simgesine basın."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Cihazın kilidini yüzünüzle açtınız. Açmak için basın."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Yüzünüz tanındı. Açmak için basın."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Yüzünüz tanındı. Kilit açma simgesine basın."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Tekrar denemek için yukarı kaydırın"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC\'yi kullanmak için kilidi açın"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz, kuruluşunuza ait"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Oturumunuza devam etmek istiyor musunuz?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Baştan başla"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Evet, devam et"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Misafir modu"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Misafir modundasınız"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Yeni kullanıcı eklensin mi?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Yeni bir kullanıcı eklediğinizde, bu kişinin kendi alanını ayarlaması gerekir.\n\nHerhangi bir kullanıcı, diğer tüm kullanıcılar için uygulamaları güncelleyebilir."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Yeni bir kullanıcı eklendiğinde misafir modundan çıkılarak mevcut misafir oturumundaki tüm uygulamalar ve veriler silinir."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Kullanıcı sınırına ulaşıldı"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">En fazla <xliff:g id="COUNT">%d</xliff:g> kullanıcı ekleyebilirsiniz.</item>
@@ -422,14 +421,14 @@
     <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Altyazı yer paylaşımı"</string>
     <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"etkinleştir"</string>
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"devre dışı bırak"</string>
-    <string name="screen_pinning_title" msgid="9058007390337841305">"Uygulama sabitlenmiştir"</string>
+    <string name="screen_pinning_title" msgid="9058007390337841305">"Uygulama sabitlendi"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Geri\'ye ve Genel Bakış\'a dokunup basılı tutun."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Geri\'ye ve Ana sayfaya dokunup basılı tutun."</string>
     <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Bu, sabitleme kaldırılana kadar öğenin görünmesini sağlar. Sabitlemeyi kaldırmak için yukarı kaydırıp basılı tutun."</string>
     <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Genel bakış\'a dokunup basılı tutun."</string>
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Ana sayfaya dokunup basılı tutun."</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Kişisel verilere erişilebilir (ör. kişiler ve e-posta içerikleri)."</string>
-    <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Sabitlenmiş uygulama diğer uygulamaları açabilir."</string>
+    <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Sabitlenen uygulama diğer uygulamaları açabilir."</string>
     <string name="screen_pinning_toast" msgid="8177286912533744328">"Bu uygulamanın sabitlemesini kaldırmak için Geri ve Genel Bakış düğmelerine dokunup basılı tutun"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Bu uygulamanın sabitlemesini kaldırmak için Geri ve Ana sayfa düğmelerine dokunup basılı tutun"</string>
     <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Bu uygulamanın sabitlemesini kaldırmak için yukarı kaydırıp tutun"</string>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Öncelikli"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>, sohbet özelliklerini desteklemiyor"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirimler değiştirilemez."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Arama bildirimleri değiştirilemez."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Bu bildirim grubu burada yapılandırılamaz"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Proxy uygulanan bildirim"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Tüm <xliff:g id="APP_NAME">%1$s</xliff:g> bildirimleri"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 66de3bb..e4a716b 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Підтверджено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Щоб завершити, натисніть \"Підтвердити\""</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Розблоковано (фейсконтроль). Натисніть значок розблокування."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Розблоковано (фейсконтроль). Натисніть, щоб продовжити."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Обличчя розпізнано. Натисніть, щоб продовжити."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Обличчя розпізнано. Натисніть значок розблокування."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Автентифіковано"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Ввести PIN-код"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Намалювати ключ"</string>
@@ -322,12 +319,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Щоб відкрити, натисніть значок розблокування."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Розблоковано (фейсконтроль). Натисніть значок розблокування."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Розблоковано (фейсконтроль). Натисніть, щоб відкрити."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Обличчя розпізнано. Натисніть, щоб відкрити."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Обличчя розпізнано. Натисніть значок розблокування."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Проведіть пальцем угору, щоб повторити спробу"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Розблокуйте екран, щоб скористатись NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Цей пристрій належить вашій організації"</string>
@@ -354,6 +348,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Продовжити сеанс?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почати знову"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Так, продовжити"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Режим гостя"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Ви ввійшли в режимі гостя"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Додати нового користувача?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Користувач має налаштувати свій профіль після створення.\n\nБудь-який користувач пристрою може оновлювати додатки для решти користувачів."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Якщо додати нового користувача, ви вийдете з режиму гостя, а всі додатки й дані з поточного сеансу цього режиму буде видалено."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Ви досягли ліміту користувачів"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Можна додати до <xliff:g id="COUNT">%d</xliff:g> користувача.</item>
@@ -524,8 +523,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Пріоритет"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не підтримує функції розмов"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ці сповіщення не можна змінити."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Сповіщення про виклик не можна змінити."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Цю групу сповіщень не можна налаштувати тут"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Проксі-сповіщення"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Усі сповіщення від додатка <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 61a20c3..7bf9bc5 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"کیا آپ اپنا سیشن جاری رکھنا چاہتے ہیں؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"دوبارہ شروع کریں"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ہاں، جاری رکھیں"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"مہمان وضع"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"آپ مہمان وضع میں ہیں"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"نیا صارف شامل کریں؟"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"جب آپ ایک نیا صارف شامل کرتے ہیں تو اس شخص کو اپنی جگہ کو ترتیب دینے کی ضرورت ہوتی ہے۔\n\nکوئی بھی صارف دیگر سبھی صارفین کیلئے ایپس کو اپ ڈیٹ کر سکتا ہے۔"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"نئے صارف کو شامل کرنے سے مہمان وضع سے باہر نکل جائے گا اور موجودہ مہمان سیشن سے تمام ایپس اور ڈیٹا حذف ہو جائیں گے۔"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"صارف کی حد مکمل ہو گئی"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">صرف <xliff:g id="COUNT">%d</xliff:g> صارفین بنائے جا سکتے ہیں۔</item>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ایپس فعال ہیں</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ایپ فعال ہے</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"نئی معلومات"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"فعال ایپس"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"آپ کے ان ایپس کے استعمال نہ کرنے کے باوجود بھی یہ فعال رہتی ہیں اور بیٹری کی لائف کو متاثر کر سکتی ہیں"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"روکیں"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"رکی ہوئی ہے"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"ہو گیا"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index fe583f5..c55e3a8 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Tasdiqlangan"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tasdiqlash uchun tegining"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Yuz orqali ochilgan. Davom etish uchun ochish belgisini bosing."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Yuz orqali ochildi. Davom etish uchun bosing."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yuz aniqlandi. Davom etish uchun bosing."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yuz aniqlandi. Davom etish uchun ochish belgisini bosing."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Tasdiqlandi"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN kod kiritish"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Grafik kalitdan foydalanish"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Ochish uchun tepaga suring"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ochish uchun ochish belgisini bosing"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Yuz orqali ochilgan. Ochish uchun ochish belgisini bosing."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Yuz orqali ochildi. Ochish uchun bosing."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Yuz aniqlandi. Ochish uchun bosing."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Yuz aniqlandi. Ochish uchun ochish belgisini bosing."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Qayta urinish uchun tepaga suring"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ishlatish uchun qurilma qulfini oching"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu qurilma tashkilotingizga tegishli"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Seansni davom ettirmoqchimisiz?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Boshidan boshlansin"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ha, davom ettirilsin"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mehmon rejimi"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Mehmon rejimidasiz"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Foydalanuvchi qo‘shilsinmi?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Yangi profil qo‘shilgach, uni sozlash lozim.\n\nQurilmaning istalgan foydalanuvchisi ilovalarni barcha hisoblar uchun yangilashi mumkin."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Yangi foydalanuvchi kiritilsa, mehmon rejimi tark etiladi va joriy mehmon seansidagi barcha ilova va ularning maʼlumotlari tozalanadi."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limitga yetib keldi"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> tagacha foydalanuvchi qo‘shish mumkin.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Muhim"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasida suhbat funksiyalari ishlamaydi"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirishnomalarni tahrirlash imkonsiz."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Chaqiruv bildirishnomalarini tahrirlash imkonsiz."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ushbu bildirishnomalar guruhi bu yerda sozlanmaydi"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Ishonchli bildirishnoma"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Barcha <xliff:g id="APP_NAME">%1$s</xliff:g> bildirishnomalari"</string>
@@ -845,7 +843,7 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> ta qurilma tanlandi"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(uzildi)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Xatolik. Qayta urinish uchun bosing."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yangi qurilmani ulash"</string>
+    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yangi qurilmani juftlash"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu seansni translatsiya qilish uchun ilovani oching."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Notanish ilova"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Toʻxtatish"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 9fd4f31..6a2fdf8 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Ðã xác nhận"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Nhấn vào Xác nhận để hoàn tất"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Đã mở khoá bằng khuôn mặt. Nhấn biểu tượng mở khoá để tiếp tục."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Đã mở khoá bằng khuôn mặt. Hãy nhấn để tiếp tục."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Đã nhận diện khuôn mặt. Hãy nhấn để tiếp tục."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Đã nhận diện khuôn mặt. Nhấn biểu tượng mở khoá để tiếp tục."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Đã xác thực"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Dùng mã PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Dùng hình mở khóa"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Vuốt lên để mở"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Nhấn biểu tượng mở khoá để mở"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Đã mở khoá bằng khuôn mặt. Nhấn biểu tượng mở khoá để mở."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Đã mở khoá bằng khuôn mặt. Nhấn để mở."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Đã nhận diện khuôn mặt. Nhấn để mở."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Đã nhận diện khuôn mặt. Nhấn biểu tượng mở khoá để mở."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Vuốt lên để thử lại"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Mở khóa để sử dụng NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Thiết bị này thuộc về tổ chức của bạn"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Bạn có muốn tiếp tục phiên của mình không?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Bắt đầu lại"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Có, tiếp tục"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Chế độ khách"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Bạn đang ở chế độ khách"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Thêm người dùng mới?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Khi bạn thêm người dùng mới, họ cần thiết lập không gian của mình.\n\nMọi người dùng đều có thể cập nhật ứng dụng cho tất cả người dùng khác."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Khi thêm người dùng mới, chế độ khách sẽ bị thoát và mọi ứng dụng cũng như dữ liệu trong phiên khách hiện tại sẽ bị xoá."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Đã đạt đến giới hạn người dùng"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Bạn có thể thêm tối đa <xliff:g id="COUNT">%d</xliff:g> người dùng.</item>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Mức độ ưu tiên"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> không hỗ trợ các tính năng trò chuyện"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Không thể sửa đổi các thông báo này."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Không thể sửa đổi các thông báo cuộc gọi."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Không thể định cấu hình nhóm thông báo này tại đây"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Thông báo đã xử lý qua máy chủ proxy"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Tất cả thông báo của <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -924,11 +922,13 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Thêm ô"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Không thêm ô"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Chọn người dùng"</string>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other">Ứng dụng <xliff:g id="COUNT_1">%s</xliff:g> đang hoạt động</item>
+      <item quantity="one">Ứng dụng <xliff:g id="COUNT_0">%s</xliff:g> đang hoạt động</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Thông tin mới"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ứng dụng đang hoạt động"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"Ngay cả khi bạn không sử dụng, những ứng dụng này vẫn hoạt động và có thể ảnh hưởng đến tuổi thọ pin"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Dừng"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Đã dừng"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"Xong"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 3fa6c60..223c700 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"要继续您的会话吗?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新开始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是,继续"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"访客模式"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"您当前处于访客模式"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"要添加新用户吗?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"当您添加新用户时,该用户必须设置自己的空间。\n\n任何用户均可为其他所有用户更新应用。"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"如果添加新用户,系统将退出访客模式并删除当前访客会话中的所有应用和数据。"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"已达到用户数上限"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">您最多可以添加 <xliff:g id="COUNT">%d</xliff:g> 位用户。</item>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 6950c20..ccb9d12 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"您要繼續您的工作階段嗎?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是的,請繼續"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"訪客模式"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"您正在使用訪客模式"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"新增使用者?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"新增的使用者需要自行設定個人空間。\n\n任何使用者均可為所有其他使用者更新應用程式。"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"新增使用者後,系統就會結束訪客模式,並刪除目前訪客工作階段中的所有應用程式和資料。"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"已達到使用者上限"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">您可以加入多達 <xliff:g id="COUNT">%d</xliff:g> 個使用者。</item>
@@ -917,11 +922,13 @@
     <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>
-    <!-- no translation found for fgs_manager_footer_label (790443735462280164) -->
+    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
+      <item quantity="other">已啟用 <xliff:g id="COUNT_1">%s</xliff:g> 個應用程式</item>
+      <item quantity="one">已啟用 <xliff:g id="COUNT_0">%s</xliff:g> 個應用程式</item>
+    </plurals>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"新資料"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的應用程式"</string>
-    <!-- no translation found for fgs_manager_dialog_message (6839542063522121108) -->
-    <skip />
+    <string name="fgs_manager_dialog_message" msgid="6839542063522121108">"即使您並非正在使用這些應用程式,它們仍然在啟用狀態,而且可能會影響電池壽命"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"停止"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"已停止"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"完成"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 4222030..874da6b 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -344,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"你要繼續這個工作階段嗎?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是,繼續"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"訪客模式"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"你目前處於訪客模式"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"要新增使用者嗎?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"新增的使用者需要自行設定個人空間。\n\n任何使用者皆可為其他所有使用者更新應用程式。"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"新增使用者後,系統就會結束訪客模式,並刪除目前訪客工作階段中的所有應用程式和資料。"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"已達使用者數量上限"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">最多可新增 <xliff:g id="COUNT">%d</xliff:g> 位使用者。</item>
@@ -419,7 +424,7 @@
     <string name="screen_pinning_title" msgid="9058007390337841305">"應用程式已固定"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"這會讓目前的螢幕畫面保持顯示狀態,直到取消固定為止。按住 [返回] 按鈕和 [總覽] 按鈕即可取消固定。"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"這會讓應用程式顯示在螢幕上,直到取消固定為止。按住 [返回] 按鈕和主畫面按鈕即可取消固定。"</string>
-    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"這會讓目前的螢幕畫面保持顯示,直到取消固定為止。向上滑動並按住即可取消固定。"</string>
+    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"這會讓應用程式一直顯示在螢幕畫面上,直到你取消固定為止。向上滑動並按住即可取消固定。"</string>
     <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"這會讓目前的螢幕畫面保持顯示狀態,直到取消固定為止。按住 [總覽] 按鈕即可取消固定。"</string>
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"這會讓應用程式顯示在螢幕上,直到取消固定為止。按住主畫面按鈕即可取消固定。"</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"該應用程式或許可存取個人資料 (例如聯絡人和電子郵件內容)。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index bf013c9..a9240ad 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -136,12 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Kuqinisekisiwe"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Thepha okuthi Qinisekisa ukuze uqedele"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ivulwe ngobuso. Cindezela isithonjana sokuvula ukuze uqhubeke."</string>
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
-    <skip />
-    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
-    <skip />
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Vula ngobuso. Cindezela ukuze uqhubeke."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ubuso buyaziwa. Cindezela ukuze uqhubeke."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ubuso buyaziwa. Cindezela isithonjana sokuvula ukuze uqhubeke."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kugunyaziwe"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Sebenzisa iphinikhodi"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Sebenzisa iphethini"</string>
@@ -318,12 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swayiphela phezulu ukuze uvule"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Cindezela isithonjana sokuvula ukuze uvule"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ivulwe ngobuso. Cindezela isithonjana sokuvula ukuze uvule."</string>
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
-    <skip />
-    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
-    <skip />
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Vula ngobuso. Cindezela ukuze uvule."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ubuso buyaziwa. Cindezela ukuze uvule."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ubuso buyaziwa. Cindezela isithonjana sokuvula ukuze uvule."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Swayiphela phezulu ukuze uzame futhi"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Vula ukuze usebenzise i-NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Le divayisi eyenhlangano yakho"</string>
@@ -350,6 +344,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ingabe ufuna ukuqhubeka ngesikhathi sakho?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Qala phansi"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yebo, qhubeka"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Imodi yesivakashi"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Usemodini yesivakashi"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Engeza umsebenzisi omusha?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Uma ungeza umsebenzisi omusha, loyo muntu udinga ukusetha isikhala sakhe.\n\nNoma yimuphi umsebenzisi angabuyekeza izinhlelo zokusebenza kubo bonke abasebenzisi."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ukwengeza umsebenzisi omusha kuzokhipha imodi yesivakashi futhi kusule wonke ama-app nedatha kusuka esikhathini sesihambeli samanje."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Kufinyelelwe kumkhawulo womsebenzisi"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Ungangeza kufikela kubasebenzisi abangu-<xliff:g id="COUNT">%d</xliff:g>.</item>
@@ -422,7 +421,7 @@
     <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Imbondela yamagama-ncazo"</string>
     <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"nika amandla"</string>
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"khubaza"</string>
-    <string name="screen_pinning_title" msgid="9058007390337841305">"Uhlelo lokusebenza luphiniwe"</string>
+    <string name="screen_pinning_title" msgid="9058007390337841305">"I-app iphiniwe"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Lokhu kuyigcina ibukeka uze ususe ukuphina. Thinta uphinde ubambe okuthi Emuva Nokubuka konke ukuze ususe ukuphina."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Lokhu kuyigcina ibonakala uze uyisuse. Thinta uphinde ubambe okuthi Emuva nokuthi Ekhaya ukuze ususe ukuphina."</string>
     <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Lokhu kuyigcina ibonakala uze ususe ukuphina. Swayiphela phezulu uphinde ubambe ukuze ususe ukuphina."</string>
@@ -518,8 +517,7 @@
     <string name="notification_priority_title" msgid="2079708866333537093">"Okubalulekile"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayisekeli izici zengxoxo"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Lezi zaziso azikwazi ukushintshwa."</string>
-    <!-- no translation found for notification_unblockable_call_desc (5907328164696532169) -->
-    <skip />
+    <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Izaziso zekholi azikwazi ukushintshwa."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Leli qembu lezaziso alikwazi ukulungiselelwa lapha"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Isaziso sommeli"</string>
     <string name="notification_channel_dialog_title" msgid="6856514143093200019">"Zonke izaziso ze-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 9e6b277..4b6c0dc 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -714,4 +714,10 @@
         <item>@*android:string/status_bar_alarm_clock</item>
         <item>@*android:string/status_bar_call_strength</item>
     </string-array>
+
+    <!-- Packages of SystemUI -->
+    <string-array name="system_ui_packages" translatable="false">
+        <item>com.android.keyguard</item>
+        <item>com.android.systemui</item>
+    </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f513710..3015400 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -213,6 +213,8 @@
     <!-- Notification text displayed when we fail to take a screenshot. [CHAR LIMIT=100] -->
     <string name="screenshot_failed_to_capture_text">Taking screenshots isn\'t allowed by the app or
         your organization</string>
+    <!-- Notification text displayed when screenshots are blocked by an IT admin. [CHAR LIMIT=100] -->
+    <string name="screenshot_blocked_by_admin">Taking screenshots is blocked by your IT admin</string>
     <!-- Label for UI element which allows editing the screenshot [CHAR LIMIT=30] -->
     <string name="screenshot_edit_label">Edit</string>
     <!-- Content description indicating that tapping the element will allow editing the screenshot [CHAR LIMIT=NONE] -->
@@ -906,12 +908,6 @@
     <!-- Title of the notification when guest mode is entered [CHAR LIMIT=35] -->
     <string name="guest_notification_session_active">You are in guest mode</string>
 
-    <!-- Title for add user confirmation dialog [CHAR LIMIT=30] -->
-    <string name="user_add_user_title" msgid="2108112641783146007">Add new user?</string>
-
-    <!-- Message for add user confirmation dialog - short version. [CHAR LIMIT=none] -->
-    <string name="user_add_user_message_short" msgid="1511354412249044381">When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users. </string>
-
     <!-- Additional message for add user confirmation dialog that is appended when current user is
          guest and guest is ephemeral. This is to warn users that current guest session
          would get removed after a new user is added and switched to [CHAR LIMIT=none] -->
@@ -2024,7 +2020,8 @@
          app for debugging. Will not be seen by users. [CHAR LIMIT=20] -->
     <string name="heap_dump_tile_name">Dump SysUI Heap</string>
 
-    <!-- Content description for ongoing privacy chip. Use with a single app [CHAR LIMIT=NONE]-->
+    <!-- Title for the privacy indicators dialog, only appears as part of a11y descriptions [CHAR LIMIT=NONE] -->
+    <string name="ongoing_privacy_dialog_a11y_title">In use</string>
 
     <!-- Content description for ongoing privacy chip. Use with multiple apps [CHAR LIMIT=NONE]-->
     <string name="ongoing_privacy_chip_content_multiple_apps">Applications are using your <xliff:g id="types_list" example="camera, location">%s</xliff:g>.</string>
diff --git a/packages/SystemUI/res/xml/media_recommendation_collapsed.xml b/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
index a6113473..b7d4b3a 100644
--- a/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
@@ -25,8 +25,10 @@
         />
 
     <!-- Only the constraintBottom and marginBottom are different. The rest of the constraints are
-         the same as the constraints in media_smartspace_recommendations. But due to how
-         ConstraintSets work, all the constraints need to be in the same place.
+         the same as the constraints in media_recommendations_expanded.xml. But, due to how
+         ConstraintSets work, all the constraints need to be in the same place. So, the shared
+         constraints can't be put in the shared layout file media_smartspace_recommendations.xml and
+         the constraints are instead duplicated between here and media_recommendations_expanded.xml.
          Ditto for the other cover containers. -->
     <Constraint
         android:id="@+id/media_cover1_container"
diff --git a/packages/SystemUI/res/xml/media_recommendation_expanded.xml b/packages/SystemUI/res/xml/media_recommendation_expanded.xml
index 09ffebb..ce25a7d 100644
--- a/packages/SystemUI/res/xml/media_recommendation_expanded.xml
+++ b/packages/SystemUI/res/xml/media_recommendation_expanded.xml
@@ -15,7 +15,9 @@
   ~ limitations under the License
   -->
 <ConstraintSet
-    xmlns:android="http://schemas.android.com/apk/res/android" >
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    >
 
     <Constraint
         android:id="@+id/sizing_view"
@@ -23,4 +25,99 @@
         android:layout_height="@dimen/qs_media_session_height_expanded"
         />
 
+    <Constraint
+        android:id="@+id/media_cover1_container"
+        style="@style/MediaPlayer.Recommendation.AlbumContainer"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@+id/media_title1"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/media_cover2_container"
+        android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintVertical_chainStyle="packed"
+        app:layout_constraintHorizontal_bias="1.0"
+        app:layout_constraintVertical_bias="0.4"
+        />
+
+    <Constraint
+        android:id="@+id/media_title1"
+        style="@style/MediaPlayer.Recommendation.Text.Title"
+        app:layout_constraintStart_toStartOf="@+id/media_cover1_container"
+        app:layout_constraintEnd_toEndOf="@+id/media_cover1_container"
+        app:layout_constraintTop_toBottomOf="@+id/media_cover1_container"
+        app:layout_constraintBottom_toTopOf="@+id/media_subtitle1"
+        />
+
+    <Constraint
+        android:id="@+id/media_subtitle1"
+        style="@style/MediaPlayer.Recommendation.Text.Subtitle"
+        app:layout_constraintStart_toStartOf="@+id/media_cover1_container"
+        app:layout_constraintEnd_toEndOf="@+id/media_cover1_container"
+        app:layout_constraintTop_toBottomOf="@+id/media_title1"
+        app:layout_constraintBottom_toBottomOf="parent"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        />
+
+    <Constraint
+        android:id="@+id/media_cover2_container"
+        style="@style/MediaPlayer.Recommendation.AlbumContainer"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/media_title2"
+        app:layout_constraintStart_toEndOf="@id/media_cover1_container"
+        app:layout_constraintEnd_toStartOf="@id/media_cover3_container"
+        android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
+        app:layout_constraintVertical_chainStyle="packed"
+        app:layout_constraintVertical_bias="0.4"
+        />
+
+    <Constraint
+        android:id="@+id/media_title2"
+        style="@style/MediaPlayer.Recommendation.Text.Title"
+        app:layout_constraintStart_toStartOf="@+id/media_cover2_container"
+        app:layout_constraintEnd_toEndOf="@+id/media_cover2_container"
+        app:layout_constraintTop_toBottomOf="@+id/media_cover2_container"
+        app:layout_constraintBottom_toTopOf="@+id/media_subtitle2"
+        />
+
+    <Constraint
+        android:id="@+id/media_subtitle2"
+        style="@style/MediaPlayer.Recommendation.Text.Subtitle"
+        app:layout_constraintStart_toStartOf="@+id/media_cover2_container"
+        app:layout_constraintEnd_toEndOf="@+id/media_cover2_container"
+        app:layout_constraintTop_toBottomOf="@+id/media_title2"
+        app:layout_constraintBottom_toBottomOf="parent"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        />
+
+    <Constraint
+        android:id="@+id/media_cover3_container"
+        style="@style/MediaPlayer.Recommendation.AlbumContainer"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/media_title3"
+        app:layout_constraintStart_toEndOf="@id/media_cover2_container"
+        app:layout_constraintEnd_toEndOf="parent"
+        android:layout_marginEnd="@dimen/qs_media_padding"
+        app:layout_constraintVertical_chainStyle="packed"
+        app:layout_constraintVertical_bias="0.4"
+        />
+
+    <Constraint
+        android:id="@+id/media_title3"
+        style="@style/MediaPlayer.Recommendation.Text.Title"
+        app:layout_constraintStart_toStartOf="@+id/media_cover3_container"
+        app:layout_constraintEnd_toEndOf="@+id/media_cover3_container"
+        app:layout_constraintTop_toBottomOf="@+id/media_cover3_container"
+        app:layout_constraintBottom_toTopOf="@+id/media_subtitle3"
+        />
+
+    <Constraint
+        android:id="@+id/media_subtitle3"
+        style="@style/MediaPlayer.Recommendation.Text.Subtitle"
+        app:layout_constraintStart_toStartOf="@+id/media_cover3_container"
+        app:layout_constraintEnd_toEndOf="@+id/media_cover3_container"
+        app:layout_constraintTop_toBottomOf="@+id/media_title3"
+        app:layout_constraintBottom_toBottomOf="parent"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        />
+
 </ConstraintSet>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt
index fc6bb50..d7a0b47 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt
@@ -52,7 +52,7 @@
 
     private val animatedViews: MutableList<AnimatedView> = arrayListOf()
 
-    private var lastAnimationProgress: Float = 0f
+    private var lastAnimationProgress: Float = 1f
 
     /**
      * Updates display properties in order to calculate the initial position for the views
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/RecentsTransition.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/RecentsTransition.java
index e253360..b8319e5 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/RecentsTransition.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/RecentsTransition.java
@@ -45,7 +45,7 @@
             private boolean mHandled;
 
             @Override
-            public void onAnimationStarted() {
+            public void onAnimationStarted(long elapsedRealTime) {
                 // OnAnimationStartedListener can be called numerous times, so debounce here to
                 // prevent multiple callbacks
                 if (mHandled) {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
index e38d2ba..add2d02 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
@@ -67,7 +67,7 @@
                 callbackHandler,
                 new ActivityOptions.OnAnimationStartedListener() {
                     @Override
-                    public void onAnimationStarted() {
+                    public void onAnimationStarted(long elapsedRealTime) {
                         if (callback != null) {
                             callbackHandler.post(callback);
                         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index f435579..fd7a6e6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -315,6 +315,7 @@
         Log.i(TAG, "Switching mode from " + modeToString(mCurrentMode) + " to "
                 + modeToString(mode));
         mCurrentMode = mode;
+        mViewMode.onDestroy();
 
         switch (mode) {
             case MODE_ONE_HANDED:
@@ -710,7 +711,6 @@
      * Enscapsulates the differences between bouncer modes for the container.
      */
     interface ViewMode {
-
         default void init(@NonNull ViewGroup v, @NonNull GlobalSettings globalSettings,
                 @NonNull KeyguardSecurityViewFlipper viewFlipper,
                 @NonNull FalsingManager falsingManager,
@@ -738,6 +738,9 @@
         default int getChildWidthMeasureSpec(int parentWidthMeasureSpec) {
             return parentWidthMeasureSpec;
         }
+
+        /** Called when we are setting a new ViewMode */
+        default void onDestroy() {};
     }
 
     /**
@@ -781,6 +784,8 @@
         private UserSwitcherController mUserSwitcherController;
         private KeyguardUserSwitcherPopupMenu mPopup;
         private Resources mResources;
+        private UserSwitcherController.UserSwitchCallback mUserSwitchCallback =
+                this::setupUserSwitcher;
 
         @Override
         public void init(@NonNull ViewGroup v, @NonNull GlobalSettings globalSettings,
@@ -805,6 +810,7 @@
 
             mUserSwitcher = mView.findViewById(R.id.user_switcher_header);
             setupUserSwitcher();
+            mUserSwitcherController.addUserSwitchCallback(mUserSwitchCallback);
         }
 
         @Override
@@ -813,7 +819,11 @@
                 mPopup.dismiss();
                 mPopup = null;
             }
-            setupUserSwitcher();
+        }
+
+        @Override
+        public void onDestroy() {
+            mUserSwitcherController.removeUserSwitchCallback(mUserSwitchCallback);
         }
 
         private Drawable findUserIcon(int userId) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a6feedb5..3f8c4b3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1512,6 +1512,20 @@
                 handleFingerprintAuthenticated(userId, isStrongBiometric);
             };
 
+    /**
+     * Propagates a pointer down event to keyguard.
+     */
+    public void onUdfpsPointerDown(int sensorId) {
+        mFingerprintAuthenticationCallback.onUdfpsPointerDown(sensorId);
+    }
+
+    /**
+     * Propagates a pointer up event to keyguard.
+     */
+    public void onUdfpsPointerUp(int sensorId) {
+        mFingerprintAuthenticationCallback.onUdfpsPointerUp(sensorId);
+    }
+
     @VisibleForTesting
     final FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
             = new AuthenticationCallback() {
@@ -1553,6 +1567,9 @@
                     Trace.endSection();
                 }
 
+                /**
+                 * Note, this is currently called from UdfpsController.
+                 */
                 @Override
                 public void onUdfpsPointerDown(int sensorId) {
                     Log.d(TAG, "onUdfpsPointerDown, sensorId: " + sensorId);
@@ -1562,6 +1579,9 @@
                     }
                 }
 
+                /**
+                 * Note, this is currently called from UdfpsController.
+                 */
                 @Override
                 public void onUdfpsPointerUp(int sensorId) {
                     Log.d(TAG, "onUdfpsPointerUp, sensorId: " + sensorId);
diff --git a/packages/SystemUI/src/com/android/systemui/FontSizeUtils.java b/packages/SystemUI/src/com/android/systemui/FontSizeUtils.java
index 35a70a5..0d1dc9d 100644
--- a/packages/SystemUI/src/com/android/systemui/FontSizeUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/FontSizeUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui;
 
+import android.annotation.StyleRes;
+import android.content.res.TypedArray;
 import android.util.TypedValue;
 import android.view.View;
 import android.widget.TextView;
@@ -23,9 +25,9 @@
 /**
  * Utility class to update the font size when the configuration has changed.
  */
-public class FontSizeUtils {
+public final class FontSizeUtils {
 
-    public static final float LARGE_TEXT_SCALE = 1.3f;
+    private FontSizeUtils() {}
 
     public static void updateFontSize(View parent, int viewId, int dimensId) {
         updateFontSize((TextView) parent.findViewById(viewId), dimensId);
@@ -37,4 +39,20 @@
                     v.getResources().getDimensionPixelSize(dimensId));
         }
     }
+
+    /**
+     * Updates the font size according to the style given.
+     *
+     * @param v     Text to update.
+     * @param resId Style applying to the text.
+     */
+    public static void updateFontSizeFromStyle(TextView v, @StyleRes int resId) {
+        int[] attrs = {android.R.attr.textSize};
+        int indexOfAttrTextSize = 0;
+        TypedArray ta = v.getContext().obtainStyledAttributes(resId, attrs);
+        int updatedTextPixelSize = ta.getDimensionPixelSize(indexOfAttrTextSize,
+                (int) v.getTextSize());
+        v.setTextSize(TypedValue.COMPLEX_UNIT_PX, updatedTextPixelSize);
+        ta.recycle();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
index 3641e1d..0df2730 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
@@ -380,7 +380,7 @@
     ) {
         if (hasTopRoundedCorner == hasTop &&
                 hasBottomRoundedCorner == hasBottom &&
-                roundedCornerBottomSize == bottomSize &&
+                roundedCornerTopSize == topSize &&
                 roundedCornerBottomSize == bottomSize) {
             return
         }
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index b98fc03..8d65098 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -348,7 +348,8 @@
             @Override
             public void onDisplayChanged(int displayId) {
                 final int newRotation = mContext.getDisplay().getRotation();
-                if (mOverlays != null && mRotation != newRotation) {
+                if ((mOverlays != null || mScreenDecorHwcWindow != null)
+                        && mRotation != newRotation) {
                     // We cannot immediately update the orientation. Otherwise
                     // WindowManager is still deferring layout until it has finished dispatching
                     // the config changes, which may cause divergence between what we draw
@@ -362,11 +363,13 @@
                                 + mRotation);
                     }
 
-                    for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
-                        if (mOverlays[i] != null) {
-                            final ViewGroup overlayView = mOverlays[i].getRootView();
-                            overlayView.getViewTreeObserver().addOnPreDrawListener(
-                                    new RestartingPreDrawListener(overlayView, i, newRotation));
+                    if (mOverlays != null) {
+                        for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
+                            if (mOverlays[i] != null) {
+                                final ViewGroup overlayView = mOverlays[i].getRootView();
+                                overlayView.getViewTreeObserver().addOnPreDrawListener(
+                                        new RestartingPreDrawListener(overlayView, i, newRotation));
+                            }
                         }
                     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 9d5b93c..7c2673c 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -187,6 +187,14 @@
                     }
 
                     @Override
+                    public void onVoiceSessionWindowVisibilityChanged(boolean visible)
+                            throws RemoteException {
+                        if (VERBOSE) {
+                            Log.v(TAG, "Window visibility changed: " + visible);
+                        }
+                    }
+
+                    @Override
                     public void onSetUiHints(Bundle hints) {
                         if (VERBOSE) {
                             Log.v(TAG, "UI hints received");
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 8e11326..d4dad73 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -149,7 +149,7 @@
     final TaskStackListener mTaskStackListener = new TaskStackListener() {
         @Override
         public void onTaskStackChanged() {
-            mHandler.post(AuthController.this::handleTaskStackChanged);
+            mHandler.post(AuthController.this::cancelIfOwnerIsNotInForeground);
         }
     };
 
@@ -200,7 +200,7 @@
         }
     };
 
-    private void handleTaskStackChanged() {
+    private void cancelIfOwnerIsNotInForeground() {
         mExecution.assertIsMainThread();
         if (mCurrentDialog != null) {
             try {
@@ -212,7 +212,7 @@
                     final String topPackage = runningTasks.get(0).topActivity.getPackageName();
                     if (!topPackage.contentEquals(clientPackage)
                             && !Utils.isSystem(mContext, clientPackage)) {
-                        Log.w(TAG, "Evicting client due to: " + topPackage);
+                        Log.e(TAG, "Evicting client due to: " + topPackage);
                         mCurrentDialog.dismissWithoutCallback(true /* animate */);
                         mCurrentDialog = null;
                         mOrientationListener.disable();
@@ -919,6 +919,10 @@
         mCurrentDialog = newDialog;
         mCurrentDialog.show(mWindowManager, savedState);
         mOrientationListener.enable();
+
+        if (!promptInfo.isAllowBackgroundAuthentication()) {
+            mHandler.post(this::cancelIfOwnerIsNotInForeground);
+        }
     }
 
     private void onDialogDismissed(@DismissedReason int reason) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
index ac81633..5cfbdb0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
@@ -54,14 +54,13 @@
     private var dialogAlphaAnimator: ValueAnimator? = null
     private val dialogListener = SystemUIDialogManager.Listener { runDialogAlphaAnimator() }
 
-    private val panelExpansionListener =
-        PanelExpansionListener { fraction, expanded, tracking ->
-            // Notification shade can be expanded but not visible (fraction: 0.0), for example
-            // when a heads-up notification (HUN) is showing.
-            notificationShadeVisible = expanded && fraction > 0f
-            view.onExpansionChanged(fraction)
-            updatePauseAuth()
-        }
+    private val panelExpansionListener = PanelExpansionListener { event ->
+        // Notification shade can be expanded but not visible (fraction: 0.0), for example
+        // when a heads-up notification (HUN) is showing.
+        notificationShadeVisible = event.expanded && event.fraction > 0f
+        view.onExpansionChanged(event.fraction)
+        updatePauseAuth()
+    }
 
     /** If the notification shade is visible. */
     var notificationShadeVisible: Boolean = false
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 0096032..09d9792 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -796,6 +796,11 @@
         mOnFingerDown = true;
         if (mAlternateTouchProvider != null) {
             mAlternateTouchProvider.onPointerDown(requestId, x, y, minor, major);
+            mFgExecutor.execute(() -> {
+                if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
+                    mKeyguardUpdateMonitor.onUdfpsPointerDown((int) requestId);
+                }
+            });
         } else {
             mFingerprintManager.onPointerDown(requestId, mSensorId, x, y, minor, major);
         }
@@ -821,6 +826,11 @@
         if (mOnFingerDown) {
             if (mAlternateTouchProvider != null) {
                 mAlternateTouchProvider.onPointerUp(requestId);
+                mFgExecutor.execute(() -> {
+                    if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
+                        mKeyguardUpdateMonitor.onUdfpsPointerUp((int) requestId);
+                    }
+                });
             } else {
                 mFingerprintManager.onPointerUp(requestId, mSensorId);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
index dbfce2e..2f09792 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
@@ -112,17 +112,16 @@
             if (child.getId() == R.id.biometric_icon_frame) {
                 final FrameLayout iconFrame = (FrameLayout) child;
                 final View icon = iconFrame.getChildAt(0);
-
-                // Ensure that the icon is never larger than the sensor.
-                icon.measure(
-                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST),
-                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST));
-
                 // Create a frame that's exactly the height of the sensor circle.
                 iconFrame.measure(
                         MeasureSpec.makeMeasureSpec(
                                 child.getLayoutParams().width, MeasureSpec.EXACTLY),
                         MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
+
+                // Ensure that the icon is never larger than the sensor.
+                icon.measure(
+                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST),
+                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST));
             } else if (child.getId() == R.id.space_above_icon) {
                 child.measure(
                         MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
@@ -208,16 +207,15 @@
             if (child.getId() == R.id.biometric_icon_frame) {
                 final FrameLayout iconFrame = (FrameLayout) child;
                 final View icon = iconFrame.getChildAt(0);
+                // Create a frame that's exactly the height of the sensor circle.
+                iconFrame.measure(
+                        MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
+                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
 
                 // Ensure that the icon is never larger than the sensor.
                 icon.measure(
                         MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST),
                         MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST));
-
-                // Create a frame that's exactly the height of the sensor circle.
-                iconFrame.measure(
-                        MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
-                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
             } else if (child.getId() == R.id.space_above_icon) {
                 // Adjust the width and height of the top spacer if necessary.
                 final int newTopSpacerHeight = child.getLayoutParams().height
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
index 59c658f..49e378e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
@@ -22,6 +22,10 @@
 import android.graphics.ColorFilter;
 import android.graphics.Paint;
 import android.graphics.drawable.Drawable;
+import android.os.Process;
+import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
@@ -46,6 +50,17 @@
     private static final float STROKE_WIDTH_DP = 12f;
     private static final Interpolator DEACCEL = new DecelerateInterpolator();
 
+    private static final VibrationEffect VIBRATE_EFFECT_ERROR =
+            VibrationEffect.createWaveform(new long[] {0, 5, 55, 60}, -1);
+    private static final VibrationAttributes FINGERPRINT_ENROLLING_SONFICATION_ATTRIBUTES =
+            VibrationAttributes.createForUsage(VibrationAttributes.USAGE_ACCESSIBILITY);
+
+    private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
+            VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
+
+    private static final VibrationEffect SUCCESS_VIBRATION_EFFECT =
+            VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+
     private final float mStrokeWidthPx;
     @ColorInt private final int mProgressColor;
     @ColorInt private final int mHelpColor;
@@ -54,6 +69,9 @@
     @NonNull private final Interpolator mCheckmarkInterpolator;
     @NonNull private final Paint mBackgroundPaint;
     @NonNull private final Paint mFillPaint;
+    @NonNull private final Vibrator mVibrator;
+    @NonNull private final boolean mIsAccessibilityEnabled;
+    @NonNull private final Context mContext;
 
     private boolean mAfterFirstTouch;
 
@@ -76,11 +94,12 @@
     @NonNull private final ValueAnimator.AnimatorUpdateListener mCheckmarkUpdateListener;
 
     public UdfpsEnrollProgressBarDrawable(@NonNull Context context) {
+        mContext = context;
         mStrokeWidthPx = Utils.dpToPixels(context, STROKE_WIDTH_DP);
         mProgressColor = context.getColor(R.color.udfps_enroll_progress);
         final AccessibilityManager am = context.getSystemService(AccessibilityManager.class);
-        final boolean isAccessbilityEnabled = am.isTouchExplorationEnabled();
-        if (!isAccessbilityEnabled) {
+        mIsAccessibilityEnabled = am.isTouchExplorationEnabled();
+        if (!mIsAccessibilityEnabled) {
             mHelpColor = context.getColor(R.color.udfps_enroll_progress_help);
             mOnFirstBucketFailedColor = context.getColor(R.color.udfps_moving_target_fill_error);
         } else {
@@ -106,6 +125,8 @@
         mFillPaint.setStyle(Paint.Style.STROKE);
         mFillPaint.setStrokeCap(Paint.Cap.ROUND);
 
+        mVibrator = mContext.getSystemService(Vibrator.class);
+
         mProgressUpdateListener = animation -> {
             mProgress = (float) animation.getAnimatedValue();
             invalidateSelf();
@@ -141,14 +162,41 @@
     }
 
     private void updateState(int remainingSteps, int totalSteps, boolean showingHelp) {
-        updateProgress(remainingSteps, totalSteps);
+        updateProgress(remainingSteps, totalSteps, showingHelp);
         updateFillColor(showingHelp);
     }
 
-    private void updateProgress(int remainingSteps, int totalSteps) {
+    private void updateProgress(int remainingSteps, int totalSteps, boolean showingHelp) {
         if (mRemainingSteps == remainingSteps && mTotalSteps == totalSteps) {
             return;
         }
+
+        if (mShowingHelp) {
+            if (mVibrator != null && mIsAccessibilityEnabled) {
+                mVibrator.vibrate(Process.myUid(), mContext.getOpPackageName(),
+                        VIBRATE_EFFECT_ERROR, getClass().getSimpleName() + "::onEnrollmentHelp",
+                        FINGERPRINT_ENROLLING_SONFICATION_ATTRIBUTES);
+            }
+        } else {
+            // If the first touch is an error, remainingSteps will be -1 and the callback
+            // doesn't come from onEnrollmentHelp. If we are in the accessibility flow,
+            // we still would like to vibrate.
+            if (mVibrator != null) {
+                if (remainingSteps == -1 && mIsAccessibilityEnabled) {
+                    mVibrator.vibrate(Process.myUid(), mContext.getOpPackageName(),
+                            VIBRATE_EFFECT_ERROR,
+                            getClass().getSimpleName() + "::onFirstTouchError",
+                            FINGERPRINT_ENROLLING_SONFICATION_ATTRIBUTES);
+                } else if (remainingSteps != -1 && !mIsAccessibilityEnabled) {
+                    mVibrator.vibrate(Process.myUid(),
+                            mContext.getOpPackageName(),
+                            SUCCESS_VIBRATION_EFFECT,
+                            getClass().getSimpleName() + "::OnEnrollmentProgress",
+                            HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
+                }
+            }
+        }
+
         mRemainingSteps = remainingSteps;
         mTotalSteps = totalSteps;
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
index 67d0db2..937b813 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
@@ -127,19 +127,20 @@
         mBurnInProgress = MathUtils.lerp(0f, getBurnInProgressOffset(), darkAmountForAnimation);
 
         if (mAnimatingBetweenAodAndLockscreen && !mPauseAuth) {
-            mBgProtection.setAlpha(1f - mInterpolatedDarkAmount);
-
             mLockScreenFp.setTranslationX(mBurnInOffsetX);
             mLockScreenFp.setTranslationY(mBurnInOffsetY);
-            mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
+            mBgProtection.setAlpha(1f - mInterpolatedDarkAmount);
             mLockScreenFp.setAlpha(1f - mInterpolatedDarkAmount);
         } else if (mInterpolatedDarkAmount == 0f) {
+            mLockScreenFp.setTranslationX(0);
+            mLockScreenFp.setTranslationY(0);
             mBgProtection.setAlpha(mAlpha / 255f);
             mLockScreenFp.setAlpha(mAlpha / 255f);
         } else {
             mBgProtection.setAlpha(0f);
             mLockScreenFp.setAlpha(0f);
         }
+        mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
 
         mAodFp.setTranslationX(mBurnInOffsetX);
         mAodFp.setTranslationY(mBurnInOffsetY);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index e8cfd42..416b8ee 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -38,6 +38,7 @@
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.SystemUIDialogManager;
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -491,8 +492,8 @@
 
     private final PanelExpansionListener mPanelExpansionListener = new PanelExpansionListener() {
         @Override
-        public void onPanelExpansionChanged(
-                float fraction, boolean expanded, boolean tracking) {
+        public void onPanelExpansionChanged(PanelExpansionChangeEvent event) {
+            float fraction = event.getFraction();
             mPanelExpansionFraction =
                     mKeyguardViewManager.isBouncerInTransit() ? BouncerPanelExpansionCalculator
                             .aboutToShowBouncerProgress(fraction) : fraction;
diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
index 9dbeb77..e316722 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
@@ -105,7 +105,7 @@
         DisplayCutout.BOUNDS_POSITION_LEFT -> Gravity.BOTTOM
         DisplayCutout.BOUNDS_POSITION_TOP -> Gravity.LEFT
         DisplayCutout.BOUNDS_POSITION_RIGHT -> Gravity.TOP
-        else /* DisplayCutout.BOUNDS_POSITION_BOTTOM */ -> Gravity.LEFT
+        else /* DisplayCutout.BOUNDS_POSITION_BOTTOM */ -> Gravity.RIGHT
     }
     Surface.ROTATION_270 -> when (this) {
         DisplayCutout.BOUNDS_POSITION_LEFT -> Gravity.TOP
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
index a83e006..7666eb8 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
@@ -26,7 +26,7 @@
 import com.android.systemui.dreams.complication.Complication;
 import com.android.systemui.dreams.complication.ComplicationLayoutParams;
 import com.android.systemui.dreams.complication.ComplicationViewModel;
-import com.android.systemui.dreams.smartspace.DreamsSmartspaceController;
+import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
 
 import java.util.List;
@@ -43,7 +43,7 @@
      * SystemUI.
      */
     public static class Registrant extends CoreStartable {
-        private final DreamsSmartspaceController mSmartSpaceController;
+        private final DreamSmartspaceController mSmartSpaceController;
         private final DreamOverlayStateController mDreamOverlayStateController;
         private final SmartSpaceComplication mComplication;
 
@@ -66,7 +66,7 @@
         public Registrant(Context context,
                 DreamOverlayStateController dreamOverlayStateController,
                 SmartSpaceComplication smartSpaceComplication,
-                DreamsSmartspaceController smartSpaceController) {
+                DreamSmartspaceController smartSpaceController) {
             super(context);
             mDreamOverlayStateController = dreamOverlayStateController;
             mComplication = smartSpaceComplication;
@@ -90,12 +90,12 @@
 
     private static class SmartSpaceComplicationViewHolder implements ViewHolder {
         private static final int SMARTSPACE_COMPLICATION_WEIGHT = 10;
-        private final DreamsSmartspaceController mSmartSpaceController;
+        private final DreamSmartspaceController mSmartSpaceController;
         private final Context mContext;
 
         protected SmartSpaceComplicationViewHolder(
                 Context context,
-                DreamsSmartspaceController smartSpaceController) {
+                DreamSmartspaceController smartSpaceController) {
             mSmartSpaceController = smartSpaceController;
             mContext = context;
         }
@@ -120,12 +120,12 @@
         }
     }
 
-    private final DreamsSmartspaceController mSmartSpaceController;
+    private final DreamSmartspaceController mSmartSpaceController;
     private final Context mContext;
 
     @Inject
     public SmartSpaceComplication(Context context,
-            DreamsSmartspaceController smartSpaceController) {
+            DreamSmartspaceController smartSpaceController) {
         mContext = context;
         mSmartSpaceController = smartSpaceController;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt
rename to packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt
index 9b99c52..da2cf84 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt
@@ -46,7 +46,7 @@
  * Controller for managing the smartspace view on the dream
  */
 @SysUISingleton
-class DreamsSmartspaceController @Inject constructor(
+class DreamSmartspaceController @Inject constructor(
     private val context: Context,
     private val smartspaceManager: SmartspaceManager,
     private val execution: Execution,
@@ -58,7 +58,7 @@
     @Named(DREAM_SMARTSPACE_DATA_PLUGIN) optionalPlugin: Optional<BcSmartspaceDataPlugin>
 ) {
     companion object {
-        private const val TAG = "DreamsSmartspaceCtrlr"
+        private const val TAG = "DreamSmartspaceCtrlr"
     }
 
     private var session: SmartspaceSession? = null
@@ -98,6 +98,7 @@
             view.setPrimaryTextColor(Color.WHITE)
             smartspaceViews.add(view)
             connectSession()
+            view.setDozeAmount(0f)
         }
 
         override fun onViewDetachedFromWindow(v: View) {
@@ -127,6 +128,7 @@
         }
 
         val view = buildView(parent)
+
         connectSession()
 
         return view
@@ -136,12 +138,13 @@
         return if (plugin != null) {
             var view = smartspaceViewComponentFactory.create(parent, plugin, stateChangeListener)
                     .getView()
-
-            if (view is View) {
-                return view
+            if (view !is View) {
+                return null
             }
 
-            return null
+            view.setIsDreaming(true)
+
+            return view
         } else {
             null
         }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
index 56eb9d2..f769a23 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
@@ -40,9 +40,11 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
 import java.util.Optional;
+
 import javax.inject.Inject;
 import javax.inject.Named;
 
@@ -141,21 +143,27 @@
                     // bouncer. As that view's expansion shrinks, the bouncer appears. The bouncer
                     // is fully hidden at full expansion (1) and fully visible when fully collapsed
                     // (0).
+                    final float dragDownAmount = e2.getY() - e1.getY();
                     final float screenTravelPercentage = Math.abs(e1.getY() - e2.getY())
                             / mCentralSurfaces.get().getDisplayHeight();
                     setPanelExpansion(mBouncerInitiallyShowing
-                            ? screenTravelPercentage : 1 - screenTravelPercentage);
+                            ? screenTravelPercentage : 1 - screenTravelPercentage, dragDownAmount);
                     return true;
                 }
             };
 
-    private void setPanelExpansion(float expansion) {
+    private void setPanelExpansion(float expansion, float dragDownAmount) {
         mCurrentExpansion = expansion;
-        mCentralSurfaces.ifPresent(centralSurfaces -> centralSurfaces.setBouncerShowingOverDream(
-                mCurrentExpansion != KeyguardBouncer.EXPANSION_HIDDEN));
-        mStatusBarKeyguardViewManager.onPanelExpansionChanged(mCurrentExpansion, false, true);
+        PanelExpansionChangeEvent event =
+                new PanelExpansionChangeEvent(
+                        /* fraction= */ mCurrentExpansion,
+                        /* expanded= */ false,
+                        /* tracking= */ true,
+                        /* dragDownPxAmount= */ dragDownAmount);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(event);
     }
 
+
     @VisibleForTesting
     public enum DreamEvent implements UiEventLogger.UiEventEnum {
         @UiEvent(doc = "The screensaver has been swiped up.")
@@ -285,12 +293,14 @@
         }
     }
 
-    private ValueAnimator createExpansionAnimator(float targetExpansion) {
+    private ValueAnimator createExpansionAnimator(float targetExpansion, float expansionHeight) {
         final ValueAnimator animator =
                 mValueAnimatorCreator.create(mCurrentExpansion, targetExpansion);
         animator.addUpdateListener(
                 animation -> {
-                    setPanelExpansion((float) animation.getAnimatedValue());
+                    float expansionFraction = (float) animation.getAnimatedValue();
+                    float dragDownAmount = expansionFraction * expansionHeight;
+                    setPanelExpansion(expansionFraction, dragDownAmount);
                 });
         if (!mBouncerInitiallyShowing && targetExpansion == KeyguardBouncer.EXPANSION_VISIBLE) {
             animator.addListener(
@@ -323,8 +333,8 @@
         final float viewHeight = mCentralSurfaces.get().getDisplayHeight();
         final float currentHeight = viewHeight * mCurrentExpansion;
         final float targetHeight = viewHeight * expansion;
-
-        final ValueAnimator animator = createExpansionAnimator(expansion);
+        final float expansionHeight = targetHeight - currentHeight;
+        final ValueAnimator animator = createExpansionAnimator(expansion, expansionHeight);
         if (expansion == KeyguardBouncer.EXPANSION_HIDDEN) {
             // Hides the bouncer, i.e., fully expands the space above the bouncer.
             mFlingAnimationUtilsClosing.apply(animator, currentHeight, targetHeight, velocity,
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
index 3ae11ff..9c7411b 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
@@ -54,7 +54,7 @@
     private final View mRootView;
     private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
             ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE
-                    | ActivityInfo.CONFIG_LAYOUT_DIRECTION | ActivityInfo.CONFIG_ASSETS_PATHS);
+                    | ActivityInfo.CONFIG_ASSETS_PATHS);
     private final FragmentService mManager;
     private final ExtensionFragmentManager mPlugins = new ExtensionFragmentManager();
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index d6843bf..29e940f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -849,7 +849,8 @@
 
                 @Override
                 public void onLaunchAnimationCancelled() {
-                    setOccluded(true /* occluded */, false /* animate */);
+                    Log.d(TAG, "Occlude launch animation cancelled. "
+                            + "Occluded state is now: " + mOccluded);
                 }
 
                 @NonNull
@@ -894,7 +895,7 @@
             };
 
     private IRemoteAnimationRunner mOccludeAnimationRunner =
-            new ActivityLaunchRemoteAnimationRunner(mOccludeAnimationController);
+            new OccludeActivityLaunchRemoteAnimationRunner(mOccludeAnimationController);
 
     /**
      * Animation controller for activities that unocclude the keyguard. This does not use the
@@ -919,13 +920,17 @@
                         RemoteAnimationTarget[] wallpapers,
                         RemoteAnimationTarget[] nonApps,
                         IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
-                    final RemoteAnimationTarget primary = apps[0];
+                    if (apps == null || apps.length == 0 || apps[0] == null) {
+                        Log.d(TAG, "No apps provided to unocclude runner; "
+                                + "skipping animation and unoccluding.");
 
-                    if (primary == null) {
                         finishedCallback.onAnimationFinished();
+                        setOccluded(false /* isOccluded */, true /* animate */);
                         return;
                     }
 
+                    final RemoteAnimationTarget primary = apps[0];
+
                     final SyncRtSurfaceTransactionApplier applier =
                             new SyncRtSurfaceTransactionApplier(
                                     mKeyguardViewControllerLazy.get().getViewRootImpl().getView());
@@ -965,6 +970,7 @@
                             @Override
                             public void onAnimationEnd(Animator animation) {
                                 try {
+                                    setOccluded(false /* isOccluded */, true /* animate */);
                                     finishedCallback.onAnimationFinished();
                                     mUnoccludeAnimator = null;
                                 } catch (RemoteException e) {
@@ -2604,6 +2610,9 @@
 
             finishSurfaceBehindRemoteAnimation(cancelled);
             mSurfaceBehindRemoteAnimationRequested = false;
+
+            // The remote animation is over, so we're not going away anymore.
+            mKeyguardStateController.notifyKeyguardGoingAway(false);
         });
 
         mKeyguardUnlockAnimationControllerLazy.get().notifyFinishedKeyguardExitAnimation(
@@ -2622,6 +2631,7 @@
             ActivityTaskManager.getService().keyguardGoingAway(
                     WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS
                             | WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER);
+            mKeyguardStateController.notifyKeyguardGoingAway(true);
         } catch (RemoteException e) {
             mSurfaceBehindRemoteAnimationRequested = false;
             e.printStackTrace();
@@ -3121,4 +3131,36 @@
             mRunner.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback);
         }
     }
+
+    /**
+     * Subclass of {@link ActivityLaunchRemoteAnimationRunner} that calls {@link #setOccluded} when
+     * onAnimationStart is called.
+     */
+    private class OccludeActivityLaunchRemoteAnimationRunner
+            extends ActivityLaunchRemoteAnimationRunner {
+
+        OccludeActivityLaunchRemoteAnimationRunner(
+                ActivityLaunchAnimator.Controller controller) {
+            super(controller);
+        }
+
+        @Override
+        public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
+                RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
+                IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
+            super.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback);
+
+            // This is the first signal we have from WM that we're going to be occluded. Set our
+            // internal state to reflect that immediately, vs. waiting for the launch animator to
+            // begin. Otherwise, calls to setShowingLocked, etc. will not know that we're about to
+            // be occluded and might re-show the keyguard.
+            setOccluded(true /* isOccluded */, false /* animate */);
+        }
+
+        @Override
+        public void onAnimationCancelled() throws RemoteException {
+            super.onAnimationCancelled();
+            Log.d(TAG, "Occlude launch animation cancelled. Occluded state is now: " + mOccluded);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 39f00f4..2467169 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -208,6 +208,16 @@
         return factory.create("MediaView", 100);
     }
 
+    /**
+     * Provides a buffer for media playback state changes
+     */
+    @Provides
+    @SysUISingleton
+    @MediaTimeoutListenerLog
+    public static LogBuffer providesMediaTimeoutListenerLogBuffer(LogBufferFactory factory) {
+        return factory.create("MediaTimeout", 100);
+    }
+
     /** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */
     @Provides
     @SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/MediaTimeoutListenerLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaTimeoutListenerLog.java
new file mode 100644
index 0000000..53963fc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaTimeoutListenerLog.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/**
+ * A {@link LogBuffer} for {@link com.android.systemui.media.MediaTimeoutLogger}
+ */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface MediaTimeoutListenerLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index af54e96..d9ee8f3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -30,10 +30,12 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
+import android.graphics.Color;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Rect;
 import android.graphics.drawable.Animatable;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.graphics.drawable.TransitionDrawable;
@@ -159,6 +161,7 @@
     private MetadataAnimationHandler mMetadataAnimationHandler;
     private ColorSchemeTransition mColorSchemeTransition;
     private Drawable mPrevArtwork = null;
+    private boolean mIsArtworkBound = false;
     private int mArtworkBoundId = 0;
     private int mArtworkNextBindRequestId = 0;
 
@@ -586,6 +589,9 @@
 
     private void bindArtworkAndColors(MediaData data, boolean updateBackground) {
         final int reqId = mArtworkNextBindRequestId++;
+        if (updateBackground) {
+            mIsArtworkBound = false;
+        }
 
         // Capture width & height from views in foreground for artwork scaling in background
         int width = mMediaViewHolder.getPlayer().getWidth();
@@ -597,15 +603,18 @@
             // Album art
             ColorScheme mutableColorScheme = null;
             Drawable artwork;
+            boolean isArtworkBound;
             Icon artworkIcon = data.getArtwork();
             if (artworkIcon != null) {
                 WallpaperColors wallpaperColors = WallpaperColors
                         .fromBitmap(artworkIcon.getBitmap());
                 mutableColorScheme = new ColorScheme(wallpaperColors, true);
                 artwork = getScaledBackground(artworkIcon, width, height);
+                isArtworkBound = true;
             } else {
                 // If there's no artwork, use colors from the app icon
-                artwork = null;
+                artwork = new ColorDrawable(Color.TRANSPARENT);
+                isArtworkBound = false;
                 try {
                     Drawable icon = mContext.getPackageManager()
                             .getApplicationIcon(data.getPackageName());
@@ -625,16 +634,20 @@
                 ImageView albumView = mMediaViewHolder.getAlbumView();
                 albumView.setPadding(0, 0, 0, 0);
                 albumView.setClipToOutline(true);
-                if (updateBackground) {
-                    if (mPrevArtwork == null || artwork == null) {
+                if (updateBackground || (!mIsArtworkBound && isArtworkBound)) {
+                    if (mPrevArtwork == null) {
                         albumView.setImageDrawable(artwork);
                     } else {
+                        // Since we throw away the last transition, this'll pop if you backgrounds
+                        // are cycled too fast (or the correct background arrives very soon after
+                        // the metadata changes).
                         TransitionDrawable transitionDrawable = new TransitionDrawable(
-                                new Drawable[] { mPrevArtwork, artwork });
+                                new Drawable[]{mPrevArtwork, artwork});
                         albumView.setImageDrawable(transitionDrawable);
-                        transitionDrawable.startTransition(333);
+                        transitionDrawable.startTransition(isArtworkBound ? 333 : 80);
                     }
                     mPrevArtwork = artwork;
+                    mIsArtworkBound = isArtworkBound;
                 }
 
                 // Transition Colors to current color scheme
@@ -991,6 +1004,9 @@
         List<ViewGroup> mediaCoverContainers = mRecommendationViewHolder.getMediaCoverContainers();
         int mediaRecommendationNum = Math.min(mediaRecommendationList.size(),
                 MEDIA_RECOMMENDATION_MAX_NUM);
+
+        boolean hasTitle = false;
+        boolean hasSubtitle = false;
         int uiComponentIndex = 0;
         for (int itemIndex = 0;
                 itemIndex < mediaRecommendationNum && uiComponentIndex < mediaRecommendationNum;
@@ -1036,26 +1052,33 @@
 
             // Set up title
             CharSequence title = recommendation.getTitle();
+            hasTitle |= !TextUtils.isEmpty(title);
             TextView titleView =
                     mRecommendationViewHolder.getMediaTitles().get(uiComponentIndex);
             titleView.setText(title);
-            // TODO(b/223603970): If none of them have titles, should we then hide the views?
 
             // Set up subtitle
-            CharSequence subtitle = recommendation.getSubtitle();
-            TextView subtitleView =
-                    mRecommendationViewHolder.getMediaSubtitles().get(uiComponentIndex);
             // It would look awkward to show a subtitle if we don't have a title.
             boolean shouldShowSubtitleText = !TextUtils.isEmpty(title);
-            CharSequence subtitleText = shouldShowSubtitleText ? subtitle : "";
-            subtitleView.setText(subtitleText);
-            // TODO(b/223603970): If none of them have subtitles, should we then hide the views?
+            CharSequence subtitle = shouldShowSubtitleText ? recommendation.getSubtitle() : "";
+            hasSubtitle |= !TextUtils.isEmpty(subtitle);
+            TextView subtitleView =
+                    mRecommendationViewHolder.getMediaSubtitles().get(uiComponentIndex);
+            subtitleView.setText(subtitle);
 
             uiComponentIndex++;
         }
-
         mSmartspaceMediaItemsCount = uiComponentIndex;
 
+        // If there's no subtitles and/or titles for any of the albums, hide those views.
+        ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
+        final boolean titlesVisible = hasTitle;
+        final boolean subtitlesVisible = hasSubtitle;
+        mRecommendationViewHolder.getMediaTitles().forEach((titleView) ->
+                setVisibleAndAlpha(expandedSet, titleView.getId(), titlesVisible));
+        mRecommendationViewHolder.getMediaSubtitles().forEach((subtitleView) ->
+                setVisibleAndAlpha(expandedSet, subtitleView.getId(), subtitlesVisible));
+
         // Guts
         Runnable onDismissClickedRunnable = () -> {
             closeGuts();
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
index 51755065..8c6710a6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
@@ -19,7 +19,6 @@
 import android.media.session.MediaController
 import android.media.session.PlaybackState
 import android.os.SystemProperties
-import android.util.Log
 import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
@@ -28,9 +27,6 @@
 import java.util.concurrent.TimeUnit
 import javax.inject.Inject
 
-private const val DEBUG = true
-private const val TAG = "MediaTimeout"
-
 @VisibleForTesting
 val PAUSED_MEDIA_TIMEOUT = SystemProperties
         .getLong("debug.sysui.media_timeout", TimeUnit.MINUTES.toMillis(10))
@@ -45,7 +41,8 @@
 @SysUISingleton
 class MediaTimeoutListener @Inject constructor(
     private val mediaControllerFactory: MediaControllerFactory,
-    @Main private val mainExecutor: DelayableExecutor
+    @Main private val mainExecutor: DelayableExecutor,
+    private val logger: MediaTimeoutLogger
 ) : MediaDataManager.Listener {
 
     private val mediaListeners: MutableMap<String, PlaybackStateListener> = mutableMapOf()
@@ -75,9 +72,7 @@
             }
 
             // If listener was destroyed previously, we'll need to re-register it
-            if (DEBUG) {
-                Log.d(TAG, "Reusing destroyed listener $key")
-            }
+            logger.logReuseListener(key)
             reusedListener = it
         }
 
@@ -86,16 +81,12 @@
         val migrating = oldKey != null && key != oldKey
         if (migrating) {
             reusedListener = mediaListeners.remove(oldKey)
-            if (reusedListener != null) {
-                if (DEBUG) Log.d(TAG, "migrating key $oldKey to $key, for resumption")
-            } else {
-                Log.w(TAG, "Old key $oldKey for player $key doesn't exist. Continuing...")
-            }
+            logger.logMigrateListener(oldKey, key, reusedListener != null)
         }
 
         reusedListener?.let {
             val wasPlaying = it.playing ?: false
-            if (DEBUG) Log.d(TAG, "updating listener for $key, was playing? $wasPlaying")
+            logger.logUpdateListener(key, wasPlaying)
             it.mediaData = data
             it.key = key
             mediaListeners[key] = it
@@ -105,7 +96,7 @@
                 // until we're done.
                 mainExecutor.execute {
                     if (mediaListeners[key]?.playing == true) {
-                        if (DEBUG) Log.d(TAG, "deliver delayed playback state for $key")
+                        logger.logDelayedUpdate(key)
                         timeoutCallback.invoke(key, false /* timedOut */)
                     }
                 }
@@ -169,10 +160,7 @@
         }
 
         override fun onSessionDestroyed() {
-            if (DEBUG) {
-                Log.d(TAG, "Session destroyed for $key")
-            }
-
+            logger.logSessionDestroyed(key)
             if (resumption == true) {
                 // Some apps create a session when MBS is queried. We should unregister the
                 // controller since it will no longer be valid, but don't cancel the timeout
@@ -185,9 +173,7 @@
         }
 
         private fun processState(state: PlaybackState?, dispatchEvents: Boolean) {
-            if (DEBUG) {
-                Log.v(TAG, "processState $key: $state")
-            }
+            logger.logPlaybackState(key, state)
 
             val isPlaying = state != null && isPlayingState(state.state)
             val resumptionChanged = resumption != mediaData.resumption
@@ -198,12 +184,10 @@
             resumption = mediaData.resumption
 
             if (!isPlaying) {
-                if (DEBUG) {
-                    Log.v(TAG, "schedule timeout for $key playing $isPlaying, $resumption")
-                }
+                logger.logScheduleTimeout(key, isPlaying, resumption!!)
                 if (cancellation != null && !resumptionChanged) {
                     // if the media changed resume state, we'll need to adjust the timeout length
-                    if (DEBUG) Log.d(TAG, "cancellation already exists, continuing.")
+                    logger.logCancelIgnored(key)
                     return
                 }
                 expireMediaTimeout(key, "PLAYBACK STATE CHANGED - $state, $resumption")
@@ -214,9 +198,7 @@
                 }
                 cancellation = mainExecutor.executeDelayed({
                     cancellation = null
-                    if (DEBUG) {
-                        Log.v(TAG, "Execute timeout for $key")
-                    }
+                    logger.logTimeout(key)
                     timedOut = true
                     // this event is async, so it's safe even when `dispatchEvents` is false
                     timeoutCallback(key, timedOut)
@@ -232,9 +214,7 @@
 
         private fun expireMediaTimeout(mediaKey: String, reason: String) {
             cancellation?.apply {
-                if (DEBUG) {
-                    Log.v(TAG, "media timeout cancelled for  $mediaKey, reason: $reason")
-                }
+                logger.logTimeoutCancelled(mediaKey, reason)
                 run()
             }
             cancellation = null
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutLogger.kt b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutLogger.kt
new file mode 100644
index 0000000..a865159
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutLogger.kt
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media
+
+import android.media.session.PlaybackState
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.MediaTimeoutListenerLog
+import javax.inject.Inject
+
+private const val TAG = "MediaTimeout"
+
+/**
+ * A buffered log for [MediaTimeoutListener] events
+ */
+@SysUISingleton
+class MediaTimeoutLogger @Inject constructor(
+    @MediaTimeoutListenerLog private val buffer: LogBuffer
+) {
+    fun logReuseListener(key: String) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        {
+            str1 = key
+        },
+        {
+            "reuse listener: $str1"
+        }
+    )
+
+    fun logMigrateListener(oldKey: String?, newKey: String?, hadListener: Boolean) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        {
+            str1 = oldKey
+            str2 = newKey
+            bool1 = hadListener
+        },
+        {
+            "migrate from $str1 to $str2, had listener? $bool1"
+        }
+    )
+
+    fun logUpdateListener(key: String, wasPlaying: Boolean) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        {
+            str1 = key
+            bool1 = wasPlaying
+        },
+        {
+            "updating $str1, was playing? $bool1"
+        }
+    )
+
+    fun logDelayedUpdate(key: String) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        {
+            str1 = key
+        },
+        {
+            "deliver delayed playback state for $str1"
+        }
+    )
+
+    fun logSessionDestroyed(key: String) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        {
+            str1 = key
+        },
+        {
+            "session destroyed $str1"
+        }
+    )
+
+    fun logPlaybackState(key: String, state: PlaybackState?) = buffer.log(
+        TAG,
+        LogLevel.VERBOSE,
+        {
+            str1 = key
+            str2 = state?.toString()
+        },
+        {
+            "state update: key=$str1 state=$str2"
+        }
+    )
+
+    fun logScheduleTimeout(key: String, playing: Boolean, resumption: Boolean) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        {
+            str1 = key
+            bool1 = playing
+            bool2 = resumption
+        },
+        {
+            "schedule timeout $str1, playing=$bool1 resumption=$bool2"
+        }
+    )
+
+    fun logCancelIgnored(key: String) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        {
+            str1 = key
+        },
+        {
+            "cancellation already exists for $str1"
+        }
+    )
+
+    fun logTimeout(key: String) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        {
+            str1 = key
+        },
+        {
+            "execute timeout for $str1"
+        }
+    )
+
+    fun logTimeoutCancelled(key: String, reason: String) = buffer.log(
+        TAG,
+        LogLevel.VERBOSE,
+        {
+            str1 = key
+            str2 = reason
+        },
+        {
+            "media timeout cancelled for $str1, reason: $str2"
+        }
+    )
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
index 193166b..0359c63 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
@@ -151,13 +151,21 @@
     }
 
     /**
-     * Event indicating that the user has moved the seek bar but hasn't yet finished the gesture.
+     * Event indicating that the user has moved the seek bar.
+     *
      * @param position Current location in the track.
      */
     @AnyThread
     fun onSeekProgress(position: Long) = bgExecutor.execute {
         if (scrubbing) {
+            // The user hasn't yet finished their touch gesture, so only update the data for visual
+            // feedback and don't update [controller] yet.
             _data = _data.copy(elapsedTime = position.toInt())
+        } else {
+            // The seek progress came from an a11y action and we should immediately update to the
+            // new position. (a11y actions to change the seekbar position don't trigger
+            // SeekBar.OnSeekBarChangeListener.onStartTrackingTouch or onStopTrackingTouch.)
+            onSeek(position)
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 72488f3..357ff38 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -197,6 +197,7 @@
     private final Optional<Pip> mPipOptional;
     private final Optional<Recents> mRecentsOptional;
     private final DeviceConfigProxy mDeviceConfigProxy;
+    private final NavigationBarTransitions mNavigationBarTransitions;
     private final Optional<BackAnimation> mBackAnimation;
     private final Handler mHandler;
     private final NavigationBarOverlayController mNavbarOverlayController;
@@ -329,7 +330,8 @@
         @Override
         public void onConnectionChanged(boolean isConnected) {
             mView.onOverviewProxyConnectionChange(
-                    mOverviewProxyService.isEnabled(), mOverviewProxyService.shouldShowSwipeUpUI());
+                    mOverviewProxyService.isEnabled());
+            mView.setShouldShowSwipeUpUi(mOverviewProxyService.shouldShowSwipeUpUI());
             updateScreenPinningGestures();
         }
 
@@ -513,6 +515,7 @@
             InputMethodManager inputMethodManager,
             DeadZone deadZone,
             DeviceConfigProxy deviceConfigProxy,
+            NavigationBarTransitions navigationBarTransitions,
             Optional<BackAnimation> backAnimation) {
         super(navigationBarView);
         mFrame = navigationBarFrame;
@@ -537,6 +540,7 @@
         mRecentsOptional = recentsOptional;
         mDeadZone = deadZone;
         mDeviceConfigProxy = deviceConfigProxy;
+        mNavigationBarTransitions = navigationBarTransitions;
         mBackAnimation = backAnimation;
         mHandler = mainHandler;
         mNavbarOverlayController = navbarOverlayController;
@@ -561,6 +565,7 @@
     public void onInit() {
         // TODO: A great deal of this code should probably live in onViewAttached.
         // It should also has corresponding cleanup in onViewDetached.
+        mView.setBarTransitions(mNavigationBarTransitions);
         mView.setTouchHandler(mTouchHandler);
         mView.setNavBarMode(mNavBarMode);
         mView.updateRotationButton();
@@ -632,7 +637,7 @@
         mView.setOnVerticalChangedListener(this::onVerticalChanged);
         mView.setOnTouchListener(this::onNavigationTouch);
         if (mSavedState != null) {
-            mView.getLightTransitionsController().restoreState(mSavedState);
+            getBarTransitions().getLightTransitionsController().restoreState(mSavedState);
         }
         setNavigationIconHints(mNavigationIconHints);
         mView.setWindowVisible(isNavBarWindowVisible());
@@ -705,8 +710,7 @@
                 mView.getRotationButtonController();
         rotationButtonController.setRotationCallback(null);
         mView.setUpdateActiveTouchRegionsCallback(null);
-        mView.getBarTransitions().destroy();
-        mView.getLightTransitionsController().destroy(mContext);
+        getBarTransitions().destroy();
         mOverviewProxyService.removeCallback(mOverviewProxyListener);
         mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
         if (mOrientationHandle != null) {
@@ -732,7 +736,7 @@
         outState.putInt(EXTRA_APPEARANCE, mAppearance);
         outState.putInt(EXTRA_BEHAVIOR, mBehavior);
         outState.putBoolean(EXTRA_TRANSIENT_STATE, mTransientShown);
-        mView.getLightTransitionsController().saveState(outState);
+        getBarTransitions().getLightTransitionsController().saveState(outState);
     }
 
     /**
@@ -893,7 +897,7 @@
         pw.println("  mTransientShown=" + mTransientShown);
         pw.println("  mTransientShownFromGestureOnSystemBar="
                 + mTransientShownFromGestureOnSystemBar);
-        dumpBarTransitions(pw, "mNavigationBarView", mView.getBarTransitions());
+        dumpBarTransitions(pw, "mNavigationBarView", getBarTransitions());
         mView.dump(pw);
     }
 
@@ -1430,7 +1434,7 @@
         mLightBarController = lightBarController;
         if (mLightBarController != null) {
             mLightBarController.setNavigationBar(
-                    mView.getLightTransitionsController());
+                    getBarTransitions().getLightTransitionsController());
         }
     }
 
@@ -1472,7 +1476,7 @@
                 mCentralSurfacesOptionalLazy.get().map(CentralSurfaces::isDeviceInteractive)
                         .orElse(false)
                 && mNavigationBarWindowState != WINDOW_STATE_HIDDEN;
-        mView.getBarTransitions().transitionTo(mTransitionMode, anim);
+        getBarTransitions().transitionTo(mTransitionMode, anim);
     }
 
     public void disableAnimationsDuringHide(long delay) {
@@ -1492,11 +1496,11 @@
     }
 
     public NavigationBarTransitions getBarTransitions() {
-        return mView.getBarTransitions();
+        return mNavigationBarTransitions;
     }
 
     public void finishBarAnimations() {
-        mView.getBarTransitions().finishAnimations();
+        getBarTransitions().finishAnimations();
     }
 
     private WindowManager.LayoutParams getBarLayoutParams(int rotation) {
@@ -1654,6 +1658,7 @@
             }
             if (mView != null) {
                 mView.setNavBarMode(mode);
+                mView.setShouldShowSwipeUpUi(mOverviewProxyService.shouldShowSwipeUpUI());
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
index 58e07db..11a4b3b 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
@@ -29,19 +29,20 @@
 import android.view.IWindowManager;
 import android.view.View;
 
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
 import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.BarTransitions;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.inject.Inject;
+
+/** */
+@NavigationBarScope
 public final class NavigationBarTransitions extends BarTransitions implements
         LightBarTransitionsController.DarkIntensityApplier {
 
@@ -60,6 +61,8 @@
     }
 
     private final NavigationBarView mView;
+    @org.jetbrains.annotations.NotNull
+    private final IWindowManager mWindowManagerService;
     private final LightBarTransitionsController mLightTransitionsController;
     private final boolean mAllowAutoDimWallpaperNotVisible;
     private boolean mWallpaperVisible;
@@ -81,22 +84,21 @@
         }
     };
 
-    public NavigationBarTransitions(NavigationBarView view, CommandQueue commandQueue) {
+    @Inject
+    public NavigationBarTransitions(
+            NavigationBarView view,
+            IWindowManager windowManagerService,
+            LightBarTransitionsController.Factory lightBarTransitionsControllerFactory) {
         super(view, R.drawable.nav_background);
         mView = view;
-        mLightTransitionsController = new LightBarTransitionsController(
-                view.getContext(),
-                this,
-                commandQueue,
-                Dependency.get(KeyguardStateController.class),
-                Dependency.get(StatusBarStateController.class));
+        mWindowManagerService = windowManagerService;
+        mLightTransitionsController = lightBarTransitionsControllerFactory.create(this);
         mAllowAutoDimWallpaperNotVisible = view.getContext().getResources()
                 .getBoolean(R.bool.config_navigation_bar_enable_auto_dim_no_visible_wallpaper);
         mDarkIntensityListeners = new ArrayList();
 
-        IWindowManager windowManagerService = Dependency.get(IWindowManager.class);
         try {
-            mWallpaperVisible = windowManagerService.registerWallpaperVisibilityListener(
+            mWallpaperVisible = mWindowManagerService.registerWallpaperVisibilityListener(
                     mWallpaperVisibilityListener, Display.DEFAULT_DISPLAY);
         } catch (RemoteException e) {
         }
@@ -121,12 +123,12 @@
 
     @Override
     public void destroy() {
-        IWindowManager windowManagerService = Dependency.get(IWindowManager.class);
         try {
-            windowManagerService.unregisterWallpaperVisibilityListener(mWallpaperVisibilityListener,
+            mWindowManagerService.unregisterWallpaperVisibilityListener(mWallpaperVisibilityListener,
                     Display.DEFAULT_DISPLAY);
         } catch (RemoteException e) {
         }
+        mLightTransitionsController.destroy();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index abff914..f3a3f10 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -85,7 +85,6 @@
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
@@ -140,7 +139,7 @@
     private EdgeBackGestureHandler mEdgeBackGestureHandler;
     private final DeadZone mDeadZone;
     private boolean mDeadZoneConsuming = false;
-    private final NavigationBarTransitions mBarTransitions;
+    private NavigationBarTransitions mBarTransitions;
     @Nullable
     private AutoHideController mAutoHideController;
 
@@ -370,7 +369,6 @@
         mConfiguration.updateFrom(context.getResources().getConfiguration());
 
         mScreenPinningNotify = new ScreenPinningNotify(mContext);
-        mBarTransitions = new NavigationBarTransitions(this, Dependency.get(CommandQueue.class));
 
         mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
         mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
@@ -418,12 +416,12 @@
         }
     }
 
-    public void setAutoHideController(AutoHideController autoHideController) {
-        mAutoHideController = autoHideController;
+    void setBarTransitions(NavigationBarTransitions navigationBarTransitions) {
+        mBarTransitions = navigationBarTransitions;
     }
 
-    public NavigationBarTransitions getBarTransitions() {
-        return mBarTransitions;
+    public void setAutoHideController(AutoHideController autoHideController) {
+        mAutoHideController = autoHideController;
     }
 
     public LightBarTransitionsController getLightTransitionsController() {
@@ -888,8 +886,11 @@
         }
     }
 
-    void onOverviewProxyConnectionChange(boolean enabled, boolean showSwipeUpUi) {
+    void onOverviewProxyConnectionChange(boolean enabled) {
         mOverviewProxyEnabled = enabled;
+    }
+
+    void setShouldShowSwipeUpUi(boolean showSwipeUpUi) {
         mShowSwipeUpUi = showSwipeUpUi;
         updateStates();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index cdc6b3b..363baaa 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -264,7 +264,7 @@
             mWindowContext = null;
         }
         mAutoHideController.setNavigationBar(null);
-        mLightBarTransitionsController.destroy(mContext);
+        mLightBarTransitionsController.destroy();
         mLightBarController.setNavigationBar(null);
         mPipOptional.ifPresent(this::removePipExclusionBoundsChangeListener);
         mInitialized = false;
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
index fe4cb71..d4e1642 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
@@ -67,7 +67,7 @@
             attributes.receiveInsetsIgnoringZOrder = true
             setGravity(Gravity.TOP or Gravity.CENTER_HORIZONTAL)
         }
-
+        setTitle(R.string.ongoing_privacy_dialog_a11y_title)
         setContentView(R.layout.privacy_dialog)
         rootView = requireViewById<ViewGroup>(R.id.root)
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 34f771c..ce50ddf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -39,6 +39,7 @@
 
     private static final boolean DEBUG = false;
     private static final String CURRENT_PAGE = "current_page";
+    private static final int NO_PAGE = -1;
 
     private static final String TAG = "PagedTileLayout";
     private static final int REVEAL_SCROLL_DURATION_MILLIS = 750;
@@ -109,13 +110,14 @@
     }
 
     public void saveInstanceState(Bundle outState) {
-        outState.putInt(CURRENT_PAGE, getCurrentItem());
+        int resolvedPage = mPageToRestore != NO_PAGE ? mPageToRestore : getCurrentPageNumber();
+        outState.putInt(CURRENT_PAGE, resolvedPage);
     }
 
     public void restoreInstanceState(Bundle savedInstanceState) {
         // There's only 1 page at this point. We want to restore the correct page once the
         // pages have been inflated
-        mPageToRestore = savedInstanceState.getInt(CURRENT_PAGE, -1);
+        mPageToRestore = savedInstanceState.getInt(CURRENT_PAGE, NO_PAGE);
     }
 
     @Override
@@ -151,12 +153,15 @@
 
     @Override
     public void onRtlPropertiesChanged(int layoutDirection) {
+        // The configuration change will change the flag in the view (that's returned in
+        // isLayoutRtl). As we detect the change, we use the cached direction to store the page
+        // before setting it.
+        final int page = getPageNumberForDirection(mLayoutDirection == LAYOUT_DIRECTION_RTL);
         super.onRtlPropertiesChanged(layoutDirection);
         if (mLayoutDirection != layoutDirection) {
             mLayoutDirection = layoutDirection;
             setAdapter(mAdapter);
-            setCurrentItem(0, false);
-            mPageToRestore = 0;
+            setCurrentItem(page, false);
         }
     }
 
@@ -172,8 +177,12 @@
      * Obtains the current page number respecting RTL
      */
     private int getCurrentPageNumber() {
+        return getPageNumberForDirection(isLayoutRtl());
+    }
+
+    private int getPageNumberForDirection(boolean isLayoutRTL) {
         int page = getCurrentItem();
-        if (mLayoutDirection == LAYOUT_DIRECTION_RTL) {
+        if (isLayoutRTL) {
             page = mPages.size() - 1 - page;
         }
         return page;
@@ -388,9 +397,9 @@
         mPageIndicator.setNumPages(mPages.size());
         setAdapter(mAdapter);
         mAdapter.notifyDataSetChanged();
-        if (mPageToRestore != -1) {
+        if (mPageToRestore != NO_PAGE) {
             setCurrentItem(mPageToRestore, false);
-            mPageToRestore = -1;
+            mPageToRestore = NO_PAGE;
         }
     }
 
@@ -479,9 +488,27 @@
                 maxHeight = height;
             }
         }
+        if (mPages.get(0).getParent() == null) {
+            // Measure page 0 so we know how tall it is if it's not attached to the pager.
+            mPages.get(0).measure(widthMeasureSpec, heightMeasureSpec);
+            int height = mPages.get(0).getMeasuredHeight();
+            if (height > maxHeight) {
+                maxHeight = height;
+            }
+        }
         setMeasuredDimension(getMeasuredWidth(), maxHeight + getPaddingBottom());
     }
 
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+        if (mPages.get(0).getParent() == null) {
+            // Layout page 0, so we can get the bottom of the tiles. We only do this if the page
+            // is not attached.
+            mPages.get(0).layout(l, t, r, b);
+        }
+    }
+
     public int getColumnCount() {
         if (mPages.size() == 0) return 0;
         return mPages.get(0).mColumns;
@@ -625,8 +652,7 @@
                     if (mPageIndicator == null) return;
                     if (mPageListener != null) {
                         int pageNumber = isLayoutRtl() ? mPages.size() - 1 - position : position;
-                        mPageListener.onPageChanged(isLayoutRtl() ? position == mPages.size() - 1
-                                : position == 0, pageNumber);
+                        mPageListener.onPageChanged(pageNumber == 0, pageNumber);
                     }
                 }
 
@@ -645,8 +671,8 @@
                     mPageIndicator.setLocation(mPageIndicatorPosition);
                     if (mPageListener != null) {
                         int pageNumber = isLayoutRtl() ? mPages.size() - 1 - position : position;
-                        mPageListener.onPageChanged(positionOffsetPixels == 0 &&
-                                (isLayoutRtl() ? position == mPages.size() - 1 : position == 0),
+                        mPageListener.onPageChanged(
+                                positionOffsetPixels == 0 && pageNumber == 0,
                                 // Send only valid page number on integer pages
                                 positionOffsetPixels == 0 ? pageNumber : PageListener.INVALID_PAGE
                         );
diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrier.java b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrier.java
index 2959c3b..592da65 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrier.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrier.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.qs.carrier;
 
+import android.annotation.StyleRes;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.text.TextUtils;
@@ -30,6 +31,7 @@
 
 import com.android.settingslib.Utils;
 import com.android.settingslib.graph.SignalDrawable;
+import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 
 import java.util.Objects;
@@ -146,4 +148,8 @@
     public void setCarrierText(CharSequence text) {
         mCarrierText.setText(text);
     }
+
+    public void updateTextAppearance(@StyleRes int resId) {
+        FontSizeUtils.updateFontSizeFromStyle(mCarrierText, resId);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroup.java b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroup.java
index d03563f..a36035b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroup.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroup.java
@@ -16,12 +16,14 @@
 
 package com.android.systemui.qs.carrier;
 
+import android.annotation.StyleRes;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 
 /**
@@ -55,4 +57,11 @@
     View getCarrierDivider2() {
         return findViewById(R.id.qs_carrier_divider2);
     }
+
+    public void updateTextAppearance(@StyleRes int resId) {
+        FontSizeUtils.updateFontSizeFromStyle(getNoSimTextView(), resId);
+        getCarrier1View().updateTextAppearance(resId);
+        getCarrier2View().updateTextAppearance(resId);
+        getCarrier3View().updateTextAppearance(resId);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
index 8ca095d..6eb54f7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
@@ -24,7 +24,6 @@
 import android.graphics.drawable.Drawable;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.telephony.ServiceState;
@@ -90,8 +89,6 @@
     @VisibleForTesting
     protected InternetAdapter mAdapter;
     @VisibleForTesting
-    protected WifiManager mWifiManager;
-    @VisibleForTesting
     protected View mDialogView;
     @VisibleForTesting
     protected boolean mCanConfigWifi;
@@ -179,7 +176,6 @@
         mSubscriptionManager = mInternetDialogController.getSubscriptionManager();
         mDefaultDataSubId = mInternetDialogController.getDefaultDataSubscriptionId();
         mTelephonyManager = mInternetDialogController.getTelephonyManager();
-        mWifiManager = mInternetDialogController.getWifiManager();
         mCanConfigMobileData = canConfigMobileData;
         mCanConfigWifi = canConfigWifi;
         mCanChangeWifiState = WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(context);
@@ -332,7 +328,7 @@
 
         showProgressBar();
         final boolean isDeviceLocked = mInternetDialogController.isDeviceLocked();
-        final boolean isWifiEnabled = mWifiManager != null && mWifiManager.isWifiEnabled();
+        final boolean isWifiEnabled = mInternetDialogController.isWifiEnabled();
         final boolean isWifiScanEnabled = mInternetDialogController.isWifiScanEnabled();
         updateWifiToggle(isWifiEnabled, isDeviceLocked);
         updateConnectedWifi(isWifiEnabled, isDeviceLocked);
@@ -362,9 +358,8 @@
         mSeeAllLayout.setOnClickListener(this::onClickSeeMoreButton);
         mWiFiToggle.setOnCheckedChangeListener(
                 (buttonView, isChecked) -> {
-                    if (mWifiManager == null) return;
-                    buttonView.setChecked(isChecked);
-                    mWifiManager.setWifiEnabled(isChecked);
+                    if (mInternetDialogController.isWifiEnabled() == isChecked) return;
+                    mInternetDialogController.setWifiEnabled(isChecked);
                 });
         mDoneButton.setOnClickListener(v -> dismiss());
         mAirplaneModeButton.setOnClickListener(v -> {
@@ -388,7 +383,7 @@
             Log.d(TAG, "setMobileDataLayout, isCarrierNetworkActive = " + isCarrierNetworkActive);
         }
 
-        boolean isWifiEnabled = mWifiManager != null && mWifiManager.isWifiEnabled();
+        boolean isWifiEnabled = mInternetDialogController.isWifiEnabled();
         if (!mInternetDialogController.hasActiveSubId()
                 && (!isWifiEnabled || !isCarrierNetworkActive)) {
             mMobileNetworkLayout.setVisibility(View.GONE);
@@ -444,7 +439,9 @@
 
     @MainThread
     private void updateWifiToggle(boolean isWifiEnabled, boolean isDeviceLocked) {
-        mWiFiToggle.setChecked(isWifiEnabled);
+        if (mWiFiToggle.isChecked() != isWifiEnabled) {
+            mWiFiToggle.setChecked(isWifiEnabled);
+        }
         if (isDeviceLocked) {
             mWifiToggleTitleText.setTextAppearance((mConnectedWifiEntry != null)
                     ? R.style.TextAppearance_InternetDialog_Active
@@ -572,7 +569,7 @@
     }
 
     protected void showProgressBar() {
-        if (mWifiManager == null || !mWifiManager.isWifiEnabled()
+        if (!mInternetDialogController.isWifiEnabled()
                 || mInternetDialogController.isDeviceLocked()) {
             setProgressBarVisible(false);
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index d97ce77..90a3d45 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -22,6 +22,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.annotation.AnyThread;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -157,6 +158,7 @@
     private LocationController mLocationController;
     private DialogLaunchAnimator mDialogLaunchAnimator;
     private boolean mHasWifiEntries;
+    private WifiStateWorker mWifiStateWorker;
 
     @VisibleForTesting
     static final float TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f;
@@ -210,7 +212,9 @@
             @Background Handler workerHandler,
             CarrierConfigTracker carrierConfigTracker,
             LocationController locationController,
-            DialogLaunchAnimator dialogLaunchAnimator) {
+            DialogLaunchAnimator dialogLaunchAnimator,
+            WifiStateWorker wifiStateWorker
+    ) {
         if (DEBUG) {
             Log.d(TAG, "Init InternetDialogController");
         }
@@ -241,6 +245,7 @@
         mLocationController = locationController;
         mDialogLaunchAnimator = dialogLaunchAnimator;
         mConnectedWifiInternetMonitor = new ConnectedWifiInternetMonitor();
+        mWifiStateWorker = wifiStateWorker;
     }
 
     void onStart(@NonNull InternetDialogCallback callback, boolean canConfigWifi) {
@@ -323,7 +328,7 @@
 
     @Nullable
     CharSequence getSubtitleText(boolean isProgressBarVisible) {
-        if (mCanConfigWifi && !mWifiManager.isWifiEnabled()) {
+        if (mCanConfigWifi && !isWifiEnabled()) {
             // When Wi-Fi is disabled.
             //   Sub-Title: Wi-Fi is off
             if (DEBUG) {
@@ -648,6 +653,27 @@
         startActivity(intent, view);
     }
 
+    /**
+     * Enable or disable Wi-Fi.
+     *
+     * @param enabled {@code true} to enable, {@code false} to disable.
+     */
+    @AnyThread
+    public void setWifiEnabled(boolean enabled) {
+        mWifiStateWorker.setWifiEnabled(enabled);
+    }
+
+    /**
+     * Return whether Wi-Fi is enabled or disabled.
+     *
+     * @return {@code true} if Wi-Fi is enabled or enabling
+     * @see WifiManager#getWifiState()
+     */
+    @AnyThread
+    public boolean isWifiEnabled() {
+        return mWifiStateWorker.isWifiEnabled();
+    }
+
     void connectCarrierNetwork() {
         final MergedCarrierEntry mergedCarrierEntry =
                 mAccessPointController.getMergedCarrierEntry();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/WifiStateWorker.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/WifiStateWorker.java
new file mode 100644
index 0000000..a7ea50e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/WifiStateWorker.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.dialog;
+
+import static android.net.wifi.WifiManager.EXTRA_WIFI_STATE;
+import static android.net.wifi.WifiManager.WIFI_STATE_CHANGED_ACTION;
+import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
+import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
+import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
+import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
+import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.WifiManager;
+import android.util.Log;
+
+import androidx.annotation.AnyThread;
+import androidx.annotation.Nullable;
+
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+
+import javax.inject.Inject;
+
+/**
+ * Worker for the Wi-Fi enabled state cache.
+ */
+@SysUISingleton
+public class WifiStateWorker extends BroadcastReceiver {
+
+    private static final String TAG = "WifiStateWorker";
+
+    private DelayableExecutor mBackgroundExecutor;
+    private WifiManager mWifiManager;
+    private int mWifiState = WIFI_STATE_DISABLED;
+
+    @Inject
+    public WifiStateWorker(
+            BroadcastDispatcher broadcastDispatcher,
+            @Background DelayableExecutor backgroundExecutor,
+            @Nullable WifiManager wifiManager) {
+        mWifiManager = wifiManager;
+        mBackgroundExecutor = backgroundExecutor;
+
+        broadcastDispatcher.registerReceiver(this, new IntentFilter(WIFI_STATE_CHANGED_ACTION));
+        mBackgroundExecutor.execute(() -> {
+            if (mWifiManager == null) return;
+
+            mWifiState = mWifiManager.getWifiState();
+            Log.i(TAG, "WifiManager.getWifiState():" + mWifiState);
+        });
+    }
+
+    /**
+     * Enable or disable Wi-Fi.
+     *
+     * @param enabled {@code true} to enable, {@code false} to disable.
+     */
+    @AnyThread
+    public void setWifiEnabled(boolean enabled) {
+        mBackgroundExecutor.execute(() -> {
+            if (mWifiManager == null) return;
+
+            mWifiState = (enabled) ? WIFI_STATE_ENABLING : WIFI_STATE_DISABLING;
+            if (!mWifiManager.setWifiEnabled(enabled)) {
+                Log.e(TAG, "Failed to WifiManager.setWifiEnabled(" + enabled + ");");
+            }
+        });
+    }
+
+    /**
+     * Gets the Wi-Fi enabled state.
+     *
+     * @return One of {@link WifiManager#WIFI_STATE_DISABLED},
+     *         {@link WifiManager#WIFI_STATE_DISABLING}, {@link WifiManager#WIFI_STATE_ENABLED},
+     *         {@link WifiManager#WIFI_STATE_ENABLING}
+     */
+    @AnyThread
+    public int getWifiState() {
+        return mWifiState;
+    }
+
+    /**
+     * Return whether Wi-Fi is enabled or disabled.
+     *
+     * @return {@code true} if Wi-Fi is enabled or enabling
+     * @see WifiManager#getWifiState()
+     */
+    @AnyThread
+    public boolean isWifiEnabled() {
+        return (mWifiState == WIFI_STATE_ENABLED || mWifiState == WIFI_STATE_ENABLING);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (intent == null) return;
+
+        if (WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
+            final int wifiState = intent.getIntExtra(EXTRA_WIFI_STATE, WIFI_STATE_DISABLED);
+            if (wifiState == WIFI_STATE_UNKNOWN) return;
+
+            mWifiState = wifiState;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 924351d..7f3758e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -27,6 +27,7 @@
 
 import android.annotation.MainThread;
 import android.app.Service;
+import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -42,9 +43,11 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Log;
 import android.view.WindowManager;
+import android.widget.Toast;
 
 import androidx.annotation.NonNull;
 
@@ -62,9 +65,11 @@
     private ScreenshotController mScreenshot;
 
     private final UserManager mUserManager;
+    private final DevicePolicyManager mDevicePolicyManager;
     private final UiEventLogger mUiEventLogger;
     private final ScreenshotNotificationsController mNotificationsController;
     private final Handler mHandler;
+    private final Context mContext;
 
     private final BroadcastReceiver mCloseSystemDialogs = new BroadcastReceiver() {
         @Override
@@ -91,16 +96,18 @@
 
     @Inject
     public TakeScreenshotService(ScreenshotController screenshotController, UserManager userManager,
-            UiEventLogger uiEventLogger,
-            ScreenshotNotificationsController notificationsController) {
+            DevicePolicyManager devicePolicyManager, UiEventLogger uiEventLogger,
+            ScreenshotNotificationsController notificationsController, Context context) {
         if (DEBUG_SERVICE) {
             Log.d(TAG, "new " + this);
         }
         mHandler = new Handler(Looper.getMainLooper(), this::handleMessage);
         mScreenshot = screenshotController;
         mUserManager = userManager;
+        mDevicePolicyManager = devicePolicyManager;
         mUiEventLogger = uiEventLogger;
         mNotificationsController = notificationsController;
+        mContext = context;
     }
 
     @Override
@@ -182,6 +189,14 @@
             requestCallback.reportError();
             return true;
         }
+        if(mDevicePolicyManager.getScreenCaptureDisabled(null, UserHandle.USER_ALL)) {
+            Log.w(TAG, "Skipping screenshot because an IT admin has disabled "
+                    + "screenshots on the device");
+            Toast.makeText(mContext, R.string.screenshot_blocked_by_admin,
+                    Toast.LENGTH_SHORT).show();
+            requestCallback.reportError();
+            return true;
+        }
 
         ScreenshotHelper.ScreenshotRequest screenshotRequest =
                 (ScreenshotHelper.ScreenshotRequest) msg.obj;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 6ef9382..f6c4a31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -42,6 +42,7 @@
 import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.phone.ScrimController
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -340,7 +341,9 @@
     /**
      * Update blurs when pulling down the shade
      */
-    override fun onPanelExpansionChanged(rawFraction: Float, expanded: Boolean, tracking: Boolean) {
+    override fun onPanelExpansionChanged(event: PanelExpansionChangeEvent) {
+        val rawFraction = event.fraction
+        val tracking = event.tracking
         val timestamp = SystemClock.elapsedRealtimeNanos()
         val expansion = MathUtils.saturate(
                 (rawFraction - panelPullDownMinFraction) / (1f - panelPullDownMinFraction))
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 74aedb2..a8d6852 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -28,6 +28,7 @@
 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.phone.panelstate.PanelExpansionChangeEvent
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener
 import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
@@ -292,8 +293,8 @@
         this.state = newState
     }
 
-    override fun onPanelExpansionChanged(fraction: Float, expanded: Boolean, tracking: Boolean) {
-        val collapsedEnough = fraction <= 0.9f
+    override fun onPanelExpansionChanged(event: PanelExpansionChangeEvent) {
+        val collapsedEnough = event.fraction <= 0.9f
         if (collapsedEnough != this.collapsedEnoughToHide) {
             val couldShowPulsingHuns = canShowPulsingHuns
             this.collapsedEnoughToHide = collapsedEnough
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 cf3783e..36cd173 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
@@ -85,8 +85,8 @@
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.NotificationShelfController;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
 import com.android.systemui.statusbar.notification.FakeShadowView;
+import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.ShadeViewRefactor;
@@ -415,6 +415,10 @@
     private boolean mForwardScrollable;
     private boolean mBackwardScrollable;
     private NotificationShelf mShelf;
+    /**
+     * Limits the number of visible notifications. The remaining are collapsed in the notification
+     * shelf. -1 when there is no limit.
+     */
     private int mMaxDisplayedNotifications = -1;
     private float mKeyguardBottomPadding = -1;
     @VisibleForTesting int mStatusBarHeight;
@@ -1323,7 +1327,14 @@
     }
 
     private float updateStackEndHeight(float height, float bottomMargin, float topPadding) {
-        final float stackEndHeight = Math.max(0f, height - bottomMargin - topPadding);
+        final float stackEndHeight;
+        if (mMaxDisplayedNotifications != -1) {
+            // The stack intrinsic height already contains the correct value when there is a limit
+            // in the max number of notifications (e.g. as in keyguard).
+            stackEndHeight = mIntrinsicContentHeight;
+        } else {
+            stackEndHeight = Math.max(0f, height - bottomMargin - topPadding);
+        }
         mAmbientState.setStackEndHeight(stackEndHeight);
         return stackEndHeight;
     }
@@ -3615,7 +3626,7 @@
     @ShadeViewRefactor(RefactorComponent.INPUT)
     protected boolean isInsideQsHeader(MotionEvent ev) {
         mQsHeader.getBoundsOnScreen(mQsHeaderBound);
-        return mQsHeaderBound.contains((int) ev.getX(), (int) ev.getY());
+        return mQsHeaderBound.contains((int) ev.getRawX(), (int) ev.getRawY());
     }
 
     @ShadeViewRefactor(RefactorComponent.INPUT)
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 ae1fd2b..c2750c2 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
@@ -1207,7 +1207,7 @@
      */
     public void updateShowEmptyShadeView() {
         Trace.beginSection("NSSLC.updateShowEmptyShadeView");
-        mShowEmptyShadeView = mBarState != KEYGUARD
+        mShowEmptyShadeView = mStatusBarStateController.getCurrentOrUpcomingState() != KEYGUARD
                 && !mView.isQsFullScreen()
                 && getVisibleNotificationCount() == 0;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index a1dbf0c..b8411a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -110,6 +110,7 @@
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.DateTimeView;
+import android.window.SplashScreen;
 
 import androidx.annotation.NonNull;
 import androidx.lifecycle.Lifecycle;
@@ -225,6 +226,7 @@
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
@@ -1418,7 +1420,9 @@
         }
     }
 
-    private void onPanelExpansionChanged(float fraction, boolean expanded, boolean tracking) {
+    private void onPanelExpansionChanged(PanelExpansionChangeEvent event) {
+        float fraction = event.getFraction();
+        boolean tracking = event.getTracking();
         dispatchPanelExpansionForKeyguardDismiss(fraction, tracking);
 
         if (fraction == 0 || fraction == 1) {
@@ -1745,6 +1749,23 @@
                 }
 
                 @Override
+                public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {
+                    super.onLaunchAnimationStart(isExpandingFullyAbove);
+
+                    // Double check that the keyguard is still showing and not going away, but if so
+                    // set the keyguard occluded. Typically, WM will let KeyguardViewMediator know
+                    // directly, but we're overriding that to play the custom launch animation, so
+                    // we need to take care of that here. The unocclude animation is not overridden,
+                    // so WM will call KeyguardViewMediator's unocclude animation runner when the
+                    // activity is exited.
+                    if (mKeyguardStateController.isShowing()
+                            && !mKeyguardStateController.isKeyguardGoingAway()) {
+                        mKeyguardViewMediator.setOccluded(true /* isOccluded */,
+                                true /* animate */);
+                    }
+                }
+
+                @Override
                 public void onLaunchAnimationEnd(boolean isExpandingFullyAbove) {
                     // Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
                     // animation so that we can assume that mIsLaunchingActivityOverLockscreen
@@ -4112,6 +4133,7 @@
         } else {
             options = ActivityOptions.makeBasic();
         }
+        options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR);
         return options;
     }
 
@@ -4525,9 +4547,12 @@
      * @return UserHandle
      */
     private UserHandle getActivityUserHandle(Intent intent) {
-        if (intent.getComponent() != null
-                && mContext.getPackageName().equals(intent.getComponent().getPackageName())) {
-            return new UserHandle(UserHandle.myUserId());
+        String[] packages = mContext.getResources().getStringArray(R.array.system_ui_packages);
+        for (String pkg : packages) {
+            if (intent.getComponent() == null) break;
+            if (pkg.equals(intent.getComponent().getPackageName())) {
+                return new UserHandle(UserHandle.myUserId());
+            }
         }
         return UserHandle.CURRENT;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt
index 289dfc8..178c17d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt
@@ -18,9 +18,11 @@
 
 import android.app.StatusBarManager
 import android.view.View
+import android.widget.TextView
 import androidx.constraintlayout.motion.widget.MotionLayout
 import com.android.settingslib.Utils
 import com.android.systemui.Dumpable
+import com.android.systemui.FontSizeUtils
 import com.android.systemui.R
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.battery.BatteryMeterView
@@ -30,10 +32,12 @@
 import com.android.systemui.flags.Flags
 import com.android.systemui.qs.ChipVisibilityListener
 import com.android.systemui.qs.HeaderPrivacyIconsController
+import com.android.systemui.qs.carrier.QSCarrierGroup
 import com.android.systemui.qs.carrier.QSCarrierGroupController
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
 import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_BATTERY_CONTROLLER
 import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_SHADE_HEADER
+import com.android.systemui.statusbar.policy.ConfigurationController
 import java.io.PrintWriter
 import javax.inject.Inject
 import javax.inject.Named
@@ -43,6 +47,7 @@
     @Named(LARGE_SCREEN_SHADE_HEADER) private val header: View,
     private val statusBarIconController: StatusBarIconController,
     private val privacyIconsController: HeaderPrivacyIconsController,
+    private val configurationController: ConfigurationController,
     qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder,
     featureFlags: FeatureFlags,
     @Named(LARGE_SCREEN_BATTERY_CONTROLLER) batteryMeterViewController: BatteryMeterViewController,
@@ -69,6 +74,9 @@
     private val iconContainer: StatusIconContainer
     private val carrierIconSlots: List<String>
     private val qsCarrierGroupController: QSCarrierGroupController
+    private val clock: TextView = header.findViewById(R.id.clock)
+    private val date: TextView = header.findViewById(R.id.date)
+    private val qsCarrierGroup: QSCarrierGroup = header.findViewById(R.id.carrier_group)
 
     private var qsDisabled = false
 
@@ -148,9 +156,9 @@
                     .load(context, resources.getXml(R.xml.large_screen_shade_header))
             privacyIconsController.chipVisibilityListener = chipVisibilityListener
         }
-    }
 
-    init {
+        bindConfigurationListener()
+
         batteryMeterViewController.init()
         val batteryIcon: BatteryMeterView = header.findViewById(R.id.batteryRemainingIcon)
 
@@ -194,6 +202,18 @@
         }
     }
 
+    private fun bindConfigurationListener() {
+        val listener = object : ConfigurationController.ConfigurationListener {
+            override fun onDensityOrFontScaleChanged() {
+                val qsStatusStyle = R.style.TextAppearance_QS_Status
+                FontSizeUtils.updateFontSizeFromStyle(clock, qsStatusStyle)
+                FontSizeUtils.updateFontSizeFromStyle(date, qsStatusStyle)
+                qsCarrierGroup.updateTextAppearance(qsStatusStyle)
+            }
+        }
+        configurationController.addCallback(listener)
+    }
+
     private fun onShadeExpandedChanged() {
         if (shadeExpanded) {
             privacyIconsController.startListening()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index b6ad9f7..16fddb42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -93,7 +93,8 @@
         mDisplayId = mContext.getDisplayId();
     }
 
-    public void destroy(Context context) {
+    /** Call to cleanup the LightBarTransitionsController when done with it. */
+    public void destroy() {
         mCommandQueue.removeCallback(this);
         mStatusBarStateController.removeCallback(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 29fdfdb..e4f42b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -1233,6 +1233,11 @@
         mKeyguardBottomArea.initQRCodeScanner(mQRCodeScannerController);
     }
 
+    @VisibleForTesting
+    void setMaxDisplayedNotifications(int maxAllowed) {
+        mMaxAllowedKeyguardNotifications = maxAllowed;
+    }
+
     private void updateMaxDisplayedNotifications(boolean recompute) {
         if (recompute) {
             mMaxAllowedKeyguardNotifications = Math.max(computeMaxKeyguardNotifications(), 1);
@@ -1463,7 +1468,11 @@
     /**
      * @return the maximum keyguard notifications that can fit on the screen
      */
-    private int computeMaxKeyguardNotifications() {
+    @VisibleForTesting
+    int computeMaxKeyguardNotifications() {
+        if (mAmbientState.getFractionToShade() > 0 || mAmbientState.getDozeAmount() > 0) {
+            return mMaxAllowedKeyguardNotifications;
+        }
         float topPadding = mNotificationStackScrollLayoutController.getTopPadding();
         float shelfIntrinsicHeight =
                 mNotificationShelfController.getVisibility() == View.GONE
@@ -1735,6 +1744,11 @@
         return false;
     }
 
+    @VisibleForTesting
+    boolean isQsTracking() {
+        return mQsTracking;
+    }
+
     @Override
     protected boolean isInContentBounds(float x, float y) {
         float stackScrollerX = mNotificationStackScrollLayoutController.getX();
@@ -2812,16 +2826,16 @@
     private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) {
         if (!isQsExpansionEnabled() || mCollapsedOnDown
                 || (mKeyguardShowing && mKeyguardBypassController.getBypassEnabled())
-                || (mKeyguardShowing && mShouldUseSplitNotificationShade)) {
+                || mShouldUseSplitNotificationShade) {
             return false;
         }
         View header = mKeyguardShowing || mQs == null ? mKeyguardStatusBar : mQs.getHeader();
-
+        int frameTop = mKeyguardShowing || mQs == null ? 0 : mQsFrame.getTop();
         mQsInterceptRegion.set(
                 /* left= */ (int) mQsFrame.getX(),
-                /* top= */ header.getTop(),
+                /* top= */ header.getTop() + frameTop,
                 /* right= */ (int) mQsFrame.getX() + mQsFrame.getWidth(),
-                /* bottom= */ header.getBottom());
+                /* bottom= */ header.getBottom() + frameTop);
         // Also allow QS to intercept if the touch is near the notch.
         mStatusBarTouchableRegionManager.updateRegionForNotch(mQsInterceptRegion);
         final boolean onHeader = mQsInterceptRegion.contains((int) x, (int) y);
@@ -3164,12 +3178,6 @@
         mFalsingCollector.onTrackingStarted(!mKeyguardStateController.canDismissLockScreen());
         super.onTrackingStarted();
         mScrimController.onTrackingStarted();
-        // normally we want to set mQsExpandImmediate for every split shade case (at least when
-        // expanding), but keyguard tracking logic is different - this callback is called when
-        // unlocking with swipe up but not when swiping down to reveal shade
-        if (mShouldUseSplitNotificationShade && !mKeyguardShowing) {
-            mQsExpandImmediate = true;
-        }
         if (mQsFullyExpanded) {
             mQsExpandImmediate = true;
             setShowShelfOnly(true);
@@ -4916,6 +4924,12 @@
             mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
         }
         if (state == STATE_OPENING) {
+            // we need to ignore it on keyguard as this is a false alarm - transition from unlocked
+            // to locked will trigger this event and we're not actually in the process of opening
+            // the shade, lockscreen is just always expanded
+            if (mShouldUseSplitNotificationShade && !isOnKeyguard()) {
+                mQsExpandImmediate = true;
+            }
             mCentralSurfaces.makeExpandedVisible(false);
         }
         if (state == STATE_CLOSED) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 711b7e0..bdbc670 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -120,6 +120,7 @@
     private float mInitialOffsetOnTouch;
     private boolean mCollapsedAndHeadsUpOnDown;
     private float mExpandedFraction = 0;
+    private float mExpansionDragDownAmountPx = 0;
     protected float mExpandedHeight = 0;
     private boolean mPanelClosedOnDown;
     private boolean mHasLayoutedSinceDown;
@@ -795,6 +796,7 @@
                     mHeightAnimator.end();
                 }
             }
+            mExpansionDragDownAmountPx = h;
             mExpandedFraction = Math.min(1f,
                     maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
             mAmbientState.setExpansionFraction(mExpandedFraction);
@@ -1111,7 +1113,7 @@
      */
     public void updatePanelExpansionAndVisibility() {
         mPanelExpansionStateManager.onPanelExpansionChanged(
-                mExpandedFraction, isExpanded(), mTracking);
+                mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx);
         updateVisibility();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 35aee66..f9e17da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -306,7 +306,7 @@
             }
         });
         panelExpansionStateManager.addExpansionListener(
-                (fraction, expanded, tracking) -> setRawPanelExpansionFraction(fraction)
+                event -> setRawPanelExpansionFraction(event.getFraction())
         );
 
         mColors = new GradientColors();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index dd166dd..7f5cef0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -65,6 +65,7 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.ViewGroupFadeHelper;
 import com.android.systemui.statusbar.phone.KeyguardBouncer.BouncerExpansionCallback;
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -163,6 +164,10 @@
 
         @Override
         public void onVisibilityChanged(boolean isVisible) {
+            mCentralSurfaces
+                    .setBouncerShowingOverDream(
+                            isVisible && mDreamOverlayStateController.isOverlayActive());
+
             if (!isVisible) {
                 mCentralSurfaces.setBouncerHiddenFraction(KeyguardBouncer.EXPANSION_HIDDEN);
             }
@@ -353,7 +358,9 @@
     }
 
     @Override
-    public void onPanelExpansionChanged(float fraction, boolean expanded, boolean tracking) {
+    public void onPanelExpansionChanged(PanelExpansionChangeEvent event) {
+        float fraction = event.getFraction();
+        boolean tracking = event.getTracking();
         // Avoid having the shade and the bouncer open at the same time over a dream.
         final boolean hideBouncerOverDream =
                 mDreamOverlayStateController.isOverlayActive()
@@ -387,6 +394,11 @@
                     && !mBouncer.isShowing() && !mBouncer.isAnimatingAway()) {
                 mBouncer.show(false /* resetSecuritySelection */, false /* scrimmed */);
             }
+        } else if (!mShowing && mBouncer.inTransit()) {
+            // Keyguard is not visible anymore, but expansion animation was still running.
+            // We need to keep propagating the expansion state to the bouncer, otherwise it will be
+            // stuck in transit.
+            mBouncer.setExpansion(fraction);
         } else if (mPulsing && fraction == KeyguardBouncer.EXPANSION_VISIBLE) {
             // Panel expanded while pulsing but didn't translate the bouncer (because we are
             // unlocked.) Let's simply wake-up to dismiss the lock screen.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionChangeEvent.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionChangeEvent.kt
new file mode 100644
index 0000000..7c61b29
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionChangeEvent.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.systemui.statusbar.phone.panelstate
+
+import android.annotation.FloatRange
+
+data class PanelExpansionChangeEvent(
+    /** 0 when collapsed, 1 when fully expanded. */
+    @FloatRange(from = 0.0, to = 1.0) val fraction: Float,
+    /** Whether the panel should be considered expanded */
+    val expanded: Boolean,
+    /** Whether the user is actively dragging the panel. */
+    val tracking: Boolean,
+    /** The amount of pixels that the user has dragged during the expansion. */
+    val dragDownPxAmount: Float
+)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionListener.java
deleted file mode 100644
index b9f806d20..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionListener.java
+++ /dev/null
@@ -1,31 +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.systemui.statusbar.phone.panelstate;
-
-/** A listener interface to be notified of expansion events for the notification panel. */
-public interface PanelExpansionListener {
-    /**
-     * Invoked whenever the notification panel expansion changes, at every animation frame.
-     * This is the main expansion that happens when the user is swiping up to dismiss the
-     * lock screen and swiping to pull down the notification shade.
-     *
-     * @param fraction 0 when collapsed, 1 when fully expanded.
-     * @param expanded true if the panel should be considered expanded.
-     * @param tracking {@code true} when the user is actively dragging the panel.
-     */
-    void onPanelExpansionChanged(float fraction, boolean expanded, boolean tracking);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionListener.kt
new file mode 100644
index 0000000..d003824
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionListener.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.systemui.statusbar.phone.panelstate
+
+/** A listener interface to be notified of expansion events for the notification panel. */
+fun interface PanelExpansionListener {
+    /**
+     * Invoked whenever the notification panel expansion changes, at every animation frame. This is
+     * the main expansion that happens when the user is swiping up to dismiss the lock screen and
+     * swiping to pull down the notification shade.
+     */
+    fun onPanelExpansionChanged(event: PanelExpansionChangeEvent)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt
index 2c7c8e1..911e750 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt
@@ -37,6 +37,7 @@
     @FloatRange(from = 0.0, to = 1.0) private var fraction: Float = 0f
     private var expanded: Boolean = false
     private var tracking: Boolean = false
+    private var dragDownPxAmount: Float = 0f
 
     /**
      * Adds a listener that will be notified when the panel expansion fraction has changed.
@@ -45,7 +46,8 @@
      */
     fun addExpansionListener(listener: PanelExpansionListener) {
         expansionListeners.add(listener)
-        listener.onPanelExpansionChanged(fraction, expanded, tracking)
+        listener.onPanelExpansionChanged(
+            PanelExpansionChangeEvent(fraction, expanded, tracking, dragDownPxAmount))
     }
 
     /** Removes an expansion listener. */
@@ -77,7 +79,8 @@
     fun onPanelExpansionChanged(
         @FloatRange(from = 0.0, to = 1.0) fraction: Float,
         expanded: Boolean,
-        tracking: Boolean
+        tracking: Boolean,
+        dragDownPxAmount: Float
     ) {
         require(!fraction.isNaN()) { "fraction cannot be NaN" }
         val oldState = state
@@ -85,6 +88,7 @@
         this.fraction = fraction
         this.expanded = expanded
         this.tracking = tracking
+        this.dragDownPxAmount = dragDownPxAmount
 
         var fullyClosed = true
         var fullyOpened = false
@@ -110,14 +114,17 @@
                     "f=$fraction " +
                     "expanded=$expanded " +
                     "tracking=$tracking" +
+                    "drawDownPxAmount=$dragDownPxAmount " +
                     "${if (fullyOpened) " fullyOpened" else ""} " +
                     if (fullyClosed) " fullyClosed" else ""
         )
 
-        expansionListeners.forEach { it.onPanelExpansionChanged(fraction, expanded, tracking) }
+        val expansionChangeEvent =
+            PanelExpansionChangeEvent(fraction, expanded, tracking, dragDownPxAmount)
+        expansionListeners.forEach { it.onPanelExpansionChanged(expansionChangeEvent) }
     }
 
-    /** Updates the panel state if necessary.  */
+    /** Updates the panel state if necessary. */
     fun updateState(@PanelState state: Int) {
         debugLog("update state: ${this.state.stateToString()} -> ${state.stateToString()}")
         if (this.state != state) {
@@ -137,7 +144,7 @@
     }
 }
 
-/** Enum for the current state of the panel.  */
+/** Enum for the current state of the panel. */
 @Retention(AnnotationRetention.SOURCE)
 @IntDef(value = [STATE_CLOSED, STATE_OPENING, STATE_OPEN])
 internal annotation class PanelState
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
index 2a9048a..169347a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
@@ -78,6 +78,7 @@
     private final UiEventLogger mUiEventLogger;
     @VisibleForTesting
     UserAvatarView mUserAvatarView;
+    private View mUserAvatarViewWithBackground;
     UserSwitcherController.UserRecord mCurrentUser;
     private boolean mIsKeyguardShowing;
 
@@ -167,6 +168,8 @@
         super.onInit();
         if (DEBUG) Log.d(TAG, "onInit");
         mUserAvatarView = mView.findViewById(R.id.kg_multi_user_avatar);
+        mUserAvatarViewWithBackground = mView.findViewById(
+                R.id.kg_multi_user_avatar_with_background);
         mAdapter = new UserSwitcherController.BaseUserAdapter(mUserSwitcherController) {
             @Override
             public View getView(int position, View convertView, ViewGroup parent) {
@@ -186,7 +189,7 @@
             mUiEventLogger.log(
                     LockscreenGestureLogger.LockscreenUiEvent.LOCKSCREEN_SWITCH_USER_TAP);
 
-            mUserSwitchDialogController.showDialog(mView);
+            mUserSwitchDialogController.showDialog(mUserAvatarViewWithBackground);
         });
 
         mUserAvatarView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
index 050b670..233778d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.app.IActivityTaskManager;
+
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.policy.KeyguardStateController.Callback;
 
@@ -234,6 +236,12 @@
         default void onKeyguardFadingAwayChanged() {}
 
         /**
+         * We've called {@link IActivityTaskManager#keyguardGoingAway}, which initiates the unlock
+         * sequence.
+         */
+        default void onKeyguardGoingAwayChanged() {}
+
+        /**
          * Triggered when the keyguard dismiss amount has changed, via either a swipe gesture or an
          * animation.
          */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index 2f56576..be5da37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -323,6 +323,7 @@
             Trace.traceCounter(Trace.TRACE_TAG_APP, "keyguardGoingAway",
                     keyguardGoingAway ? 1 : 0);
             mKeyguardGoingAway = keyguardGoingAway;
+            new ArrayList<>(mCallbacks).forEach(Callback::onKeyguardGoingAwayChanged);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 28938d1..f151d29 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -90,6 +90,7 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -165,6 +166,8 @@
     private View mView;
     private String mCreateSupervisedUserPackage;
     private GlobalSettings mGlobalSettings;
+    private List<UserSwitchCallback> mUserSwitchCallbacks =
+            Collections.synchronizedList(new ArrayList<>());
 
     @Inject
     public UserSwitcherController(Context context,
@@ -230,7 +233,8 @@
         filter.addAction(Intent.ACTION_USER_STOPPED);
         filter.addAction(Intent.ACTION_USER_UNLOCKED);
         mBroadcastDispatcher.registerReceiver(
-                mReceiver, filter, null /* handler */, UserHandle.SYSTEM);
+                mReceiver, filter, null /* executor */,
+                UserHandle.SYSTEM, Context.RECEIVER_EXPORTED, null /* permission */);
 
         mSimpleUserSwitcher = shouldUseSimpleUserSwitcher();
 
@@ -673,6 +677,7 @@
                         i--;
                     }
                 }
+                notifyUserSwitchCallbacks();
                 notifyAdapters();
 
                 // Disconnect from the old secondary user's service
@@ -1134,6 +1139,33 @@
         mActivityStarter.startActivity(intent, true);
     }
 
+    /**
+     *  Add a subscriber to when user switches.
+     */
+    public void addUserSwitchCallback(UserSwitchCallback callback) {
+        mUserSwitchCallbacks.add(callback);
+    }
+
+    /**
+     *  Remove a subscriber to when user switches.
+     */
+    public void removeUserSwitchCallback(UserSwitchCallback callback) {
+        mUserSwitchCallbacks.remove(callback);
+    }
+
+    /**
+     *  Notify user switch callbacks that user has switched.
+     */
+    private void notifyUserSwitchCallbacks() {
+        List<UserSwitchCallback> temp;
+        synchronized (mUserSwitchCallbacks) {
+            temp = new ArrayList<>(mUserSwitchCallbacks);
+        }
+        for (UserSwitchCallback callback : temp) {
+            callback.onUserSwitched();
+        }
+    }
+
     public static final class UserRecord {
         public final UserInfo info;
         public final Bitmap picture;
@@ -1383,4 +1415,14 @@
             }
         }
     }
+
+    /**
+     * Callback to for when this controller receives the intent to switch users.
+     */
+    public interface UserSwitchCallback {
+        /**
+         * Called when user has switched.
+         */
+        void onUserSwitched();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
index 23129d2..6a9bb3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
@@ -6,8 +6,10 @@
 import android.view.View
 import android.view.ViewGroup
 import android.widget.LinearLayout
+import android.widget.RelativeLayout
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.children
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertNotNull
@@ -28,18 +30,11 @@
         private val TEST_INTERPOLATOR = Interpolators.LINEAR
     }
 
-    private val childParams = LinearLayout.LayoutParams(
-        0 /* width */,
-        LinearLayout.LayoutParams.MATCH_PARENT
-    )
-    private lateinit var rootView: LinearLayout
+    private lateinit var rootView: ViewGroup
 
     @Before
     fun setUp() {
         rootView = LinearLayout(mContext)
-        rootView.orientation = LinearLayout.HORIZONTAL
-        rootView.weightSum = 1f
-        childParams.weight = 0.5f
     }
 
     @After
@@ -93,6 +88,19 @@
         animator = rootView.getTag(R.id.tag_animator) as ObjectAnimator
         assertEquals(animator.interpolator, TEST_INTERPOLATOR)
         assertEquals(animator.duration, TEST_DURATION)
+
+        // animateRemoval()
+        setUpRootWithChildren()
+        val child = rootView.getChildAt(0)
+        success = ViewHierarchyAnimator.animateRemoval(
+            child, interpolator = TEST_INTERPOLATOR, duration = TEST_DURATION
+        )
+
+        assertTrue(success)
+        assertNotNull(child.getTag(R.id.tag_animator))
+        animator = child.getTag(R.id.tag_animator) as ObjectAnimator
+        assertEquals(animator.interpolator, TEST_INTERPOLATOR)
+        assertEquals(animator.duration, TEST_DURATION)
     }
 
     @Test
@@ -170,17 +178,7 @@
 
     @Test
     fun animatesRootAndChildren() {
-        val firstChild = View(mContext)
-        firstChild.layoutParams = childParams
-        rootView.addView(firstChild)
-        val secondChild = View(mContext)
-        secondChild.layoutParams = childParams
-        rootView.addView(secondChild)
-        rootView.measure(
-            View.MeasureSpec.makeMeasureSpec(150, View.MeasureSpec.EXACTLY),
-            View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
-        )
-        rootView.layout(0 /* l */, 0 /* t */, 150 /* r */, 100 /* b */)
+        setUpRootWithChildren()
 
         val success = ViewHierarchyAnimator.animate(rootView)
         // Change all bounds.
@@ -192,20 +190,20 @@
 
         assertTrue(success)
         assertNotNull(rootView.getTag(R.id.tag_animator))
-        assertNotNull(firstChild.getTag(R.id.tag_animator))
-        assertNotNull(secondChild.getTag(R.id.tag_animator))
+        assertNotNull(rootView.getChildAt(0).getTag(R.id.tag_animator))
+        assertNotNull(rootView.getChildAt(1).getTag(R.id.tag_animator))
         // The initial values should be those of the previous layout.
-        checkBounds(rootView, l = 0, t = 0, r = 150, b = 100)
-        checkBounds(firstChild, l = 0, t = 0, r = 75, b = 100)
-        checkBounds(secondChild, l = 75, t = 0, r = 150, b = 100)
+        checkBounds(rootView, l = 0, t = 0, r = 200, b = 100)
+        checkBounds(rootView.getChildAt(0), l = 0, t = 0, r = 100, b = 100)
+        checkBounds(rootView.getChildAt(1), l = 100, t = 0, r = 200, b = 100)
         endAnimation(rootView)
         assertNull(rootView.getTag(R.id.tag_animator))
-        assertNull(firstChild.getTag(R.id.tag_animator))
-        assertNull(secondChild.getTag(R.id.tag_animator))
+        assertNull(rootView.getChildAt(0).getTag(R.id.tag_animator))
+        assertNull(rootView.getChildAt(1).getTag(R.id.tag_animator))
         // The end values should be those of the latest layout.
         checkBounds(rootView, l = 10, t = 20, r = 200, b = 120)
-        checkBounds(firstChild, l = 0, t = 0, r = 95, b = 100)
-        checkBounds(secondChild, l = 95, t = 0, r = 190, b = 100)
+        checkBounds(rootView.getChildAt(0), l = 0, t = 0, r = 95, b = 100)
+        checkBounds(rootView.getChildAt(1), l = 95, t = 0, r = 190, b = 100)
     }
 
     @Test
@@ -522,6 +520,251 @@
         endAnimation(rootView)
     }
 
+    fun animatesViewRemovalFromStartToEnd() {
+        setUpRootWithChildren()
+
+        val child = rootView.getChildAt(0)
+        val success = ViewHierarchyAnimator.animateRemoval(
+            child,
+            destination = ViewHierarchyAnimator.Hotspot.LEFT,
+            interpolator = Interpolators.LINEAR
+        )
+
+        assertTrue(success)
+        assertNotNull(child.getTag(R.id.tag_animator))
+        checkBounds(child, l = 0, t = 0, r = 100, b = 100)
+        advanceAnimation(child, 0.5f)
+        checkBounds(child, l = 0, t = 0, r = 50, b = 100)
+        advanceAnimation(child, 1.0f)
+        checkBounds(child, l = 0, t = 0, r = 0, b = 100)
+        endAnimation(rootView)
+        endAnimation(child)
+        assertEquals(1, rootView.childCount)
+        assertFalse(child in rootView.children)
+    }
+
+    @Test
+    fun animatesViewRemovalRespectingDestination() {
+        // CENTER
+        setUpRootWithChildren()
+        var removedChild = rootView.getChildAt(0)
+        var remainingChild = rootView.getChildAt(1)
+        var success = ViewHierarchyAnimator.animateRemoval(
+            removedChild, destination = ViewHierarchyAnimator.Hotspot.CENTER
+        )
+        // Ensure that the layout happens before the checks.
+        forceLayout()
+
+        assertTrue(success)
+        assertNotNull(removedChild.getTag(R.id.tag_animator))
+        advanceAnimation(removedChild, 1.0f)
+        checkBounds(removedChild, l = 50, t = 50, r = 50, b = 50)
+        endAnimation(rootView)
+        endAnimation(removedChild)
+        checkBounds(remainingChild, l = 0, t = 0, r = 100, b = 100)
+
+        // LEFT
+        setUpRootWithChildren()
+        removedChild = rootView.getChildAt(0)
+        remainingChild = rootView.getChildAt(1)
+        success = ViewHierarchyAnimator.animateRemoval(
+            removedChild, destination = ViewHierarchyAnimator.Hotspot.LEFT
+        )
+        // Ensure that the layout happens before the checks.
+        forceLayout()
+
+        assertTrue(success)
+        assertNotNull(removedChild.getTag(R.id.tag_animator))
+        advanceAnimation(removedChild, 1.0f)
+        checkBounds(removedChild, l = 0, t = 0, r = 0, b = 100)
+        endAnimation(rootView)
+        endAnimation(removedChild)
+        checkBounds(remainingChild, l = 0, t = 0, r = 100, b = 100)
+
+        // TOP_LEFT
+        setUpRootWithChildren()
+        removedChild = rootView.getChildAt(0)
+        remainingChild = rootView.getChildAt(1)
+        success = ViewHierarchyAnimator.animateRemoval(
+            removedChild, destination = ViewHierarchyAnimator.Hotspot.TOP_LEFT
+        )
+        // Ensure that the layout happens before the checks.
+        forceLayout()
+
+        assertTrue(success)
+        assertNotNull(removedChild.getTag(R.id.tag_animator))
+        advanceAnimation(removedChild, 1.0f)
+        checkBounds(removedChild, l = 0, t = 0, r = 0, b = 0)
+        endAnimation(rootView)
+        endAnimation(removedChild)
+        checkBounds(remainingChild, l = 0, t = 0, r = 100, b = 100)
+
+        // TOP
+        setUpRootWithChildren()
+        removedChild = rootView.getChildAt(0)
+        remainingChild = rootView.getChildAt(1)
+        success = ViewHierarchyAnimator.animateRemoval(
+            removedChild, destination = ViewHierarchyAnimator.Hotspot.TOP
+        )
+        // Ensure that the layout happens before the checks.
+        forceLayout()
+
+        assertTrue(success)
+        assertNotNull(removedChild.getTag(R.id.tag_animator))
+        advanceAnimation(removedChild, 1.0f)
+        checkBounds(removedChild, l = 0, t = 0, r = 100, b = 0)
+        endAnimation(rootView)
+        endAnimation(removedChild)
+        checkBounds(remainingChild, l = 0, t = 0, r = 100, b = 100)
+
+        // TOP_RIGHT
+        setUpRootWithChildren()
+        removedChild = rootView.getChildAt(0)
+        remainingChild = rootView.getChildAt(1)
+        success = ViewHierarchyAnimator.animateRemoval(
+            removedChild, destination = ViewHierarchyAnimator.Hotspot.TOP_RIGHT
+        )
+        // Ensure that the layout happens before the checks.
+        forceLayout()
+
+        assertTrue(success)
+        assertNotNull(removedChild.getTag(R.id.tag_animator))
+        advanceAnimation(removedChild, 1.0f)
+        checkBounds(removedChild, l = 100, t = 0, r = 100, b = 0)
+        endAnimation(rootView)
+        endAnimation(removedChild)
+        checkBounds(remainingChild, l = 0, t = 0, r = 100, b = 100)
+
+        // RIGHT
+        setUpRootWithChildren()
+        removedChild = rootView.getChildAt(0)
+        remainingChild = rootView.getChildAt(1)
+        success = ViewHierarchyAnimator.animateRemoval(
+            removedChild, destination = ViewHierarchyAnimator.Hotspot.RIGHT
+        )
+        // Ensure that the layout happens before the checks.
+        forceLayout()
+
+        assertTrue(success)
+        assertNotNull(removedChild.getTag(R.id.tag_animator))
+        advanceAnimation(removedChild, 1.0f)
+        checkBounds(removedChild, l = 100, t = 0, r = 100, b = 100)
+        endAnimation(rootView)
+        endAnimation(removedChild)
+        checkBounds(remainingChild, l = 0, t = 0, r = 100, b = 100)
+
+        // BOTTOM_RIGHT
+        setUpRootWithChildren()
+        removedChild = rootView.getChildAt(0)
+        remainingChild = rootView.getChildAt(1)
+        success = ViewHierarchyAnimator.animateRemoval(
+            removedChild, destination = ViewHierarchyAnimator.Hotspot.BOTTOM_RIGHT
+        )
+        // Ensure that the layout happens before the checks.
+        forceLayout()
+
+        assertTrue(success)
+        assertNotNull(removedChild.getTag(R.id.tag_animator))
+        advanceAnimation(removedChild, 1.0f)
+        checkBounds(removedChild, l = 100, t = 100, r = 100, b = 100)
+        endAnimation(rootView)
+        endAnimation(removedChild)
+        checkBounds(remainingChild, l = 0, t = 0, r = 100, b = 100)
+
+        // BOTTOM
+        setUpRootWithChildren()
+        removedChild = rootView.getChildAt(0)
+        remainingChild = rootView.getChildAt(1)
+        success = ViewHierarchyAnimator.animateRemoval(
+            removedChild, destination = ViewHierarchyAnimator.Hotspot.BOTTOM
+        )
+        // Ensure that the layout happens before the checks.
+        forceLayout()
+
+        assertTrue(success)
+        assertNotNull(removedChild.getTag(R.id.tag_animator))
+        advanceAnimation(removedChild, 1.0f)
+        checkBounds(removedChild, l = 0, t = 100, r = 100, b = 100)
+        endAnimation(rootView)
+        endAnimation(removedChild)
+        checkBounds(remainingChild, l = 0, t = 0, r = 100, b = 100)
+
+        // BOTTOM_LEFT
+        setUpRootWithChildren()
+        removedChild = rootView.getChildAt(0)
+        remainingChild = rootView.getChildAt(1)
+        success = ViewHierarchyAnimator.animateRemoval(
+            removedChild, destination = ViewHierarchyAnimator.Hotspot.BOTTOM_LEFT
+        )
+        // Ensure that the layout happens before the checks.
+        forceLayout()
+
+        assertTrue(success)
+        assertNotNull(removedChild.getTag(R.id.tag_animator))
+        advanceAnimation(removedChild, 1.0f)
+        checkBounds(removedChild, l = 0, t = 100, r = 0, b = 100)
+        endAnimation(rootView)
+        endAnimation(removedChild)
+        checkBounds(remainingChild, l = 0, t = 0, r = 100, b = 100)
+    }
+
+    @Test
+    fun animatesChildrenDuringViewRemoval() {
+        setUpRootWithChildren()
+
+        val child = rootView.getChildAt(0) as ViewGroup
+        val firstGrandChild = child.getChildAt(0)
+        val secondGrandChild = child.getChildAt(1)
+        val success = ViewHierarchyAnimator.animateRemoval(
+            child, interpolator = Interpolators.LINEAR
+        )
+
+        assertTrue(success)
+        assertNotNull(child.getTag(R.id.tag_animator))
+        assertNotNull(firstGrandChild.getTag(R.id.tag_animator))
+        assertNotNull(secondGrandChild.getTag(R.id.tag_animator))
+        checkBounds(child, l = 0, t = 0, r = 100, b = 100)
+        checkBounds(firstGrandChild, l = 0, t = 0, r = 40, b = 40)
+        checkBounds(secondGrandChild, l = 60, t = 60, r = 100, b = 100)
+
+        advanceAnimation(child, 0.5f)
+        checkBounds(child, l = 25, t = 25, r = 75, b = 75)
+        checkBounds(firstGrandChild, l = -10, t = -10, r = 30, b = 30)
+        checkBounds(secondGrandChild, l = 20, t = 20, r = 60, b = 60)
+
+        advanceAnimation(child, 1.0f)
+        checkBounds(child, l = 50, t = 50, r = 50, b = 50)
+        checkBounds(firstGrandChild, l = -20, t = -20, r = 20, b = 20)
+        checkBounds(secondGrandChild, l = -20, t = -20, r = 20, b = 20)
+
+        endAnimation(rootView)
+        endAnimation(child)
+    }
+
+    @Test
+    fun animatesSiblingsDuringViewRemoval() {
+        setUpRootWithChildren()
+
+        val removedChild = rootView.getChildAt(0)
+        val remainingChild = rootView.getChildAt(1)
+        val success = ViewHierarchyAnimator.animateRemoval(
+            removedChild, interpolator = Interpolators.LINEAR
+        )
+        // Ensure that the layout happens before the checks.
+        forceLayout()
+
+        assertTrue(success)
+        assertNotNull(remainingChild.getTag(R.id.tag_animator))
+        checkBounds(remainingChild, l = 100, t = 0, r = 200, b = 100)
+        advanceAnimation(rootView, 0.5f)
+        checkBounds(remainingChild, l = 50, t = 0, r = 150, b = 100)
+        advanceAnimation(rootView, 1.0f)
+        checkBounds(remainingChild, l = 0, t = 0, r = 100, b = 100)
+        endAnimation(rootView)
+        endAnimation(removedChild)
+        assertNull(remainingChild.getTag(R.id.tag_animator))
+    }
+
     @Test
     fun cleansUpListenersCorrectly() {
         val firstChild = View(mContext)
@@ -700,6 +943,49 @@
         checkBounds(rootView, l = 10, t = 10, r = 50, b = 50)
     }
 
+    private fun setUpRootWithChildren() {
+        rootView = LinearLayout(mContext)
+        (rootView as LinearLayout).orientation = LinearLayout.HORIZONTAL
+        (rootView as LinearLayout).weightSum = 1f
+
+        val firstChild = RelativeLayout(mContext)
+        rootView.addView(firstChild)
+        val firstGrandChild = View(mContext)
+        firstChild.addView(firstGrandChild)
+        val secondGrandChild = View(mContext)
+        firstChild.addView(secondGrandChild)
+        val secondChild = View(mContext)
+        rootView.addView(secondChild)
+
+        val childParams = LinearLayout.LayoutParams(
+            0 /* width */,
+            LinearLayout.LayoutParams.MATCH_PARENT
+        )
+        childParams.weight = 0.5f
+        firstChild.layoutParams = childParams
+        secondChild.layoutParams = childParams
+        firstGrandChild.layoutParams = RelativeLayout.LayoutParams(40 /* width */, 40 /* height */)
+        (firstGrandChild.layoutParams as RelativeLayout.LayoutParams)
+            .addRule(RelativeLayout.ALIGN_PARENT_START)
+        (firstGrandChild.layoutParams as RelativeLayout.LayoutParams)
+            .addRule(RelativeLayout.ALIGN_PARENT_TOP)
+        secondGrandChild.layoutParams = RelativeLayout.LayoutParams(40 /* width */, 40 /* height */)
+        (secondGrandChild.layoutParams as RelativeLayout.LayoutParams)
+            .addRule(RelativeLayout.ALIGN_PARENT_END)
+        (secondGrandChild.layoutParams as RelativeLayout.LayoutParams)
+            .addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
+
+        forceLayout()
+    }
+
+    private fun forceLayout() {
+        rootView.measure(
+            View.MeasureSpec.makeMeasureSpec(200 /* width */, View.MeasureSpec.AT_MOST),
+            View.MeasureSpec.makeMeasureSpec(100 /* height */, View.MeasureSpec.AT_MOST)
+        )
+        rootView.layout(0 /* l */, 0 /* t */, 200 /* r */, 100 /* b */)
+    }
+
     private fun checkBounds(v: View, l: Int, t: Int, r: Int, b: Int) {
         assertEquals(l, v.left)
         assertEquals(t, v.top)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 03b18ae..eefc412 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -603,15 +603,25 @@
     }
 
     @Test
+    public void testClientNotified_whenTaskStackChangesDuringShow() throws Exception {
+        switchTask("other_package");
+        showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
+
+        mTestableLooper.processAllMessages();
+
+        assertNull(mAuthController.mCurrentDialog);
+        assertNull(mAuthController.mReceiver);
+        verify(mDialog1).dismissWithoutCallback(true /* animate */);
+        verify(mReceiver).onDialogDismissed(
+                eq(BiometricPrompt.DISMISSED_REASON_USER_CANCEL),
+                eq(null) /* credentialAttestation */);
+    }
+
+    @Test
     public void testClientNotified_whenTaskStackChangesDuringAuthentication() throws Exception {
         showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
 
-        List<ActivityManager.RunningTaskInfo> tasks = new ArrayList<>();
-        ActivityManager.RunningTaskInfo taskInfo = mock(ActivityManager.RunningTaskInfo.class);
-        taskInfo.topActivity = mock(ComponentName.class);
-        when(taskInfo.topActivity.getPackageName()).thenReturn("other_package");
-        tasks.add(taskInfo);
-        when(mActivityTaskManager.getTasks(anyInt())).thenReturn(tasks);
+        switchTask("other_package");
 
         mAuthController.mTaskStackListener.onTaskStackChanged();
         mTestableLooper.processAllMessages();
@@ -729,6 +739,16 @@
                 BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE);
     }
 
+    private void switchTask(String packageName) {
+        final List<ActivityManager.RunningTaskInfo> tasks = new ArrayList<>();
+        final ActivityManager.RunningTaskInfo taskInfo =
+                mock(ActivityManager.RunningTaskInfo.class);
+        taskInfo.topActivity = mock(ComponentName.class);
+        when(taskInfo.topActivity.getPackageName()).thenReturn(packageName);
+        tasks.add(taskInfo);
+        when(mActivityTaskManager.getTasks(anyInt())).thenReturn(tasks);
+    }
+
     private PromptInfo createTestPromptInfo() {
         PromptInfo promptInfo = new PromptInfo();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 80df1e3..b733c5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -564,6 +564,7 @@
         // Configure UdfpsView to accept the ACTION_DOWN event
         when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
         when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
+        when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
 
         // GIVEN that the overlay is showing
         mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID,
@@ -579,6 +580,7 @@
         // FIX THIS TEST
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
         moveEvent.recycle();
+        mFgExecutor.runAllReady();
         // THEN FingerprintManager is notified about onPointerDown
         verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(0), eq(0), eq(0f),
                 eq(0f));
@@ -588,6 +590,7 @@
         // AND illumination begins
         verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
         verify(mLatencyTracker, never()).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
+        verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
         // AND onIlluminatedRunnable notifies FingerprintManager about onUiReady
         mOnIlluminatedRunnableCaptor.getValue().run();
         InOrder inOrder = inOrder(mFingerprintManager, mLatencyTracker);
@@ -606,6 +609,7 @@
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
         // WHEN fingerprint is requested because of AOD interrupt
         mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
+        mFgExecutor.runAllReady();
         // THEN illumination begins
         // AND onIlluminatedRunnable that notifies FingerprintManager is set
         verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
@@ -614,6 +618,7 @@
                 eq(0), eq(0), eq(3f) /* minor */, eq(2f) /* major */);
         verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), anyInt(),
                 anyFloat(), anyFloat());
+        verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
     }
 
     @Test
@@ -641,6 +646,7 @@
         mFgExecutor.runAllReady();
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
         mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
+        mFgExecutor.runAllReady();
         when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
         // WHEN it times out
         mFgExecutor.advanceClockToNext();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
index cd05ad4..b87a7e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -45,6 +45,7 @@
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.SystemUIDialogManager;
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -483,8 +484,11 @@
     }
 
     private void updateStatusBarExpansion(float fraction, boolean expanded) {
+        PanelExpansionChangeEvent event =
+                new PanelExpansionChangeEvent(
+                        fraction, expanded, /* tracking= */ false, /* dragDownPxAmount= */ 0f);
         for (PanelExpansionListener listener : mExpansionListeners) {
-            listener.onPanelExpansionChanged(fraction, expanded, /* tracking= */ false);
+            listener.onPanelExpansionChanged(event);
         }
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
index ed1cf69..cefdf28 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
@@ -27,7 +27,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dreams.smartspace.DreamsSmartspaceController;
+import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
 
 import org.junit.Before;
@@ -47,7 +47,7 @@
     private Context mContext;
 
     @Mock
-    private DreamsSmartspaceController mSmartspaceController;
+    private DreamSmartspaceController mSmartspaceController;
 
     @Mock
     private DreamOverlayStateController mDreamOverlayStateController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index ccbe6f7..c3fca29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
@@ -19,7 +19,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
@@ -47,6 +46,7 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
 import org.junit.Before;
@@ -193,8 +193,7 @@
         assertThat(gestureListener.onScroll(event1, event2, 0, distanceY))
                 .isTrue();
 
-        verify(mStatusBarKeyguardViewManager, never())
-                .onPanelExpansionChanged(anyFloat(), anyBoolean(), anyBoolean());
+        verify(mStatusBarKeyguardViewManager, never()).onPanelExpansionChanged(any());
     }
 
     /**
@@ -221,8 +220,7 @@
         assertThat(gestureListener.onScroll(event1, event2, 0, distanceY))
                 .isTrue();
 
-        verify(mStatusBarKeyguardViewManager, never())
-                .onPanelExpansionChanged(anyFloat(), anyBoolean(), anyBoolean());
+        verify(mStatusBarKeyguardViewManager, never()).onPanelExpansionChanged(any());
     }
 
     /**
@@ -281,14 +279,16 @@
                 .isTrue();
 
         // Ensure only called once
-        verify(mStatusBarKeyguardViewManager)
-                .onPanelExpansionChanged(anyFloat(), anyBoolean(), anyBoolean());
+        verify(mStatusBarKeyguardViewManager).onPanelExpansionChanged(any());
 
         final float expansion = isBouncerInitiallyShowing ? percent : 1 - percent;
+        final float dragDownAmount = event2.getY() - event1.getY();
 
         // Ensure correct expansion passed in.
-        verify(mStatusBarKeyguardViewManager).onPanelExpansionChanged(eq(expansion), eq(false),
-                eq(true));
+        PanelExpansionChangeEvent event =
+                new PanelExpansionChangeEvent(
+                        expansion, /* expanded= */ false, /* tracking= */ true, dragDownAmount);
+        verify(mStatusBarKeyguardViewManager).onPanelExpansionChanged(event);
     }
 
     /**
@@ -428,7 +428,6 @@
     @Test
     public void testInformBouncerShowingOnExpand() {
         swipeToPosition(1f, Direction.UP, 0);
-        verify(mCentralSurfaces).setBouncerShowingOverDream(true);
     }
 
     /**
@@ -441,7 +440,6 @@
         Mockito.clearInvocations(mCentralSurfaces);
 
         swipeToPosition(0f, Direction.DOWN, 0);
-        verify(mCentralSurfaces).setBouncerShowingOverDream(false);
     }
 
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index 83fb82c..b8c85bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -25,8 +25,12 @@
 import android.content.Intent
 import android.content.pm.ApplicationInfo
 import android.content.pm.PackageManager
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Color
 import android.graphics.drawable.Animatable2
 import android.graphics.drawable.AnimatedVectorDrawable
+import android.graphics.drawable.Drawable
 import android.graphics.drawable.GradientDrawable
 import android.graphics.drawable.Icon
 import android.graphics.drawable.RippleDrawable
@@ -124,7 +128,7 @@
     @Mock private lateinit var falsingManager: FalsingManager
     @Mock private lateinit var transitionParent: ViewGroup
     private lateinit var appIcon: ImageView
-    private lateinit var albumView: ImageView
+    @Mock private lateinit var albumView: ImageView
     private lateinit var titleText: TextView
     private lateinit var artistText: TextView
     private lateinit var seamless: ViewGroup
@@ -296,7 +300,6 @@
 
         // Set up mock views for the players
         appIcon = ImageView(context)
-        albumView = ImageView(context)
         titleText = TextView(context)
         artistText = TextView(context)
         seamless = FrameLayout(context)
@@ -416,7 +419,6 @@
         whenever(coverContainer1.context).thenReturn(mockContext)
         whenever(coverContainer2.context).thenReturn(mockContext)
         whenever(coverContainer3.context).thenReturn(mockContext)
-
     }
 
     @After
@@ -537,6 +539,60 @@
     }
 
     @Test
+    fun bindAlbumView_setAfterExecutors() {
+        val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+        val canvas = Canvas(bmp)
+        canvas.drawColor(Color.RED)
+        val albumArt = Icon.createWithBitmap(bmp)
+        val state = mediaData.copy(artwork = albumArt)
+
+        player.attachPlayer(viewHolder)
+        player.bindPlayer(state, PACKAGE)
+        bgExecutor.runAllReady()
+        mainExecutor.runAllReady()
+
+        verify(albumView).setImageDrawable(any(Drawable::class.java))
+    }
+
+    @Test
+    fun bindAlbumView_bitmapInLaterStates_setAfterExecutors() {
+        val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+        val canvas = Canvas(bmp)
+        canvas.drawColor(Color.RED)
+        val albumArt = Icon.createWithBitmap(bmp)
+
+        val state0 = mediaData.copy(artwork = null)
+        val state1 = mediaData.copy(artwork = albumArt)
+        val state2 = mediaData.copy(artwork = albumArt)
+        player.attachPlayer(viewHolder)
+
+        // First binding sets (empty) drawable
+        player.bindPlayer(state0, PACKAGE)
+        bgExecutor.runAllReady()
+        mainExecutor.runAllReady()
+        verify(albumView).setImageDrawable(any(Drawable::class.java))
+
+        // Run Metadata update so that later states don't update
+        val captor = argumentCaptor<Animator.AnimatorListener>()
+        verify(mockAnimator, times(2)).addListener(captor.capture())
+        captor.value.onAnimationEnd(mockAnimator)
+        assertThat(titleText.getText()).isEqualTo(TITLE)
+        assertThat(artistText.getText()).isEqualTo(ARTIST)
+
+        // Second binding sets transition drawable
+        player.bindPlayer(state1, PACKAGE)
+        bgExecutor.runAllReady()
+        mainExecutor.runAllReady()
+        verify(albumView, times(2)).setImageDrawable(any(Drawable::class.java))
+
+        // Third binding does run transition or update background
+        player.bindPlayer(state2, PACKAGE)
+        bgExecutor.runAllReady()
+        mainExecutor.runAllReady()
+        verify(albumView, times(2)).setImageDrawable(any(Drawable::class.java))
+    }
+
+    @Test
     fun bind_seekBarDisabled_hasActions_seekBarVisibilityIsSetToInvisible() {
         useRealConstraintSets()
 
@@ -1401,22 +1457,23 @@
         val subtitle1 = "Subtitle1"
         val subtitle2 = "Subtitle2"
         val subtitle3 = "Subtitle3"
+        val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
 
         val data = smartspaceData.copy(
             recommendations = listOf(
                 SmartspaceAction.Builder("id1", title1)
                     .setSubtitle(subtitle1)
-                    .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata))
+                    .setIcon(icon)
                     .setExtras(Bundle.EMPTY)
                     .build(),
                 SmartspaceAction.Builder("id2", title2)
                     .setSubtitle(subtitle2)
-                    .setIcon(Icon.createWithResource(context, R.drawable.ic_alarm))
+                    .setIcon(icon)
                     .setExtras(Bundle.EMPTY)
                     .build(),
                 SmartspaceAction.Builder("id3", title3)
                     .setSubtitle(subtitle3)
-                    .setIcon(Icon.createWithResource(context, R.drawable.ic_3g_mobiledata))
+                    .setIcon(icon)
                     .setExtras(Bundle.EMPTY)
                     .build()
             )
@@ -1449,6 +1506,135 @@
         assertThat(recSubtitle1.text).isEqualTo("")
     }
 
+    @Test
+    fun bindRecommendation_someHaveTitles_allTitleViewsShown() {
+        useRealConstraintSets()
+        player.attachRecommendation(recommendationViewHolder)
+
+        val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
+        val data = smartspaceData.copy(
+            recommendations = listOf(
+                SmartspaceAction.Builder("id1", "")
+                    .setSubtitle("fake subtitle")
+                    .setIcon(icon)
+                    .setExtras(Bundle.EMPTY)
+                    .build(),
+                SmartspaceAction.Builder("id2", "title2")
+                    .setSubtitle("fake subtitle")
+                    .setIcon(icon)
+                    .setExtras(Bundle.EMPTY)
+                    .build(),
+                SmartspaceAction.Builder("id3", "")
+                    .setSubtitle("fake subtitle")
+                    .setIcon(icon)
+                    .setExtras(Bundle.EMPTY)
+                    .build()
+            )
+        )
+        player.bindRecommendation(data)
+
+        assertThat(expandedSet.getVisibility(recTitle1.id)).isEqualTo(ConstraintSet.VISIBLE)
+        assertThat(expandedSet.getVisibility(recTitle2.id)).isEqualTo(ConstraintSet.VISIBLE)
+        assertThat(expandedSet.getVisibility(recTitle3.id)).isEqualTo(ConstraintSet.VISIBLE)
+    }
+
+    @Test
+    fun bindRecommendation_someHaveSubtitles_allSubtitleViewsShown() {
+        useRealConstraintSets()
+        player.attachRecommendation(recommendationViewHolder)
+
+        val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
+        val data = smartspaceData.copy(
+            recommendations = listOf(
+                SmartspaceAction.Builder("id1", "")
+                    .setSubtitle("")
+                    .setIcon(icon)
+                    .setExtras(Bundle.EMPTY)
+                    .build(),
+                SmartspaceAction.Builder("id2", "title2")
+                    .setSubtitle("")
+                    .setIcon(icon)
+                    .setExtras(Bundle.EMPTY)
+                    .build(),
+                SmartspaceAction.Builder("id3", "title3")
+                    .setSubtitle("subtitle3")
+                    .setIcon(icon)
+                    .setExtras(Bundle.EMPTY)
+                    .build()
+            )
+        )
+        player.bindRecommendation(data)
+
+        assertThat(expandedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.VISIBLE)
+        assertThat(expandedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.VISIBLE)
+        assertThat(expandedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.VISIBLE)
+    }
+
+    @Test
+    fun bindRecommendation_noneHaveSubtitles_subtitleViewsGone() {
+        useRealConstraintSets()
+        player.attachRecommendation(recommendationViewHolder)
+        val data = smartspaceData.copy(
+            recommendations = listOf(
+                SmartspaceAction.Builder("id1", "title1")
+                    .setSubtitle("")
+                    .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata))
+                    .setExtras(Bundle.EMPTY)
+                    .build(),
+                SmartspaceAction.Builder("id2", "title2")
+                    .setSubtitle("")
+                    .setIcon(Icon.createWithResource(context, R.drawable.ic_alarm))
+                    .setExtras(Bundle.EMPTY)
+                    .build(),
+                SmartspaceAction.Builder("id3", "title3")
+                    .setSubtitle("")
+                    .setIcon(Icon.createWithResource(context, R.drawable.ic_3g_mobiledata))
+                    .setExtras(Bundle.EMPTY)
+                    .build()
+            )
+        )
+
+        player.bindRecommendation(data)
+
+        assertThat(expandedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.GONE)
+        assertThat(expandedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.GONE)
+        assertThat(expandedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.GONE)
+    }
+
+    @Test
+    fun bindRecommendation_noneHaveTitles_titleAndSubtitleViewsGone() {
+        useRealConstraintSets()
+        player.attachRecommendation(recommendationViewHolder)
+        val data = smartspaceData.copy(
+            recommendations = listOf(
+                SmartspaceAction.Builder("id1", "")
+                    .setSubtitle("subtitle1")
+                    .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata))
+                    .setExtras(Bundle.EMPTY)
+                    .build(),
+                SmartspaceAction.Builder("id2", "")
+                    .setSubtitle("subtitle2")
+                    .setIcon(Icon.createWithResource(context, R.drawable.ic_alarm))
+                    .setExtras(Bundle.EMPTY)
+                    .build(),
+                SmartspaceAction.Builder("id3", "")
+                    .setSubtitle("subtitle3")
+                    .setIcon(Icon.createWithResource(context, R.drawable.ic_3g_mobiledata))
+                    .setExtras(Bundle.EMPTY)
+                    .build()
+            )
+        )
+
+        player.bindRecommendation(data)
+
+        assertThat(expandedSet.getVisibility(recTitle1.id)).isEqualTo(ConstraintSet.GONE)
+        assertThat(expandedSet.getVisibility(recTitle2.id)).isEqualTo(ConstraintSet.GONE)
+        assertThat(expandedSet.getVisibility(recTitle3.id)).isEqualTo(ConstraintSet.GONE)
+        assertThat(expandedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.GONE)
+        assertThat(expandedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.GONE)
+        assertThat(expandedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.GONE)
+    }
+
     private fun getScrubbingChangeListener(): SeekBarViewModel.ScrubbingChangeListener =
         withArgCaptor { verify(seekBarViewModel).setScrubbingChangeListener(capture()) }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
index 9116983..60cbb17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
@@ -24,6 +24,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
@@ -33,7 +34,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers.any
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.ArgumentMatchers.anyString
 import org.mockito.Captor
@@ -62,6 +62,7 @@
 
     @Mock private lateinit var mediaControllerFactory: MediaControllerFactory
     @Mock private lateinit var mediaController: MediaController
+    @Mock private lateinit var logger: MediaTimeoutLogger
     private lateinit var executor: FakeExecutor
     @Mock private lateinit var timeoutCallback: (String, Boolean) -> Unit
     @Captor private lateinit var mediaCallbackCaptor: ArgumentCaptor<MediaController.Callback>
@@ -77,7 +78,7 @@
     fun setup() {
         `when`(mediaControllerFactory.create(any())).thenReturn(mediaController)
         executor = FakeExecutor(FakeSystemClock())
-        mediaTimeoutListener = MediaTimeoutListener(mediaControllerFactory, executor)
+        mediaTimeoutListener = MediaTimeoutListener(mediaControllerFactory, executor, logger)
         mediaTimeoutListener.timeoutCallback = timeoutCallback
 
         // Create a media session and notification for testing.
@@ -112,8 +113,9 @@
         `when`(mediaController.playbackState).thenReturn(playingState)
         mediaTimeoutListener.onMediaDataLoaded(KEY, null, mediaData)
         verify(mediaController).registerCallback(capture(mediaCallbackCaptor))
+        verify(logger).logPlaybackState(eq(KEY), eq(playingState))
 
-        // Ignores is same key
+        // Ignores if same key
         clearInvocations(mediaController)
         mediaTimeoutListener.onMediaDataLoaded(KEY, KEY, mediaData)
         verify(mediaController, never()).registerCallback(anyObject())
@@ -125,6 +127,7 @@
         verify(mediaController).registerCallback(capture(mediaCallbackCaptor))
         assertThat(executor.numPending()).isEqualTo(1)
         verify(timeoutCallback, never()).invoke(anyString(), anyBoolean())
+        verify(logger).logScheduleTimeout(eq(KEY), eq(false), eq(false))
         assertThat(executor.advanceClockToNext()).isEqualTo(PAUSED_MEDIA_TIMEOUT)
     }
 
@@ -153,6 +156,7 @@
 
     @Test
     fun testOnMediaDataLoaded_migratesKeys() {
+        val newKey = "NEWKEY"
         // From not playing
         mediaTimeoutListener.onMediaDataLoaded(KEY, null, mediaData)
         clearInvocations(mediaController)
@@ -161,9 +165,10 @@
         val playingState = mock(android.media.session.PlaybackState::class.java)
         `when`(playingState.state).thenReturn(PlaybackState.STATE_PLAYING)
         `when`(mediaController.playbackState).thenReturn(playingState)
-        mediaTimeoutListener.onMediaDataLoaded("NEWKEY", KEY, mediaData)
+        mediaTimeoutListener.onMediaDataLoaded(newKey, KEY, mediaData)
         verify(mediaController).unregisterCallback(anyObject())
         verify(mediaController).registerCallback(anyObject())
+        verify(logger).logMigrateListener(eq(KEY), eq(newKey), eq(true))
 
         // Enqueues callback
         assertThat(executor.numPending()).isEqualTo(1)
@@ -171,6 +176,7 @@
 
     @Test
     fun testOnMediaDataLoaded_migratesKeys_noTimeoutExtension() {
+        val newKey = "NEWKEY"
         // From not playing
         mediaTimeoutListener.onMediaDataLoaded(KEY, null, mediaData)
         clearInvocations(mediaController)
@@ -179,11 +185,12 @@
         val playingState = mock(android.media.session.PlaybackState::class.java)
         `when`(playingState.state).thenReturn(PlaybackState.STATE_PAUSED)
         `when`(mediaController.playbackState).thenReturn(playingState)
-        mediaTimeoutListener.onMediaDataLoaded("NEWKEY", KEY, mediaData)
+        mediaTimeoutListener.onMediaDataLoaded(newKey, KEY, mediaData)
 
         // The number of queued timeout tasks remains the same. The timeout task isn't cancelled nor
         // is another scheduled
         assertThat(executor.numPending()).isEqualTo(1)
+        verify(logger).logUpdateListener(eq(newKey), eq(false))
     }
 
     @Test
@@ -205,6 +212,7 @@
         mediaCallbackCaptor.value.onPlaybackStateChanged(PlaybackState.Builder()
                 .setState(PlaybackState.STATE_PLAYING, 0L, 0f).build())
         assertThat(executor.numPending()).isEqualTo(0)
+        verify(logger).logTimeoutCancelled(eq(KEY), any())
     }
 
     @Test
@@ -249,6 +257,7 @@
         // THEN the controller is unregistered and timeout run
         verify(mediaController).unregisterCallback(anyObject())
         assertThat(executor.numPending()).isEqualTo(0)
+        verify(logger).logSessionDestroyed(eq(KEY))
     }
 
     @Test
@@ -270,6 +279,7 @@
             runAllReady()
         }
         verify(timeoutCallback).invoke(eq(KEY), eq(false))
+        verify(logger).logReuseListener(eq(KEY))
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
index afc9c81..82aa612 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
@@ -375,16 +375,20 @@
     }
 
     @Test
-    fun onProgressChangedFromUserWithoutStartTrackingTouch() {
-        // WHEN user starts dragging the seek bar
+    fun onProgressChangedFromUserWithoutStartTrackingTouch_transportUpdated() {
+        whenever(mockController.transportControls).thenReturn(mockTransport)
+        viewModel.updateController(mockController)
         val pos = 42
         val bar = SeekBar(context)
+
+        // WHEN we get an onProgressChanged event without an onStartTrackingTouch event
         with(viewModel.seekBarListener) {
             onProgressChanged(bar, pos, true)
         }
         fakeExecutor.runAllReady()
-        // THEN then elapsed time should not be updated
-        assertThat(viewModel.progress.value!!.elapsedTime).isNull()
+
+        // THEN we immediately update the transport
+        verify(mockTransport).seekTo(pos.toLong())
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index f5b006d..4a740f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -205,10 +205,9 @@
         when(mNavigationBarView.getAccessibilityButton()).thenReturn(mAccessibilityButton);
         when(mNavigationBarView.getImeSwitchButton()).thenReturn(mImeSwitchButton);
         when(mNavigationBarView.getBackButton()).thenReturn(mBackButton);
-        when(mNavigationBarView.getBarTransitions()).thenReturn(mNavigationBarTransitions);
         when(mNavigationBarView.getRotationButtonController())
                 .thenReturn(mRotationButtonController);
-        when(mNavigationBarView.getLightTransitionsController())
+        when(mNavigationBarTransitions.getLightTransitionsController())
                 .thenReturn(mLightBarTransitionsController);
         when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(true);
         setupSysuiDependency();
@@ -459,6 +458,7 @@
                 mInputMethodManager,
                 mDeadZone,
                 mDeviceConfigProxyFake,
+                mNavigationBarTransitions,
                 Optional.of(mock(BackAnimation.class))));
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
index 6a2a78b..cafd2cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
@@ -21,7 +21,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
@@ -37,8 +36,8 @@
 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.statusbar.phone.LightBarTransitionsController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Before;
@@ -53,9 +52,16 @@
 public class NavigationBarTransitionsTest extends SysuiTestCase {
 
     @Mock
+    LightBarTransitionsController.Factory mLightBarTransitionsFactory;
+    @Mock
+    LightBarTransitionsController mLightBarTransitions;
+    @Mock
     EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
     @Mock
     EdgeBackGestureHandler mEdgeBackGestureHandler;
+    @Mock
+    IWindowManager mIWindowManager;
+
     private NavigationBarTransitions mTransitions;
 
     @Before
@@ -64,7 +70,6 @@
 
         when(mEdgeBackGestureHandlerFactory.create(any(Context.class)))
                 .thenReturn(mEdgeBackGestureHandler);
-        mDependency.injectMockDependency(IWindowManager.class);
         mDependency.injectMockDependency(AssistManager.class);
         mDependency.injectMockDependency(OverviewProxyService.class);
         mDependency.injectMockDependency(StatusBarStateController.class);
@@ -76,10 +81,12 @@
                 .when(mDependency.injectMockDependency(NavigationModeController.class))
                 .getCurrentUserContext();
 
+        when(mLightBarTransitionsFactory.create(any())).thenReturn(mLightBarTransitions);
         NavigationBarView navBar = spy(new NavigationBarView(mContext, null));
         when(navBar.getCurrentView()).thenReturn(navBar);
         when(navBar.findViewById(anyInt())).thenReturn(navBar);
-        mTransitions = new NavigationBarTransitions(navBar, mock(CommandQueue.class));
+        mTransitions = new NavigationBarTransitions(
+                navBar, mIWindowManager, mLightBarTransitionsFactory);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
index c714fa0..1d687b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
@@ -35,6 +35,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 import android.content.Intent
+import android.text.TextUtils
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -373,4 +374,31 @@
                 )
         )
     }
+
+    @Test
+    fun testDialogHasTitle() {
+        // Dialog must have a non-empty title for a11y purposes.
+
+        val list = listOf(
+            PrivacyDialog.PrivacyElement(
+                PrivacyType.TYPE_MICROPHONE,
+                TEST_PACKAGE_NAME,
+                TEST_USER_ID,
+                "App",
+                null,
+                null,
+                null,
+                0L,
+                false,
+                false,
+                false,
+                TEST_PERM_GROUP,
+                null
+            )
+        )
+        dialog = PrivacyDialog(context, list, starter)
+        dialog.show()
+
+        assertThat(TextUtils.isEmpty(dialog.window?.attributes?.title)).isFalse()
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
index 633a9c3..4a8cb0b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
@@ -138,6 +138,8 @@
     private DialogLaunchAnimator mDialogLaunchAnimator;
     @Mock
     private View mDialogLaunchView;
+    @Mock
+    private WifiStateWorker mWifiStateWorker;
 
     private TestableResources mTestableResources;
     private InternetDialogController mInternetDialogController;
@@ -166,6 +168,7 @@
         when(mSystemUIToast.getView()).thenReturn(mToastView);
         when(mSystemUIToast.getGravity()).thenReturn(GRAVITY_FLAGS);
         when(mSystemUIToast.getInAnimation()).thenReturn(mAnimator);
+        when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
 
         mInternetDialogController = new InternetDialogController(mContext,
                 mock(UiEventLogger.class), mock(ActivityStarter.class), mAccessPointController,
@@ -173,7 +176,7 @@
                 mock(ConnectivityManager.class), mHandler, mExecutor, mBroadcastDispatcher,
                 mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController,
                 mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker,
-                mLocationController, mDialogLaunchAnimator);
+                mLocationController, mDialogLaunchAnimator, mWifiStateWorker);
         mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
                 mInternetDialogController.mOnSubscriptionsChangedListener);
         mInternetDialogController.onStart(mInternetDialogCallback, true);
@@ -239,7 +242,7 @@
     @Test
     public void getSubtitleText_withApmOnAndWifiOff_returnWifiIsOff() {
         fakeAirplaneModeEnabled(true);
-        when(mWifiManager.isWifiEnabled()).thenReturn(false);
+        when(mWifiStateWorker.isWifiEnabled()).thenReturn(false);
 
         assertThat(mInternetDialogController.getSubtitleText(false))
                 .isEqualTo(getResourcesString("wifi_is_off"));
@@ -254,7 +257,7 @@
     @Test
     public void getSubtitleText_withWifiOff_returnWifiIsOff() {
         fakeAirplaneModeEnabled(false);
-        when(mWifiManager.isWifiEnabled()).thenReturn(false);
+        when(mWifiStateWorker.isWifiEnabled()).thenReturn(false);
 
         assertThat(mInternetDialogController.getSubtitleText(false))
                 .isEqualTo(getResourcesString("wifi_is_off"));
@@ -269,7 +272,7 @@
     @Test
     public void getSubtitleText_withNoWifiEntry_returnSearchWifi() {
         fakeAirplaneModeEnabled(false);
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
+        when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
         mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
 
         assertThat(mInternetDialogController.getSubtitleText(true))
@@ -286,7 +289,7 @@
     public void getSubtitleText_withWifiEntry_returnTapToConnect() {
         // The preconditions WiFi Entries is already in setUp()
         fakeAirplaneModeEnabled(false);
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
+        when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
 
         assertThat(mInternetDialogController.getSubtitleText(false))
                 .isEqualTo(getResourcesString("tap_a_network_to_connect"));
@@ -301,7 +304,7 @@
     @Test
     public void getSubtitleText_deviceLockedWithWifiOn_returnUnlockToViewNetworks() {
         fakeAirplaneModeEnabled(false);
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
+        when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
         when(mKeyguardStateController.isUnlocked()).thenReturn(false);
 
         assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(false),
@@ -311,7 +314,7 @@
     @Test
     public void getSubtitleText_withNoService_returnNoNetworksAvailable() {
         fakeAirplaneModeEnabled(false);
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
+        when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
         mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
 
         doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
@@ -325,7 +328,7 @@
     @Test
     public void getSubtitleText_withMobileDataDisabled_returnNoOtherAvailable() {
         fakeAirplaneModeEnabled(false);
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
+        when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
         mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
 
         doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
@@ -346,7 +349,7 @@
     @Test
     public void getSubtitleText_withCarrierNetworkActiveOnly_returnNoOtherAvailable() {
         fakeAirplaneModeEnabled(false);
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
+        when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
         mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
         when(mMergedCarrierEntry.isDefaultNetwork()).thenReturn(true);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
index 616f894..d09a5a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
@@ -14,7 +14,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.telephony.TelephonyManager;
 import android.testing.AndroidTestingRunner;
@@ -64,8 +63,6 @@
     @Mock
     private TelephonyManager mTelephonyManager;
     @Mock
-    private WifiManager mWifiManager;
-    @Mock
     private WifiEntry mInternetWifiEntry;
     @Mock
     private List<WifiEntry> mWifiEntries;
@@ -97,7 +94,6 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
         when(mInternetWifiEntry.getTitle()).thenReturn(WIFI_TITLE);
         when(mInternetWifiEntry.getSummary(false)).thenReturn(WIFI_SUMMARY);
         when(mInternetWifiEntry.isDefaultNetwork()).thenReturn(true);
@@ -107,7 +103,7 @@
         when(mInternetDialogController.getMobileNetworkTitle()).thenReturn(MOBILE_NETWORK_TITLE);
         when(mInternetDialogController.getMobileNetworkSummary())
                 .thenReturn(MOBILE_NETWORK_SUMMARY);
-        when(mInternetDialogController.getWifiManager()).thenReturn(mWifiManager);
+        when(mInternetDialogController.isWifiEnabled()).thenReturn(true);
 
         mMockitoSession = ExtendedMockito.mockitoSession()
                 .spyStatic(WifiEnterpriseRestrictionUtils.class)
@@ -232,7 +228,7 @@
         // Carrier network should be gone if airplane mode ON and Wi-Fi is off.
         when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(true);
         when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        when(mWifiManager.isWifiEnabled()).thenReturn(false);
+        when(mInternetDialogController.isWifiEnabled()).thenReturn(false);
 
         mInternetDialog.updateDialog(true);
 
@@ -241,7 +237,7 @@
         // Carrier network should be visible if airplane mode ON and Wi-Fi is ON.
         when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(true);
         when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
+        when(mInternetDialogController.isWifiEnabled()).thenReturn(true);
 
         mInternetDialog.updateDialog(true);
 
@@ -468,7 +464,7 @@
 
     @Test
     public void updateDialog_wifiOffAndWifiScanOff_hideWifiScanNotify() {
-        when(mWifiManager.isWifiEnabled()).thenReturn(false);
+        when(mInternetDialogController.isWifiEnabled()).thenReturn(false);
         when(mInternetDialogController.isWifiScanEnabled()).thenReturn(false);
 
         mInternetDialog.updateDialog(false);
@@ -478,7 +474,7 @@
 
     @Test
     public void updateDialog_wifiOffAndWifiScanOnAndDeviceLocked_hideWifiScanNotify() {
-        when(mWifiManager.isWifiEnabled()).thenReturn(false);
+        when(mInternetDialogController.isWifiEnabled()).thenReturn(false);
         when(mInternetDialogController.isWifiScanEnabled()).thenReturn(true);
         when(mInternetDialogController.isDeviceLocked()).thenReturn(true);
 
@@ -489,7 +485,7 @@
 
     @Test
     public void updateDialog_wifiOffAndWifiScanOnAndDeviceUnlocked_showWifiScanNotify() {
-        when(mWifiManager.isWifiEnabled()).thenReturn(false);
+        when(mInternetDialogController.isWifiEnabled()).thenReturn(false);
         when(mInternetDialogController.isWifiScanEnabled()).thenReturn(true);
         when(mInternetDialogController.isDeviceLocked()).thenReturn(false);
 
@@ -502,6 +498,26 @@
     }
 
     @Test
+    public void updateDialog_wifiIsDisabled_uncheckWifiSwitch() {
+        when(mInternetDialogController.isWifiEnabled()).thenReturn(false);
+        mWifiToggleSwitch.setChecked(true);
+
+        mInternetDialog.updateDialog(false);
+
+        assertThat(mWifiToggleSwitch.isChecked()).isFalse();
+    }
+
+    @Test
+    public void updateDialog_wifiIsEnabled_checkWifiSwitch() {
+        when(mInternetDialogController.isWifiEnabled()).thenReturn(true);
+        mWifiToggleSwitch.setChecked(false);
+
+        mInternetDialog.updateDialog(false);
+
+        assertThat(mWifiToggleSwitch.isChecked()).isTrue();
+    }
+
+    @Test
     public void onClickSeeMoreButton_clickSeeAll_verifyLaunchNetworkSetting() {
         mSeeAll.performClick();
 
@@ -512,7 +528,7 @@
     @Test
     public void showProgressBar_wifiDisabled_hideProgressBar() {
         Mockito.reset(mHandler);
-        when(mWifiManager.isWifiEnabled()).thenReturn(false);
+        when(mInternetDialogController.isWifiEnabled()).thenReturn(false);
 
         mInternetDialog.showProgressBar();
 
@@ -534,7 +550,7 @@
     @Test
     public void showProgressBar_wifiEnabledWithWifiEntry_showProgressBarThenHide() {
         Mockito.reset(mHandler);
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
+        when(mInternetDialogController.isWifiEnabled()).thenReturn(true);
 
         mInternetDialog.showProgressBar();
 
@@ -553,7 +569,7 @@
     @Test
     public void showProgressBar_wifiEnabledWithoutWifiEntries_showProgressBarThenHideSearch() {
         Mockito.reset(mHandler);
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
+        when(mInternetDialogController.isWifiEnabled()).thenReturn(true);
         mInternetDialog.mConnectedWifiEntry = null;
         mInternetDialog.mWifiEntriesCount = 0;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/WifiStateWorkerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/WifiStateWorkerTest.java
new file mode 100644
index 0000000..5d7ba7b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/WifiStateWorkerTest.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.dialog;
+
+import static android.net.wifi.WifiManager.EXTRA_WIFI_STATE;
+import static android.net.wifi.WifiManager.WIFI_STATE_CHANGED_ACTION;
+import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
+import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
+import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
+import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
+import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.net.wifi.WifiManager;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class WifiStateWorkerTest extends SysuiTestCase {
+
+    @Rule
+    public MockitoRule mRule = MockitoJUnit.rule();
+    @Mock
+    private BroadcastDispatcher mBroadcastDispatcher;
+    @Mock
+    private WifiManager mWifiManager;
+    @Mock
+    private Intent mIntent;
+
+    private WifiStateWorker mWifiStateWorker;
+    private FakeExecutor mBackgroundExecutor = new FakeExecutor(new FakeSystemClock());
+
+    @Before
+    public void setup() {
+        when(mWifiManager.setWifiEnabled(anyBoolean())).thenReturn(true);
+        when(mWifiManager.getWifiState()).thenReturn(WIFI_STATE_ENABLED);
+        when(mIntent.getAction()).thenReturn(WIFI_STATE_CHANGED_ACTION);
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_ENABLED);
+
+        mWifiStateWorker = new WifiStateWorker(mBroadcastDispatcher, mBackgroundExecutor,
+                mWifiManager);
+        mBackgroundExecutor.runAllReady();
+    }
+
+    @Test
+    public void constructor_shouldGetWifiState() {
+        verify(mWifiManager).getWifiState();
+    }
+
+    @Test
+    public void setWifiEnabled_wifiManagerIsNull_shouldNotSetWifiEnabled() {
+        mWifiStateWorker = new WifiStateWorker(mBroadcastDispatcher, mBackgroundExecutor,
+                null /* wifiManager */);
+
+        mWifiStateWorker.setWifiEnabled(true);
+        mBackgroundExecutor.runAllReady();
+
+        verify(mWifiManager, never()).setWifiEnabled(anyBoolean());
+    }
+
+    @Test
+    public void setWifiEnabled_enabledIsTrue_shouldSetWifiEnabled() {
+        mWifiStateWorker.setWifiEnabled(true);
+        mBackgroundExecutor.runAllReady();
+
+        verify(mWifiManager).setWifiEnabled(true);
+    }
+
+    @Test
+    public void setWifiEnabled_enabledIsFalse_shouldSetWifiDisabled() {
+        mWifiStateWorker.setWifiEnabled(false);
+        mBackgroundExecutor.runAllReady();
+
+        verify(mWifiManager).setWifiEnabled(false);
+    }
+
+    @Test
+    public void getWifiState_receiveWifiStateDisabling_getWifiStateDisabling() {
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_DISABLING);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+
+        assertThat(mWifiStateWorker.getWifiState()).isEqualTo(WIFI_STATE_DISABLING);
+    }
+
+    @Test
+    public void getWifiState_receiveWifiStateDisabled_getWifiStateDisabled() {
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_DISABLED);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+
+        assertThat(mWifiStateWorker.getWifiState()).isEqualTo(WIFI_STATE_DISABLED);
+    }
+
+    @Test
+    public void getWifiState_receiveWifiStateEnabling_getWifiStateEnabling() {
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_ENABLING);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+
+        assertThat(mWifiStateWorker.getWifiState()).isEqualTo(WIFI_STATE_ENABLING);
+    }
+
+    @Test
+    public void getWifiState_receiveWifiStateEnabled_getWifiStateEnabled() {
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_ENABLED);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+
+        assertThat(mWifiStateWorker.getWifiState()).isEqualTo(WIFI_STATE_ENABLED);
+    }
+
+    @Test
+    public void getWifiState_receiveWifiStateUnknown_ignoreTheIntent() {
+        // Update the Wi-Fi state to WIFI_STATE_DISABLED
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_DISABLED);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+        assertThat(mWifiStateWorker.getWifiState()).isEqualTo(WIFI_STATE_DISABLED);
+
+        // Receiver WIFI_STATE_UNKNOWN
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_UNKNOWN);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+
+        // Ignore the intent and keep the Wi-Fi state to WIFI_STATE_DISABLED
+        assertThat(mWifiStateWorker.getWifiState()).isEqualTo(WIFI_STATE_DISABLED);
+
+        // Update the Wi-Fi state to WIFI_STATE_ENABLED
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_ENABLED);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+        assertThat(mWifiStateWorker.getWifiState()).isEqualTo(WIFI_STATE_ENABLED);
+
+        // Receiver WIFI_STATE_UNKNOWN change
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_UNKNOWN);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+
+        // Ignore the intent and keep the Wi-Fi state to WIFI_STATE_ENABLED
+        assertThat(mWifiStateWorker.getWifiState()).isEqualTo(WIFI_STATE_ENABLED);
+    }
+
+    @Test
+    public void isWifiEnabled_receiveWifiStateDisabling_returnFalse() {
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_DISABLING);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+
+        assertThat(mWifiStateWorker.isWifiEnabled()).isFalse();
+    }
+
+    @Test
+    public void isWifiEnabled_receiveWifiStateDisabled_returnFalse() {
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_DISABLED);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+
+        assertThat(mWifiStateWorker.isWifiEnabled()).isFalse();
+    }
+
+    @Test
+    public void isWifiEnabled_receiveWifiStateEnabling_returnTrue() {
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_ENABLING);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+
+        assertThat(mWifiStateWorker.isWifiEnabled()).isTrue();
+    }
+
+    @Test
+    public void isWifiEnabled_receiveWifiStateEnabled_returnTrue() {
+        when(mIntent.getIntExtra(eq(EXTRA_WIFI_STATE), anyInt())).thenReturn(WIFI_STATE_ENABLED);
+        mWifiStateWorker.onReceive(mContext, mIntent);
+
+        assertThat(mWifiStateWorker.isWifiEnabled()).isTrue();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
index 57803e8..446b51d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
@@ -26,7 +26,7 @@
 import android.view.ViewGroup
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.dreams.smartspace.DreamsSmartspaceController
+import com.android.systemui.dreams.smartspace.DreamSmartspaceController
 import com.android.systemui.plugins.BcSmartspaceDataPlugin
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.smartspace.dagger.SmartspaceViewComponent
@@ -97,7 +97,7 @@
      */
     @Test
     fun testConnectOnListen() {
-        val controller = DreamsSmartspaceController(context,
+        val controller = DreamSmartspaceController(context,
         smartspaceManager, execution, uiExecutor, viewComponentFactory, precondition,
                 Optional.of(targetFilter), Optional.of(plugin))
 
@@ -136,6 +136,8 @@
 
         override fun setPrimaryTextColor(color: Int) {}
 
+        override fun setIsDreaming(isDreaming: Boolean) {}
+
         override fun setDozeAmount(amount: Float) {}
 
         override fun setIntentStarter(intentStarter: BcSmartspaceDataPlugin.IntentStarter?) {}
@@ -156,7 +158,7 @@
      */
     @Test
     fun testConnectOnViewCreate() {
-        val controller = DreamsSmartspaceController(context,
+        val controller = DreamSmartspaceController(context,
                 smartspaceManager, execution, uiExecutor, viewComponentFactory, precondition,
                 Optional.of(targetFilter),
                 Optional.of(plugin))
@@ -173,6 +175,7 @@
         stateChangeListener.onViewAttachedToWindow(mockView)
 
         verify(smartspaceManager).createSmartspaceSession(any())
+        verify(mockView).setDozeAmount(0f)
 
         stateChangeListener.onViewDetachedFromWindow(mockView)
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index 1bcc038..b166b73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.statusbar.phone.BiometricUnlockController
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.phone.ScrimController
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
 import com.android.systemui.statusbar.policy.FakeConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.WallpaperController
@@ -123,7 +124,7 @@
         verify(statusBarStateController).addCallback(captor.capture())
         statusBarStateListener = captor.value
         verify(notificationShadeWindowController)
-                .setScrimsVisibilityListener(scrimVisibilityCaptor.capture())
+            .setScrimsVisibilityListener(scrimVisibilityCaptor.capture())
 
         disableSplitShade()
     }
@@ -136,16 +137,16 @@
     @Test
     fun onPanelExpansionChanged_apliesBlur_ifShade() {
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = false
-        )
+            PanelExpansionChangeEvent(
+                fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f))
         verify(shadeAnimation).animateTo(eq(maxBlur), any())
     }
 
     @Test
     fun onPanelExpansionChanged_animatesBlurIn_ifShade() {
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 0.01f, expanded = false, tracking = false
-        )
+            PanelExpansionChangeEvent(
+                fraction = 0.01f, expanded = false, tracking = false, dragDownPxAmount = 0f))
         verify(shadeAnimation).animateTo(eq(maxBlur), any())
     }
 
@@ -154,28 +155,27 @@
         onPanelExpansionChanged_animatesBlurIn_ifShade()
         clearInvocations(shadeAnimation)
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 0f, expanded = false, tracking = false
-        )
+            PanelExpansionChangeEvent(
+                fraction = 0f, expanded = false, tracking = false, dragDownPxAmount = 0f))
         verify(shadeAnimation).animateTo(eq(0), any())
     }
 
     @Test
     fun onPanelExpansionChanged_animatesBlurOut_ifFlick() {
+        val event =
+            PanelExpansionChangeEvent(
+                fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f)
         onPanelExpansionChanged_apliesBlur_ifShade()
         clearInvocations(shadeAnimation)
-        notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = true
-        )
+        notificationShadeDepthController.onPanelExpansionChanged(event)
         verify(shadeAnimation, never()).animateTo(anyInt(), any())
 
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 0.9f, expanded = true, tracking = true
-        )
+            event.copy(fraction = 0.9f, tracking = true))
         verify(shadeAnimation, never()).animateTo(anyInt(), any())
 
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 0.8f, expanded = true, tracking = false
-        )
+            event.copy(fraction = 0.8f, tracking = false))
         verify(shadeAnimation).animateTo(eq(0), any())
     }
 
@@ -184,27 +184,24 @@
         onPanelExpansionChanged_animatesBlurOut_ifFlick()
         clearInvocations(shadeAnimation)
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 0.6f, expanded = true, tracking = true
-        )
+            PanelExpansionChangeEvent(
+                fraction = 0.6f, expanded = true, tracking = true, dragDownPxAmount = 0f))
         verify(shadeAnimation).animateTo(eq(maxBlur), any())
     }
 
     @Test
     fun onPanelExpansionChanged_respectsMinPanelPullDownFraction() {
+        val event =
+            PanelExpansionChangeEvent(
+                fraction = 0.5f, expanded = true, tracking = true, dragDownPxAmount = 0f)
         notificationShadeDepthController.panelPullDownMinFraction = 0.5f
-        notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 0.5f, expanded = true, tracking = true
-        )
+        notificationShadeDepthController.onPanelExpansionChanged(event)
         assertThat(notificationShadeDepthController.shadeExpansion).isEqualTo(0f)
 
-        notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 0.75f, expanded = true, tracking = true
-        )
+        notificationShadeDepthController.onPanelExpansionChanged(event.copy(fraction = 0.75f))
         assertThat(notificationShadeDepthController.shadeExpansion).isEqualTo(0.5f)
 
-        notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = true
-        )
+        notificationShadeDepthController.onPanelExpansionChanged(event.copy(fraction = 1f))
         assertThat(notificationShadeDepthController.shadeExpansion).isEqualTo(1f)
     }
 
@@ -223,8 +220,8 @@
         statusBarState = StatusBarState.KEYGUARD
         notificationShadeDepthController.qsPanelExpansion = 1f
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = false
-        )
+            PanelExpansionChangeEvent(
+                fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f))
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
         verify(blurUtils).applyBlur(any(), eq(maxBlur), eq(false))
     }
@@ -234,11 +231,11 @@
         statusBarState = StatusBarState.KEYGUARD
         notificationShadeDepthController.qsPanelExpansion = 0.25f
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = false
-        )
+            PanelExpansionChangeEvent(
+                fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f))
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
-        verify(wallpaperController).setNotificationShadeZoom(
-                eq(ShadeInterpolation.getNotificationScrimAlpha(0.25f)))
+        verify(wallpaperController)
+            .setNotificationShadeZoom(eq(ShadeInterpolation.getNotificationScrimAlpha(0.25f)))
     }
 
     @Test
@@ -246,7 +243,8 @@
         enableSplitShade()
 
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = false)
+            PanelExpansionChangeEvent(
+                fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f))
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
 
         verify(wallpaperController).setNotificationShadeZoom(0f)
@@ -257,7 +255,8 @@
         disableSplitShade()
 
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = false)
+            PanelExpansionChangeEvent(
+                fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f))
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
 
         verify(wallpaperController).setNotificationShadeZoom(floatThat { it > 0 })
@@ -269,14 +268,16 @@
         val rawFraction = 1f
         val expanded = true
         val tracking = false
+        val dragDownPxAmount = 0f
+        val event = PanelExpansionChangeEvent(rawFraction, expanded, tracking, dragDownPxAmount)
         val inOrder = Mockito.inOrder(wallpaperController)
 
-        notificationShadeDepthController.onPanelExpansionChanged(rawFraction, expanded, tracking)
+        notificationShadeDepthController.onPanelExpansionChanged(event)
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
         inOrder.verify(wallpaperController).setNotificationShadeZoom(floatThat { it > 0 })
 
         enableSplitShade()
-        notificationShadeDepthController.onPanelExpansionChanged(rawFraction, expanded, tracking)
+        notificationShadeDepthController.onPanelExpansionChanged(event)
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
         inOrder.verify(wallpaperController).setNotificationShadeZoom(0f)
     }
@@ -332,8 +333,8 @@
     @Test
     fun updateBlurCallback_setsBlur_whenExpanded() {
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = false
-        )
+            PanelExpansionChangeEvent(
+                fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f))
         `when`(shadeAnimation.radius).thenReturn(maxBlur.toFloat())
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
         verify(blurUtils).applyBlur(any(), eq(maxBlur), eq(false))
@@ -342,8 +343,8 @@
     @Test
     fun updateBlurCallback_ignoreShadeBlurUntilHidden_overridesZoom() {
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = false
-        )
+            PanelExpansionChangeEvent(
+                fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f))
         `when`(shadeAnimation.radius).thenReturn(maxBlur.toFloat())
         notificationShadeDepthController.blursDisabledForAppLaunch = true
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
@@ -353,15 +354,15 @@
     @Test
     fun ignoreShadeBlurUntilHidden_schedulesFrame() {
         notificationShadeDepthController.blursDisabledForAppLaunch = true
-        verify(choreographer).postFrameCallback(
-                eq(notificationShadeDepthController.updateBlurCallback))
+        verify(choreographer)
+            .postFrameCallback(eq(notificationShadeDepthController.updateBlurCallback))
     }
 
     @Test
     fun ignoreBlurForUnlock_ignores() {
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = false
-        )
+            PanelExpansionChangeEvent(
+                fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f))
         `when`(shadeAnimation.radius).thenReturn(maxBlur.toFloat())
 
         notificationShadeDepthController.blursDisabledForAppLaunch = false
@@ -377,8 +378,8 @@
     @Test
     fun ignoreBlurForUnlock_doesNotIgnore() {
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = false
-        )
+            PanelExpansionChangeEvent(
+                fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f))
         `when`(shadeAnimation.radius).thenReturn(maxBlur.toFloat())
 
         notificationShadeDepthController.blursDisabledForAppLaunch = false
@@ -409,8 +410,8 @@
         `when`(brightnessSpring.ratio).thenReturn(1f)
         // And shade is blurred
         notificationShadeDepthController.onPanelExpansionChanged(
-            rawFraction = 1f, expanded = true, tracking = false
-        )
+            PanelExpansionChangeEvent(
+                fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f))
         `when`(shadeAnimation.radius).thenReturn(maxBlur.toFloat())
 
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
index 188baaf..ce58a6c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
@@ -544,6 +544,9 @@
             override fun setPrimaryTextColor(color: Int) {
             }
 
+            override fun setIsDreaming(isDreaming: Boolean) {
+            }
+
             override fun setDozeAmount(amount: Float) {
             }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index c9de608..6409967 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -228,19 +228,15 @@
     public void testUpdateEmptyShadeView_notificationsVisible_zenHiding() {
         when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(true);
         mController.attach(mNotificationStackScrollLayout);
-        verify(mSysuiStatusBarStateController).addCallback(
-                mStateListenerArgumentCaptor.capture(), anyInt());
-        StatusBarStateController.StateListener stateListener =
-                mStateListenerArgumentCaptor.getValue();
 
-        setupShowEmptyShadeViewState(stateListener, true);
+        setupShowEmptyShadeViewState(true);
         reset(mNotificationStackScrollLayout);
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
                 /* visible= */ true,
                 /* notifVisibleInShade= */ true);
 
-        setupShowEmptyShadeViewState(stateListener, false);
+        setupShowEmptyShadeViewState(false);
         reset(mNotificationStackScrollLayout);
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
@@ -252,19 +248,15 @@
     public void testUpdateEmptyShadeView_notificationsHidden_zenNotHiding() {
         when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(false);
         mController.attach(mNotificationStackScrollLayout);
-        verify(mSysuiStatusBarStateController).addCallback(
-                mStateListenerArgumentCaptor.capture(), anyInt());
-        StatusBarStateController.StateListener stateListener =
-                mStateListenerArgumentCaptor.getValue();
 
-        setupShowEmptyShadeViewState(stateListener, true);
+        setupShowEmptyShadeViewState(true);
         reset(mNotificationStackScrollLayout);
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
                 /* visible= */ true,
                 /* notifVisibleInShade= */ false);
 
-        setupShowEmptyShadeViewState(stateListener, false);
+        setupShowEmptyShadeViewState(false);
         reset(mNotificationStackScrollLayout);
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
@@ -407,15 +399,13 @@
         return argThat(new LogMatcher(category, type));
     }
 
-    private void setupShowEmptyShadeViewState(
-            StatusBarStateController.StateListener statusBarStateListener,
-            boolean toShow) {
+    private void setupShowEmptyShadeViewState(boolean toShow) {
         if (toShow) {
-            statusBarStateListener.onStateChanged(SHADE);
+            when(mSysuiStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(SHADE);
             mController.setQsFullScreen(false);
             mController.getView().removeAllViews();
         } else {
-            statusBarStateListener.onStateChanged(KEYGUARD);
+            when(mSysuiStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD);
             mController.setQsFullScreen(true);
             mController.getView().addContainerView(mock(ExpandableNotificationRow.class));
         }
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 077f6bf..e8608fa7 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
@@ -34,15 +34,20 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.graphics.Rect;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.util.MathUtils;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
 
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.filters.SmallTest;
@@ -572,9 +577,70 @@
         assertEquals(0, mStackScroller.getSpeedBumpIndex());
     }
 
+    @Test
+    public void testInsideQSHeader_noOffset() {
+        ViewGroup qsHeader = mock(ViewGroup.class);
+        Rect boundsOnScreen = new Rect(0, 0, 1000, 1000);
+        mockBoundsOnScreen(qsHeader, boundsOnScreen);
+
+        mStackScroller.setQsHeader(qsHeader);
+        mStackScroller.setLeftTopRightBottom(0, 0, 2000, 2000);
+
+        MotionEvent event1 = transformEventForView(createMotionEvent(100f, 100f), mStackScroller);
+        assertTrue(mStackScroller.isInsideQsHeader(event1));
+
+        MotionEvent event2 = transformEventForView(createMotionEvent(1100f, 100f), mStackScroller);
+        assertFalse(mStackScroller.isInsideQsHeader(event2));
+    }
+
+    @Test
+    public void testInsideQSHeader_Offset() {
+        ViewGroup qsHeader = mock(ViewGroup.class);
+        Rect boundsOnScreen = new Rect(100, 100, 1000, 1000);
+        mockBoundsOnScreen(qsHeader, boundsOnScreen);
+
+        mStackScroller.setQsHeader(qsHeader);
+        mStackScroller.setLeftTopRightBottom(200, 200, 2000, 2000);
+
+        MotionEvent event1 = transformEventForView(createMotionEvent(50f, 50f), mStackScroller);
+        assertFalse(mStackScroller.isInsideQsHeader(event1));
+
+        MotionEvent event2 = transformEventForView(createMotionEvent(150f, 150f), mStackScroller);
+        assertTrue(mStackScroller.isInsideQsHeader(event2));
+
+        MotionEvent event3 = transformEventForView(createMotionEvent(250f, 250f), mStackScroller);
+        assertTrue(mStackScroller.isInsideQsHeader(event2));
+    }
+
     private void setBarStateForTest(int state) {
         // Can't inject this through the listener or we end up on the actual implementation
         // rather than the mock because the spy just coppied the anonymous inner /shruggie.
         mStackScroller.setStatusBarState(state);
     }
+
+    private static void mockBoundsOnScreen(View view, Rect bounds) {
+        doAnswer(invocation -> {
+            Rect out = invocation.getArgument(0);
+            out.set(bounds);
+            return null;
+        }).when(view).getBoundsOnScreen(any());
+    }
+
+    private static MotionEvent transformEventForView(MotionEvent event, View view) {
+        // From `ViewGroup#dispatchTransformedTouchEvent`
+        MotionEvent transformed = event.copy();
+        transformed.offsetLocation(-view.getTop(), -view.getLeft());
+        return transformed;
+    }
+
+    private static MotionEvent createMotionEvent(float x, float y) {
+        return MotionEvent.obtain(
+                /* downTime= */0,
+                /* eventTime= */0,
+                MotionEvent.ACTION_DOWN,
+                x,
+                y,
+                /* metaState= */0
+        );
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderControllerTest.kt
index 01e9595..8066401 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderControllerTest.kt
@@ -1,8 +1,12 @@
 package com.android.systemui.statusbar.phone
 
 import android.app.StatusBarManager
+import android.content.Context
+import android.content.res.TypedArray
 import android.testing.AndroidTestingRunner
+import android.util.TypedValue.COMPLEX_UNIT_PX
 import android.view.View
+import android.widget.TextView
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
@@ -13,7 +17,9 @@
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.qs.HeaderPrivacyIconsController
+import com.android.systemui.qs.carrier.QSCarrierGroup
 import com.android.systemui.qs.carrier.QSCarrierGroupController
+import com.android.systemui.statusbar.policy.FakeConfigurationController
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Rule
@@ -22,6 +28,7 @@
 import org.mockito.ArgumentMatchers.any
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
+import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
@@ -36,19 +43,32 @@
     @Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController
     @Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
     @Mock private lateinit var featureFlags: FeatureFlags
+    @Mock private lateinit var clock: TextView
+    @Mock private lateinit var date: TextView
+    @Mock private lateinit var carrierGroup: QSCarrierGroup
     @Mock private lateinit var batteryMeterView: BatteryMeterView
     @Mock private lateinit var batteryMeterViewController: BatteryMeterViewController
     @Mock private lateinit var privacyIconsController: HeaderPrivacyIconsController
     @Mock private lateinit var dumpManager: DumpManager
 
+    @Mock private lateinit var mockedContext: Context
+    @Mock private lateinit var typedArray: TypedArray
+
     @JvmField @Rule val mockitoRule = MockitoJUnit.rule()
     var viewVisibility = View.GONE
 
     private lateinit var mLargeScreenShadeHeaderController: LargeScreenShadeHeaderController
     private lateinit var carrierIconSlots: List<String>
+    private val configurationController = FakeConfigurationController()
 
     @Before
     fun setup() {
+        whenever<TextView>(view.findViewById(R.id.clock)).thenReturn(clock)
+        whenever(clock.context).thenReturn(mockedContext)
+        whenever(mockedContext.obtainStyledAttributes(anyInt(), any())).thenReturn(typedArray)
+        whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date)
+        whenever(date.context).thenReturn(mockedContext)
+        whenever<QSCarrierGroup>(view.findViewById(R.id.carrier_group)).thenReturn(carrierGroup)
         whenever<BatteryMeterView>(view.findViewById(R.id.batteryRemainingIcon))
                 .thenReturn(batteryMeterView)
         whenever<StatusIconContainer>(view.findViewById(R.id.statusIcons)).thenReturn(statusIcons)
@@ -67,6 +87,7 @@
                 view,
                 statusBarIconController,
                 privacyIconsController,
+                configurationController,
                 qsCarrierGroupControllerBuilder,
                 featureFlags,
                 batteryMeterViewController,
@@ -138,4 +159,38 @@
         mLargeScreenShadeHeaderController.active = true
         mLargeScreenShadeHeaderController.shadeExpanded = true
     }
+
+    @Test
+    fun updateConfig_changesFontSize() {
+        val updatedTextPixelSize = 32
+        setReturnTextSize(updatedTextPixelSize)
+
+        configurationController.notifyDensityOrFontScaleChanged()
+
+        verify(clock).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize.toFloat())
+        verify(date).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize.toFloat())
+        verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status)
+    }
+
+    @Test
+    fun updateConfig_changesFontSizeMultipleTimes() {
+        val updatedTextPixelSize1 = 32
+        setReturnTextSize(updatedTextPixelSize1)
+        configurationController.notifyDensityOrFontScaleChanged()
+        verify(clock).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize1.toFloat())
+        verify(date).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize1.toFloat())
+        verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status)
+        clearInvocations(carrierGroup)
+
+        val updatedTextPixelSize2 = 42
+        setReturnTextSize(updatedTextPixelSize2)
+        configurationController.notifyDensityOrFontScaleChanged()
+        verify(clock).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize2.toFloat())
+        verify(date).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize2.toFloat())
+        verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status)
+    }
+
+    private fun setReturnTextSize(resultTextSize: Int) {
+        whenever(typedArray.getDimensionPixelSize(anyInt(), anyInt())).thenReturn(resultTextSize)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
index 05fb1f59..f51c428 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
@@ -56,6 +56,7 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewParent;
 import android.view.ViewPropertyAnimator;
 import android.view.ViewStub;
 import android.view.accessibility.AccessibilityManager;
@@ -99,6 +100,7 @@
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
 import com.android.systemui.screenrecord.RecordingController;
 import com.android.systemui.statusbar.CommandQueue;
@@ -334,6 +336,12 @@
     private NotificationStackSizeCalculator mNotificationStackSizeCalculator;
     @Mock
     private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
+    @Mock
+    private QS mQs;
+    @Mock
+    private View mQsHeader;
+    @Mock
+    private ViewParent mViewParent;
     private NotificationPanelViewController.PanelEventsEmitter mPanelEventsEmitter;
     private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
     private SysuiStatusBarStateController mStatusBarStateController;
@@ -344,6 +352,8 @@
     private FalsingManagerFake mFalsingManager = new FalsingManagerFake();
     private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
     private Handler mMainHandler;
+    private final PanelExpansionStateManager mPanelExpansionStateManager =
+            new PanelExpansionStateManager();
 
     @Before
     public void setup() {
@@ -455,6 +465,9 @@
             return null;
         }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
 
+        when(mView.getParent()).thenReturn(mViewParent);
+        when(mQs.getHeader()).thenReturn(mQsHeader);
+
         mMainHandler = new Handler(Looper.getMainLooper());
         mPanelEventsEmitter = new NotificationPanelViewController.PanelEventsEmitter();
 
@@ -505,7 +518,7 @@
                 mLargeScreenShadeHeaderController,
                 mScreenOffAnimationController,
                 mLockscreenGestureLogger,
-                new PanelExpansionStateManager(),
+                mPanelExpansionStateManager,
                 mNotificationRemoteInputManager,
                 mSysUIUnfoldComponent,
                 mControlsComponent,
@@ -547,6 +560,37 @@
     }
 
     @Test
+    public void computeMaxKeyguardNotifications_lockscreenToShade_returnsExistingMax() {
+        when(mAmbientState.getFractionToShade()).thenReturn(0.5f);
+        mNotificationPanelViewController.setMaxDisplayedNotifications(-1);
+
+        // computeMaxKeyguardNotifications sets maxAllowed to 0 at minimum if it updates the value
+        assertThat(mNotificationPanelViewController.computeMaxKeyguardNotifications())
+                .isEqualTo(-1);
+    }
+
+    @Test
+    public void computeMaxKeyguardNotifications_dozeAmountNotZero_returnsExistingMax() {
+        when(mAmbientState.getDozeAmount()).thenReturn(0.5f);
+        mNotificationPanelViewController.setMaxDisplayedNotifications(-1);
+
+        // computeMaxKeyguardNotifications sets maxAllowed to 0 at minimum if it updates the value
+        assertThat(mNotificationPanelViewController.computeMaxKeyguardNotifications())
+                .isEqualTo(-1);
+    }
+
+    @Test
+    public void computeMaxKeyguardNotifications_noTransition_updatesMax() {
+        when(mAmbientState.getFractionToShade()).thenReturn(0f);
+        when(mAmbientState.getDozeAmount()).thenReturn(0f);
+        mNotificationPanelViewController.setMaxDisplayedNotifications(-1);
+
+        // computeMaxKeyguardNotifications sets maxAllowed to 0 at minimum if it updates the value
+        assertThat(mNotificationPanelViewController.computeMaxKeyguardNotifications())
+                .isNotEqualTo(-1);
+    }
+
+    @Test
     public void testSetPanelScrimMinFraction() {
         mNotificationPanelViewController.setPanelScrimMinFraction(0.5f);
         verify(mNotificationShadeDepthController).setPanelPullDownMinFraction(eq(0.5f));
@@ -976,14 +1020,79 @@
     }
 
     @Test
-    public void testQsToBeImmediatelyExpandedInSplitShade() {
+    public void testQsToBeImmediatelyExpandedWhenOpeningPanelInSplitShade() {
         enableSplitShade(/* enabled= */ true);
+        // set panel state to CLOSED
+        mPanelExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 0,
+                /* expanded= */ false, /* tracking= */ false, /* dragDownPxAmount= */ 0);
+        assertThat(mNotificationPanelViewController.mQsExpandImmediate).isFalse();
 
-        mNotificationPanelViewController.onTrackingStarted();
+        // change panel state to OPENING
+        mPanelExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 0.5f,
+                /* expanded= */ true, /* tracking= */ true, /* dragDownPxAmount= */ 100);
 
         assertThat(mNotificationPanelViewController.mQsExpandImmediate).isTrue();
     }
 
+    @Test
+    public void testQsNotToBeImmediatelyExpandedWhenGoingFromUnlockedToLocked() {
+        enableSplitShade(/* enabled= */ true);
+        // set panel state to CLOSED
+        mPanelExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 0,
+                /* expanded= */ false, /* tracking= */ false, /* dragDownPxAmount= */ 0);
+
+        // go to lockscreen, which also sets fraction to 1.0f and makes shade "expanded"
+        mStatusBarStateController.setState(KEYGUARD);
+        mPanelExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1,
+                /* expanded= */ true, /* tracking= */ true, /* dragDownPxAmount= */ 0);
+
+        assertThat(mNotificationPanelViewController.mQsExpandImmediate).isFalse();
+    }
+
+    @Test
+    public void interceptTouchEvent_withinQs_shadeExpanded_startsQsTracking() {
+        mNotificationPanelViewController.mQs = mQs;
+        when(mQsFrame.getX()).thenReturn(0f);
+        when(mQsFrame.getWidth()).thenReturn(1000);
+        when(mQsHeader.getTop()).thenReturn(0);
+        when(mQsHeader.getBottom()).thenReturn(1000);
+        PanelViewController.TouchHandler touchHandler =
+                mNotificationPanelViewController.createTouchHandler();
+
+        mNotificationPanelViewController.setExpandedFraction(1f);
+        touchHandler.onInterceptTouchEvent(
+                createMotionEvent(/* x= */ 0, /* y= */ 0, MotionEvent.ACTION_DOWN));
+        touchHandler.onInterceptTouchEvent(
+                createMotionEvent(/* x= */ 0, /* y= */ 500, MotionEvent.ACTION_MOVE));
+
+        assertThat(mNotificationPanelViewController.isQsTracking()).isTrue();
+    }
+
+    @Test
+    public void interceptTouchEvent_withinQs_shadeExpanded_inSplitShade_doesNotStartQsTracking() {
+        enableSplitShade(true);
+        mNotificationPanelViewController.mQs = mQs;
+        when(mQsFrame.getX()).thenReturn(0f);
+        when(mQsFrame.getWidth()).thenReturn(1000);
+        when(mQsHeader.getTop()).thenReturn(0);
+        when(mQsHeader.getBottom()).thenReturn(1000);
+        PanelViewController.TouchHandler touchHandler =
+                mNotificationPanelViewController.createTouchHandler();
+
+        mNotificationPanelViewController.setExpandedFraction(1f);
+        touchHandler.onInterceptTouchEvent(
+                createMotionEvent(/* x= */ 0, /* y= */ 0, MotionEvent.ACTION_DOWN));
+        touchHandler.onInterceptTouchEvent(
+                createMotionEvent(/* x= */ 0, /* y= */ 500, MotionEvent.ACTION_MOVE));
+
+        assertThat(mNotificationPanelViewController.isQsTracking()).isFalse();
+    }
+
+    private static MotionEvent createMotionEvent(int x, int y, int action) {
+        return MotionEvent.obtain(
+                /* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0);
+    }
+
     private void triggerPositionClockAndNotifications() {
         mNotificationPanelViewController.closeQs();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 2b01872..aaa5a6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -50,6 +50,7 @@
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -60,7 +61,9 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.util.Optional;
@@ -70,80 +73,63 @@
 @TestableLooper.RunWithLooper
 public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
 
-    @Mock
-    private ViewMediatorCallback mViewMediatorCallback;
-    @Mock
-    private LockPatternUtils mLockPatternUtils;
-    @Mock
-    private KeyguardStateController mKeyguardStateController;
-    @Mock
-    private CentralSurfaces mCentralSurfaces;
-    @Mock
-    private ViewGroup mContainer;
-    @Mock
-    private NotificationPanelViewController mNotificationPanelView;
-    @Mock
-    private BiometricUnlockController mBiometricUnlockController;
-    @Mock
-    private SysuiStatusBarStateController mStatusBarStateController;
-    @Mock
-    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    @Mock
-    private View mNotificationContainer;
-    @Mock
-    private KeyguardBypassController mBypassController;
-    @Mock
-    private KeyguardBouncer.Factory mKeyguardBouncerFactory;
-    @Mock
-    private KeyguardMessageAreaController.Factory mKeyguardMessageAreaFactory;
-    @Mock
-    private KeyguardMessageAreaController mKeyguardMessageAreaController;
-    @Mock
-    private KeyguardBouncer mBouncer;
-    @Mock
-    private StatusBarKeyguardViewManager.AlternateAuthInterceptor mAlternateAuthInterceptor;
-    @Mock
-    private KeyguardMessageArea mKeyguardMessageArea;
-    @Mock
-    private ShadeController mShadeController;
-    @Mock
-    private SysUIUnfoldComponent mSysUiUnfoldComponent;
-    @Mock
-    private DreamOverlayStateController mDreamOverlayStateController;
-    @Mock
-    private LatencyTracker mLatencyTracker;
+    private static final PanelExpansionChangeEvent EXPANSION_EVENT =
+            expansionEvent(/* fraction= */ 0.5f, /* expanded= */ false, /* tracking= */ true);
+
+    @Mock private ViewMediatorCallback mViewMediatorCallback;
+    @Mock private LockPatternUtils mLockPatternUtils;
+    @Mock private KeyguardStateController mKeyguardStateController;
+    @Mock private CentralSurfaces mCentralSurfaces;
+    @Mock private ViewGroup mContainer;
+    @Mock private NotificationPanelViewController mNotificationPanelView;
+    @Mock private BiometricUnlockController mBiometricUnlockController;
+    @Mock private SysuiStatusBarStateController mStatusBarStateController;
+    @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    @Mock private View mNotificationContainer;
+    @Mock private KeyguardBypassController mBypassController;
+    @Mock private KeyguardBouncer.Factory mKeyguardBouncerFactory;
+    @Mock private KeyguardMessageAreaController.Factory mKeyguardMessageAreaFactory;
+    @Mock private KeyguardMessageAreaController mKeyguardMessageAreaController;
+    @Mock private KeyguardBouncer mBouncer;
+    @Mock private StatusBarKeyguardViewManager.AlternateAuthInterceptor mAlternateAuthInterceptor;
+    @Mock private KeyguardMessageArea mKeyguardMessageArea;
+    @Mock private ShadeController mShadeController;
+    @Mock private SysUIUnfoldComponent mSysUiUnfoldComponent;
+    @Mock private DreamOverlayStateController mDreamOverlayStateController;
+    @Mock private LatencyTracker mLatencyTracker;
 
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private KeyguardBouncer.BouncerExpansionCallback mBouncerExpansionCallback;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mKeyguardBouncerFactory.create(
-                any(ViewGroup.class),
-                any(KeyguardBouncer.BouncerExpansionCallback.class)))
+                        any(ViewGroup.class), any(KeyguardBouncer.BouncerExpansionCallback.class)))
                 .thenReturn(mBouncer);
         when(mCentralSurfaces.getBouncerContainer()).thenReturn(mContainer);
         when(mContainer.findViewById(anyInt())).thenReturn(mKeyguardMessageArea);
         when(mKeyguardMessageAreaFactory.create(any(KeyguardMessageArea.class)))
                 .thenReturn(mKeyguardMessageAreaController);
-        mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(
-                getContext(),
-                mViewMediatorCallback,
-                mLockPatternUtils,
-                mStatusBarStateController,
-                mock(ConfigurationController.class),
-                mKeyguardUpdateMonitor,
-                mDreamOverlayStateController,
-                mock(NavigationModeController.class),
-                mock(DockManager.class),
-                mock(NotificationShadeWindowController.class),
-                mKeyguardStateController,
-                mock(NotificationMediaManager.class),
-                mKeyguardBouncerFactory,
-                mKeyguardMessageAreaFactory,
-                Optional.of(mSysUiUnfoldComponent),
-                () -> mShadeController,
-                mLatencyTracker);
+        mStatusBarKeyguardViewManager =
+                new StatusBarKeyguardViewManager(
+                        getContext(),
+                        mViewMediatorCallback,
+                        mLockPatternUtils,
+                        mStatusBarStateController,
+                        mock(ConfigurationController.class),
+                        mKeyguardUpdateMonitor,
+                        mDreamOverlayStateController,
+                        mock(NavigationModeController.class),
+                        mock(DockManager.class),
+                        mock(NotificationShadeWindowController.class),
+                        mKeyguardStateController,
+                        mock(NotificationMediaManager.class),
+                        mKeyguardBouncerFactory,
+                        mKeyguardMessageAreaFactory,
+                        Optional.of(mSysUiUnfoldComponent),
+                        () -> mShadeController,
+                        mLatencyTracker);
         mStatusBarKeyguardViewManager.registerCentralSurfaces(
                 mCentralSurfaces,
                 mNotificationPanelView,
@@ -153,14 +139,19 @@
                 mBypassController);
         when(mKeyguardStateController.isOccluded()).thenReturn(false);
         mStatusBarKeyguardViewManager.show(null);
+        ArgumentCaptor<KeyguardBouncer.BouncerExpansionCallback> callbackArgumentCaptor =
+                ArgumentCaptor.forClass(KeyguardBouncer.BouncerExpansionCallback.class);
+        verify(mKeyguardBouncerFactory).create(any(ViewGroup.class),
+                callbackArgumentCaptor.capture());
+        mBouncerExpansionCallback = callbackArgumentCaptor.getValue();
     }
 
     @Test
     public void dismissWithAction_AfterKeyguardGoneSetToFalse() {
         OnDismissAction action = () -> false;
         Runnable cancelAction = () -> {};
-        mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
-                false /* afterKeyguardGone */);
+        mStatusBarKeyguardViewManager.dismissWithAction(
+                action, cancelAction, false /* afterKeyguardGone */);
         verify(mBouncer).showWithDismissAction(eq(action), eq(cancelAction));
     }
 
@@ -191,67 +182,55 @@
     public void onPanelExpansionChanged_neverHidesScrimmedBouncer() {
         when(mBouncer.isShowing()).thenReturn(true);
         when(mBouncer.isScrimmed()).thenReturn(true);
-        mStatusBarKeyguardViewManager.onPanelExpansionChanged(
-                /* fraction= */ 0.5f,
-                /* expanded= */ false,
-                /* tracking= */ true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
         verify(mBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_VISIBLE));
     }
 
     @Test
     public void onPanelExpansionChanged_neverShowsDuringHintAnimation() {
         when(mNotificationPanelView.isUnlockHintRunning()).thenReturn(true);
-        mStatusBarKeyguardViewManager.onPanelExpansionChanged(
-                /* fraction= */ 0.5f,
-                /* expanded= */ false,
-                /* tracking= */ true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
         verify(mBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_HIDDEN));
     }
 
     @Test
     public void onPanelExpansionChanged_propagatesToBouncer() {
-        mStatusBarKeyguardViewManager.onPanelExpansionChanged(
-                /* fraction= */ 0.5f,
-                /* expanded= */ false,
-                /* tracking= */ true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
         verify(mBouncer).setExpansion(eq(0.5f));
     }
 
     @Test
+    public void onPanelExpansionChanged_propagatesToBouncer_evenAfterHidden() {
+        mStatusBarKeyguardViewManager.hide(0, 0);
+        when(mBouncer.inTransit()).thenReturn(true);
+
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
+        verify(mBouncer).setExpansion(eq(EXPANSION_EVENT.getFraction()));
+    }
+
+    @Test
     public void onPanelExpansionChanged_showsBouncerWhenSwiping() {
         when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false);
-        mStatusBarKeyguardViewManager.onPanelExpansionChanged(
-                /* fraction= */ 0.5f,
-                /* expanded= */ false,
-                /* tracking= */ true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
         verify(mBouncer).show(eq(false), eq(false));
 
         // But not when it's already visible
         reset(mBouncer);
         when(mBouncer.isShowing()).thenReturn(true);
-        mStatusBarKeyguardViewManager.onPanelExpansionChanged(
-                /* fraction= */ 0.5f,
-                /* expanded= */ false,
-                /* tracking= */ true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
         verify(mBouncer, never()).show(eq(false), eq(false));
 
         // Or animating away
         reset(mBouncer);
         when(mBouncer.isAnimatingAway()).thenReturn(true);
-        mStatusBarKeyguardViewManager.onPanelExpansionChanged(
-                /* fraction= */ 0.5f,
-                /* expanded= */ false,
-                /* tracking= */ true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
         verify(mBouncer, never()).show(eq(false), eq(false));
     }
 
     @Test
     public void onPanelExpansionChanged_neverTranslatesBouncerWhenOccluded() {
         mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animate */);
-        mStatusBarKeyguardViewManager.onPanelExpansionChanged(
-                /* fraction= */ 0.5f,
-                /* expanded= */ false,
-                /* tracking= */ true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
         verify(mBouncer, never()).setExpansion(eq(0.5f));
     }
 
@@ -260,9 +239,10 @@
         when(mBiometricUnlockController.getMode())
                 .thenReturn(BiometricUnlockController.MODE_WAKE_AND_UNLOCK);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
-                /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
-                /* expanded= */ true,
-                /* tracking= */ false);
+                expansionEvent(
+                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* expanded= */ true,
+                        /* tracking= */ false));
         verify(mBouncer, never()).setExpansion(anyFloat());
     }
 
@@ -270,9 +250,10 @@
     public void onPanelExpansionChanged_neverTranslatesBouncerWhenLaunchingApp() {
         when(mCentralSurfaces.isInLaunchTransition()).thenReturn(true);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
-                /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
-                /* expanded= */ true,
-                /* tracking= */ false);
+                expansionEvent(
+                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* expanded= */ true,
+                        /* tracking= */ false));
         verify(mBouncer, never()).setExpansion(anyFloat());
     }
 
@@ -336,8 +317,8 @@
     public void testHiding_cancelsGoneRunnable() {
         OnDismissAction action = mock(OnDismissAction.class);
         Runnable cancelAction = mock(Runnable.class);
-        mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
-                true /* afterKeyguardGone */);
+        mStatusBarKeyguardViewManager.dismissWithAction(
+                action, cancelAction, true /* afterKeyguardGone */);
 
         mStatusBarKeyguardViewManager.hideBouncer(true);
         mStatusBarKeyguardViewManager.hide(0, 30);
@@ -349,8 +330,8 @@
     public void testHiding_doesntCancelWhenShowing() {
         OnDismissAction action = mock(OnDismissAction.class);
         Runnable cancelAction = mock(Runnable.class);
-        mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
-                true /* afterKeyguardGone */);
+        mStatusBarKeyguardViewManager.dismissWithAction(
+                action, cancelAction, true /* afterKeyguardGone */);
 
         mStatusBarKeyguardViewManager.hide(0, 30);
         verify(action).onDismiss();
@@ -362,7 +343,8 @@
         mStatusBarKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
         when(mBouncer.isShowing()).thenReturn(false);
         when(mAlternateAuthInterceptor.isShowingAlternateAuthBouncer()).thenReturn(true);
-        assertTrue("Is showing not accurate when alternative auth showing",
+        assertTrue(
+                "Is showing not accurate when alternative auth showing",
                 mStatusBarKeyguardViewManager.isShowing());
     }
 
@@ -371,7 +353,8 @@
         mStatusBarKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
         when(mBouncer.isShowing()).thenReturn(false);
         when(mAlternateAuthInterceptor.isShowingAlternateAuthBouncer()).thenReturn(true);
-        assertTrue("Is or will be showing not accurate when alternative auth showing",
+        assertTrue(
+                "Is or will be showing not accurate when alternative auth showing",
                 mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing());
     }
 
@@ -412,8 +395,7 @@
         // GIVEN alt auth exists, unlocking with biometric is allowed
         mStatusBarKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
         when(mBouncer.isShowing()).thenReturn(false);
-        when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
-                .thenReturn(true);
+        when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
 
         // WHEN showGenericBouncer is called
         mStatusBarKeyguardViewManager.showGenericBouncer(true);
@@ -446,4 +428,30 @@
         mBouncer = null;
         Truth.assertThat(mStatusBarKeyguardViewManager.isBouncerInTransit()).isFalse();
     }
+
+    private static PanelExpansionChangeEvent expansionEvent(
+            float fraction, boolean expanded, boolean tracking) {
+        return new PanelExpansionChangeEvent(
+                fraction, expanded, tracking, /* dragDownPxAmount= */ 0f);
+    }
+
+    @Test
+    public void testReportBouncerOnDreamWhenVisible() {
+        mBouncerExpansionCallback.onVisibilityChanged(true);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(false);
+        Mockito.clearInvocations(mCentralSurfaces);
+        when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
+        mBouncerExpansionCallback.onVisibilityChanged(true);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(true);
+    }
+
+    @Test
+    public void testReportBouncerOnDreamWhenNotVisible() {
+        mBouncerExpansionCallback.onVisibilityChanged(false);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(false);
+        Mockito.clearInvocations(mCentralSurfaces);
+        when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
+        mBouncerExpansionCallback.onVisibilityChanged(false);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(false);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt
index 1ce7ff4..1779de7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt
@@ -61,6 +61,15 @@
     }
 
     @Test
+    fun onStatusBarWidthChangedWithNoTransitionBefore_noTranslation() {
+        controller.onViewsReady(arrayOf(view))
+
+        controller.onStatusBarWidthChanged()
+
+        assertThat(view.translationX).isZero()
+    }
+
+    @Test
     fun onTransitionProgress_updatesTranslations() {
         controller.onViewsReady(arrayOf(view))
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManagerTest.kt
index 32bad5c..c4f8049 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManagerTest.kt
@@ -39,12 +39,15 @@
         val fraction = 0.6f
         val expanded = true
         val tracking = true
+        val dragDownAmount = 1234f
 
-        panelExpansionStateManager.onPanelExpansionChanged(fraction, expanded, tracking)
+        panelExpansionStateManager.onPanelExpansionChanged(
+            fraction, expanded, tracking, dragDownAmount)
 
         assertThat(listener.fraction).isEqualTo(fraction)
         assertThat(listener.expanded).isEqualTo(expanded)
         assertThat(listener.tracking).isEqualTo(tracking)
+        assertThat(listener.dragDownAmountPx).isEqualTo(dragDownAmount)
     }
 
     @Test
@@ -52,7 +55,9 @@
         val fraction = 0.6f
         val expanded = true
         val tracking = true
-        panelExpansionStateManager.onPanelExpansionChanged(fraction, expanded, tracking)
+        val dragDownAmount = 1234f
+        panelExpansionStateManager.onPanelExpansionChanged(
+            fraction, expanded, tracking, dragDownAmount)
         val listener = TestPanelExpansionListener()
 
         panelExpansionStateManager.addExpansionListener(listener)
@@ -60,6 +65,7 @@
         assertThat(listener.fraction).isEqualTo(fraction)
         assertThat(listener.expanded).isEqualTo(expanded)
         assertThat(listener.tracking).isEqualTo(tracking)
+        assertThat(listener.dragDownAmountPx).isEqualTo(dragDownAmount)
     }
 
     @Test
@@ -82,8 +88,7 @@
         panelExpansionStateManager.addStateListener(listener)
 
         panelExpansionStateManager.onPanelExpansionChanged(
-            fraction = 0.5f, expanded = true, tracking = false
-        )
+            fraction = 0.5f, expanded = true, tracking = false, dragDownPxAmount = 0f)
 
         assertThat(listener.state).isEqualTo(STATE_OPENING)
     }
@@ -94,8 +99,7 @@
         panelExpansionStateManager.addStateListener(listener)
 
         panelExpansionStateManager.onPanelExpansionChanged(
-            fraction = 0.5f, expanded = true, tracking = true
-        )
+            fraction = 0.5f, expanded = true, tracking = true, dragDownPxAmount = 0f)
 
         assertThat(listener.state).isEqualTo(STATE_OPENING)
     }
@@ -108,8 +112,7 @@
         panelExpansionStateManager.updateState(STATE_OPEN)
 
         panelExpansionStateManager.onPanelExpansionChanged(
-            fraction = 0.5f, expanded = false, tracking = false
-        )
+            fraction = 0.5f, expanded = false, tracking = false, dragDownPxAmount = 0f)
 
         assertThat(listener.state).isEqualTo(STATE_CLOSED)
     }
@@ -122,8 +125,7 @@
         panelExpansionStateManager.updateState(STATE_OPEN)
 
         panelExpansionStateManager.onPanelExpansionChanged(
-            fraction = 0.5f, expanded = false, tracking = true
-        )
+            fraction = 0.5f, expanded = false, tracking = true, dragDownPxAmount = 0f)
 
         assertThat(listener.state).isEqualTo(STATE_OPEN)
     }
@@ -136,8 +138,7 @@
         panelExpansionStateManager.addStateListener(listener)
 
         panelExpansionStateManager.onPanelExpansionChanged(
-            fraction = 1f, expanded = true, tracking = false
-        )
+            fraction = 1f, expanded = true, tracking = false, dragDownPxAmount = 0f)
 
         assertThat(listener.previousState).isEqualTo(STATE_OPENING)
         assertThat(listener.state).isEqualTo(STATE_OPEN)
@@ -149,8 +150,7 @@
         panelExpansionStateManager.addStateListener(listener)
 
         panelExpansionStateManager.onPanelExpansionChanged(
-            fraction = 1f, expanded = true, tracking = true
-        )
+            fraction = 1f, expanded = true, tracking = true, dragDownPxAmount = 0f)
 
         assertThat(listener.state).isEqualTo(STATE_OPENING)
     }
@@ -163,8 +163,7 @@
         panelExpansionStateManager.updateState(STATE_OPEN)
 
         panelExpansionStateManager.onPanelExpansionChanged(
-            fraction = 1f, expanded = false, tracking = false
-        )
+            fraction = 1f, expanded = false, tracking = false, dragDownPxAmount = 0f)
 
         assertThat(listener.state).isEqualTo(STATE_CLOSED)
     }
@@ -177,8 +176,7 @@
         panelExpansionStateManager.updateState(STATE_OPEN)
 
         panelExpansionStateManager.onPanelExpansionChanged(
-            fraction = 1f, expanded = false, tracking = true
-        )
+            fraction = 1f, expanded = false, tracking = true, dragDownPxAmount = 0f)
 
         assertThat(listener.state).isEqualTo(STATE_OPEN)
     }
@@ -189,15 +187,13 @@
         var fraction: Float = 0f
         var expanded: Boolean = false
         var tracking: Boolean = false
+        var dragDownAmountPx: Float = 0f
 
-        override fun onPanelExpansionChanged(
-            fraction: Float,
-            expanded: Boolean,
-            tracking: Boolean
-        ) {
-            this.fraction = fraction
-            this.expanded = expanded
-            this.tracking = tracking
+        override fun onPanelExpansionChanged(event: PanelExpansionChangeEvent) {
+            this.fraction = event.fraction
+            this.expanded = event.expanded
+            this.tracking = event.tracking
+            this.dragDownAmountPx = event.dragDownPxAmount
         }
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt
index 146b56e..16a3268 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt
@@ -23,6 +23,10 @@
         listeners.forEach { it.onThemeChanged() }
     }
 
+    fun notifyDensityOrFontScaleChanged() {
+        listeners.forEach { it.onDensityOrFontScaleChanged() }
+    }
+
     fun notifyConfigurationChanged() {
         onConfigurationChanged(newConfiguration = null)
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
index 152815f..e0bf9e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
@@ -19,6 +19,7 @@
 import android.app.IActivityManager
 import android.app.NotificationManager
 import android.app.admin.DevicePolicyManager
+import android.content.BroadcastReceiver
 import android.content.Context
 import android.content.DialogInterface
 import android.content.Intent
@@ -55,6 +56,10 @@
 import com.android.systemui.statusbar.phone.NotificationShadeWindowView
 import com.android.systemui.telephony.TelephonyListenerManager
 import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.settings.GlobalSettings
 import com.android.systemui.util.settings.SecureSettings
 import com.android.systemui.util.time.FakeSystemClock
@@ -66,10 +71,8 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mock
 import org.mockito.Mockito.`when`
-import org.mockito.Mockito.any
 import org.mockito.Mockito.doNothing
 import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.eq
@@ -561,4 +564,20 @@
         setupController()
         assertFalse(userSwitcherController.canCreateSupervisedUser())
     }
+
+    @Test
+    fun addUserSwitchCallback() {
+        val broadcastReceiverCaptor = argumentCaptor<BroadcastReceiver>()
+        verify(broadcastDispatcher).registerReceiver(
+                capture(broadcastReceiverCaptor),
+                any(),
+                nullable(), nullable(), anyInt(), nullable())
+
+        val cb = mock(UserSwitcherController.UserSwitchCallback::class.java)
+        userSwitcherController.addUserSwitchCallback(cb)
+
+        val intent = Intent(Intent.ACTION_USER_SWITCHED).putExtra(Intent.EXTRA_USER_HANDLE, guestId)
+        broadcastReceiverCaptor.value.onReceive(context, intent)
+        verify(cb).onUserSwitched()
+    }
 }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 8c4db70..aa5c501 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -805,12 +805,13 @@
      * Updates the last fill response when a dataset was selected.
      */
     void logDatasetSelected(@Nullable String selectedDataset, int sessionId,
-            @Nullable Bundle clientState) {
+            @Nullable Bundle clientState,  int presentationType) {
         synchronized (mLock) {
             if (isValidEventLocked("logDatasetSelected()", sessionId)) {
                 mEventHistory.addEvent(
                         new Event(Event.TYPE_DATASET_SELECTED, selectedDataset, clientState, null,
-                                null, null, null, null, null, null, null));
+                                null, null, null, null, null, null, null, NO_SAVE_UI_REASON_NONE,
+                                presentationType));
             }
         }
     }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 7e277ba..f18d13d 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -21,6 +21,7 @@
 import static android.service.autofill.FillEventHistory.Event.UI_TYPE_DIALOG;
 import static android.service.autofill.FillEventHistory.Event.UI_TYPE_INLINE;
 import static android.service.autofill.FillEventHistory.Event.UI_TYPE_MENU;
+import static android.service.autofill.FillEventHistory.Event.UI_TYPE_UNKNOWN;
 import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
 import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE;
 import static android.service.autofill.FillRequest.FLAG_SUPPORTS_FILL_DIALOG;
@@ -1406,7 +1407,7 @@
 
     // AutoFillUiCallback
     @Override
-    public void fill(int requestId, int datasetIndex, Dataset dataset) {
+    public void fill(int requestId, int datasetIndex, Dataset dataset, int uiType) {
         synchronized (mLock) {
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#fill() rejected - session: "
@@ -1416,7 +1417,7 @@
         }
         mHandler.sendMessage(obtainMessage(
                 Session::autoFill,
-                this, requestId, datasetIndex, dataset, true));
+                this, requestId, datasetIndex, dataset, true, uiType));
     }
 
     // AutoFillUiCallback
@@ -1657,7 +1658,7 @@
                 if (!isAuthResultDatasetEphemeral(oldDataset, data)) {
                     authenticatedResponse.getDatasets().set(datasetIdx, dataset);
                 }
-                autoFill(requestId, datasetIdx, dataset, false);
+                autoFill(requestId, datasetIdx, dataset, false, UI_TYPE_UNKNOWN);
             } else {
                 Slog.w(TAG, "invalid index (" + datasetIdx + ") for authentication id "
                         + authenticationId);
@@ -3376,7 +3377,7 @@
                 new InlineFillUi.InlineSuggestionUiCallback() {
                     @Override
                     public void autofill(@NonNull Dataset dataset, int datasetIndex) {
-                        fill(response.getRequestId(), datasetIndex, dataset);
+                        fill(response.getRequestId(), datasetIndex, dataset, UI_TYPE_INLINE);
                     }
 
                     @Override
@@ -3895,7 +3896,8 @@
         return viewState;
     }
 
-    void autoFill(int requestId, int datasetIndex, Dataset dataset, boolean generateEvent) {
+    void autoFill(int requestId, int datasetIndex, Dataset dataset, boolean generateEvent,
+            int uiType) {
         if (sDebug) {
             Slog.d(TAG, "autoFill(): requestId=" + requestId  + "; datasetIdx=" + datasetIndex
                     + "; dataset=" + dataset);
@@ -3909,7 +3911,7 @@
             // Autofill it directly...
             if (dataset.getAuthentication() == null) {
                 if (generateEvent) {
-                    mService.logDatasetSelected(dataset.getId(), id, mClientState);
+                    mService.logDatasetSelected(dataset.getId(), id, mClientState, uiType);
                 }
                 if (mCurrentViewId != null) {
                     mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId);
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 056ab92..57768ef 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -15,6 +15,9 @@
  */
 package com.android.server.autofill.ui;
 
+import static android.service.autofill.FillEventHistory.Event.UI_TYPE_DIALOG;
+import static android.service.autofill.FillEventHistory.Event.UI_TYPE_MENU;
+
 import static com.android.server.autofill.Helper.sDebug;
 import static com.android.server.autofill.Helper.sVerbose;
 
@@ -31,6 +34,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.service.autofill.Dataset;
+import android.service.autofill.FillEventHistory;
 import android.service.autofill.FillResponse;
 import android.service.autofill.SaveInfo;
 import android.service.autofill.ValueFinder;
@@ -81,7 +85,8 @@
     public interface AutoFillUiCallback {
         void authenticate(int requestId, int datasetIndex, @NonNull IntentSender intent,
                 @Nullable Bundle extras, boolean authenticateInline);
-        void fill(int requestId, int datasetIndex, @NonNull Dataset dataset);
+        void fill(int requestId, int datasetIndex, @NonNull Dataset dataset,
+                @FillEventHistory.Event.UiType int uiType);
         void save();
         void cancelSave();
         void requestShowFillUi(AutofillId id, int width, int height,
@@ -236,7 +241,8 @@
                     hideFillUiUiThread(callback, true);
                     if (mCallback != null) {
                         final int datasetIndex = response.getDatasets().indexOf(dataset);
-                        mCallback.fill(response.getRequestId(), datasetIndex, dataset);
+                        mCallback.fill(response.getRequestId(), datasetIndex,
+                                dataset, UI_TYPE_MENU);
                     }
                 }
 
@@ -414,7 +420,8 @@
                             hideFillDialogUiThread(callback);
                             if (mCallback != null) {
                                 final int datasetIndex = response.getDatasets().indexOf(dataset);
-                                mCallback.fill(response.getRequestId(), datasetIndex, dataset);
+                                mCallback.fill(response.getRequestId(), datasetIndex, dataset,
+                                        UI_TYPE_DIALOG);
                             }
                         }
 
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 8b48d0f..fbf6482 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -143,10 +143,12 @@
             "android.hardware.media.omx@1.0::IOmx",
             "android.hardware.media.omx@1.0::IOmxStore",
             "android.hardware.neuralnetworks@1.0::IDevice",
+            "android.hardware.power@1.0::IPower",
             "android.hardware.power.stats@1.0::IPowerStats",
             "android.hardware.sensors@1.0::ISensors",
             "android.hardware.sensors@2.0::ISensors",
             "android.hardware.sensors@2.1::ISensors",
+            "android.hardware.vibrator@1.0::IVibrator",
             "android.hardware.vr@1.0::IVr",
             "android.system.suspend@1.0::ISystemSuspend"
     );
@@ -155,7 +157,10 @@
             "android.hardware.biometrics.face.IFace/",
             "android.hardware.biometrics.fingerprint.IFingerprint/",
             "android.hardware.light.ILights/",
+            "android.hardware.power.IPower/",
             "android.hardware.power.stats.IPowerStats/",
+            "android.hardware.vibrator.IVibrator/",
+            "android.hardware.vibrator.IVibratorManager/"
     };
 
     private static Watchdog sWatchdog;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 99cd760..1ebdb84 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8703,7 +8703,9 @@
         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
 
         // Check if we should rate limit and abort early if needed.
-        if (mDropboxRateLimiter.shouldRateLimit(eventType, processName)) return;
+        final DropboxRateLimiter.RateLimitResult rateLimitResult =
+                mDropboxRateLimiter.shouldRateLimit(eventType, processName);
+        if (rateLimitResult.shouldRateLimit()) return;
 
         final StringBuilder sb = new StringBuilder(1024);
         appendDropBoxProcessHeaders(process, processName, sb);
@@ -8752,6 +8754,8 @@
                         millisSinceOldestPendingRead).append("\n");
             }
         }
+        sb.append("Dropped-Count: ").append(
+                rateLimitResult.droppedCountSinceRateLimitActivated()).append("\n");
         sb.append("\n");
 
         // Do the rest in a worker thread to avoid blocking the caller on I/O
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 6fa13eb..6e28d8f 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -276,7 +276,9 @@
                         AppBackgroundRestrictionsInfo.REASON_UNKNOWN, // ExemptionReason
                         AppBackgroundRestrictionsInfo.UNKNOWN, // OptimizationLevel
                         AppBackgroundRestrictionsInfo.SDK_UNKNOWN, // TargetSdk
-                        isLowRamDeviceStatic());
+                        isLowRamDeviceStatic(),
+                        AppBackgroundRestrictionsInfo.LEVEL_UNKNOWN // previous RestrictionLevel
+                );
             }
         }
     }
@@ -287,7 +289,10 @@
      */
     @Override
     byte[] getTrackerInfoForStatsd(int uid) {
-        final ImmutableBatteryUsage temp = mUidBatteryUsageInWindow.get(uid);
+        final ImmutableBatteryUsage temp;
+        synchronized (mLock) {
+            temp = mUidBatteryUsageInWindow.get(uid);
+        }
         if (temp == null) {
             return null;
         }
@@ -301,11 +306,17 @@
                 bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_BACKGROUND];
         final double usageFgs =
                 bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_FOREGROUND_SERVICE];
+        final double usageForeground =
+                bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_FOREGROUND];
+        final double usageCached =
+                bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_CACHED];
         if (DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE) {
             Slog.d(TAG, "getBatteryTrackerInfoProtoLocked uid:" + uid
                     + " allUsage:" + String.format("%4.2f%%", allUsage)
                     + " usageBackground:" + String.format("%4.2f%%", usageBackground)
-                    + " usageFgs:" + String.format("%4.2f%%", usageFgs));
+                    + " usageFgs:" + String.format("%4.2f%%", usageFgs)
+                    + " usageForeground:" + String.format("%4.2f%%", usageForeground)
+                    + " usageCached:" + String.format("%4.2f%%", usageCached));
         }
         final ProtoOutputStream proto = new ProtoOutputStream();
         proto.write(AppBackgroundRestrictionsInfo.BatteryTrackerInfo.BATTERY_24H,
@@ -314,6 +325,10 @@
                 usageBackground * 10000);
         proto.write(AppBackgroundRestrictionsInfo.BatteryTrackerInfo.BATTERY_USAGE_FGS,
                 usageFgs * 10000);
+        proto.write(AppBackgroundRestrictionsInfo.BatteryTrackerInfo.BATTERY_USAGE_FOREGROUND,
+                usageForeground * 10000);
+        proto.write(AppBackgroundRestrictionsInfo.BatteryTrackerInfo.BATTERY_USAGE_CACHED,
+                usageCached * 10000);
         proto.flush();
         return proto.getBytes();
     }
@@ -1673,6 +1688,7 @@
                 if (pair != null) {
                     final long[] ts = pair.first;
                     final int restrictedLevel = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] > 0
+                            && mTracker.mAppRestrictionController.isAutoRestrictAbusiveAppEnabled()
                             ? RESTRICTION_LEVEL_RESTRICTED_BUCKET
                             : RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
                     if (maxLevel > RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) {
diff --git a/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java b/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java
index 9bed077..f944322 100644
--- a/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java
+++ b/services/core/java/com/android/server/am/AppBindServiceEventsTracker.java
@@ -24,6 +24,9 @@
 import android.annotation.NonNull;
 import android.app.ActivityManagerInternal.BindServiceEventListener;
 import android.content.Context;
+import android.os.AppBackgroundRestrictionsInfo;
+import android.os.SystemClock;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.server.am.AppBindServiceEventsTracker.AppBindServiceEventsPolicy;
 import com.android.server.am.AppRestrictionController.TrackerType;
@@ -82,6 +85,22 @@
     }
 
     @Override
+    byte[] getTrackerInfoForStatsd(int uid) {
+        final long now = SystemClock.elapsedRealtime();
+        final int numOfBindRequests = getTotalEventsLocked(uid, now);
+        if (numOfBindRequests == 0) {
+            // Not interested.
+            return null;
+        }
+        final ProtoOutputStream proto = new ProtoOutputStream();
+        proto.write(
+                AppBackgroundRestrictionsInfo.BindServiceEventsTrackerInfo.BIND_SERVICE_REQUESTS,
+                numOfBindRequests);
+        proto.flush();
+        return proto.getBytes();
+    }
+
+    @Override
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix);
         pw.println("APP BIND SERVICE EVENT TRACKER:");
diff --git a/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java b/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java
index a9155a1..b509008f 100644
--- a/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java
+++ b/services/core/java/com/android/server/am/AppBroadcastEventsTracker.java
@@ -24,6 +24,9 @@
 import android.annotation.NonNull;
 import android.app.ActivityManagerInternal.BroadcastEventListener;
 import android.content.Context;
+import android.os.AppBackgroundRestrictionsInfo;
+import android.os.SystemClock;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.server.am.AppBroadcastEventsTracker.AppBroadcastEventsPolicy;
 import com.android.server.am.AppRestrictionController.TrackerType;
@@ -81,6 +84,21 @@
     }
 
     @Override
+    byte[] getTrackerInfoForStatsd(int uid) {
+        final long now = SystemClock.elapsedRealtime();
+        final int numOfBroadcasts = getTotalEventsLocked(uid, now);
+        if (numOfBroadcasts == 0) {
+            // Not interested.
+            return null;
+        }
+        final ProtoOutputStream proto = new ProtoOutputStream();
+        proto.write(AppBackgroundRestrictionsInfo.BroadcastEventsTrackerInfo.BROADCASTS_SENT,
+                numOfBroadcasts);
+        proto.flush();
+        return proto.getBytes();
+    }
+
+    @Override
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix);
         pw.println("APP BROADCAST EVENT TRACKER:");
diff --git a/services/core/java/com/android/server/am/AppFGSTracker.java b/services/core/java/com/android/server/am/AppFGSTracker.java
index ddd2764..50515cd 100644
--- a/services/core/java/com/android/server/am/AppFGSTracker.java
+++ b/services/core/java/com/android/server/am/AppFGSTracker.java
@@ -35,6 +35,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ServiceInfo.ForegroundServiceType;
+import android.os.AppBackgroundRestrictionsInfo;
 import android.os.Handler;
 import android.os.Message;
 import android.os.PowerExemptionManager.ReasonCode;
@@ -49,6 +50,7 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -516,6 +518,12 @@
                 foregroundServiceTypeToIndex(FOREGROUND_SERVICE_TYPE_NONE));
     }
 
+    @Override
+    long getTotalDurations(int uid, long now) {
+        return getTotalDurations(uid, now,
+                foregroundServiceTypeToIndex(FOREGROUND_SERVICE_TYPE_NONE));
+    }
+
     boolean hasForegroundServices(String packageName, int uid) {
         synchronized (mLock) {
             final PackageDurations pkg = mPkgEvents.get(uid, packageName);
@@ -562,6 +570,21 @@
     }
 
     @Override
+    byte[] getTrackerInfoForStatsd(int uid) {
+        final long fgsDurations = getTotalDurations(uid, SystemClock.elapsedRealtime());
+        if (fgsDurations == 0L) {
+            // Not interested
+            return null;
+        }
+        final ProtoOutputStream proto = new ProtoOutputStream();
+        proto.write(AppBackgroundRestrictionsInfo.FgsTrackerInfo.FGS_NOTIFICATION_VISIBLE,
+                hasForegroundServiceNotifications(uid));
+        proto.write(AppBackgroundRestrictionsInfo.FgsTrackerInfo.FGS_DURATION, fgsDurations);
+        proto.flush();
+        return proto.getBytes();
+    }
+
+    @Override
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix);
         pw.println("APP FOREGROUND SERVICE TRACKER:");
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index da083af..f7abb11 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -1063,6 +1063,13 @@
                 DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "auto_restricted_bucket_on_bg_restricted";
 
         /**
+         * Whether or not to move the app to restricted standby level automatically
+         * when system detects it's abusive.
+         */
+        static final String KEY_BG_AUTO_RESTRICT_ABUSIVE_APPS =
+                DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "auto_restrict_abusive_apps";
+
+        /**
          * The minimal interval in ms before posting a notification again on abusive behaviors
          * of a certain package.
          */
@@ -1107,6 +1114,11 @@
                 DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "prompt_abusive_apps_to_bg_restricted";
 
         /**
+         * Default value to {@link #mBgAutoRestrictAbusiveApps}.
+         */
+        static final boolean DEFAULT_BG_AUTO_RESTRICT_ABUSIVE_APPS = true;
+
+        /**
          * Default value to {@link #mBgAutoRestrictedBucket}.
          */
         static final boolean DEFAULT_BG_AUTO_RESTRICTED_BUCKET_ON_BG_RESTRICTION = false;
@@ -1138,6 +1150,8 @@
 
         volatile boolean mBgAutoRestrictedBucket;
 
+        volatile boolean mBgAutoRestrictAbusiveApps;
+
         volatile boolean mRestrictedBucketEnabled;
 
         volatile long mBgAbusiveNotificationMinIntervalMs;
@@ -1184,6 +1198,9 @@
                     case KEY_BG_AUTO_RESTRICTED_BUCKET_ON_BG_RESTRICTION:
                         updateBgAutoRestrictedBucketChanged();
                         break;
+                    case KEY_BG_AUTO_RESTRICT_ABUSIVE_APPS:
+                        updateBgAutoRestrictAbusiveApps();
+                        break;
                     case KEY_BG_ABUSIVE_NOTIFICATION_MINIMAL_INTERVAL:
                         updateBgAbusiveNotificationMinimalInterval();
                         break;
@@ -1232,6 +1249,7 @@
 
         void updateDeviceConfig() {
             updateBgAutoRestrictedBucketChanged();
+            updateBgAutoRestrictAbusiveApps();
             updateBgAbusiveNotificationMinimalInterval();
             updateBgLongFgsNotificationMinimalInterval();
             updateBgPromptFgsWithNotiToBgRestricted();
@@ -1251,6 +1269,13 @@
             }
         }
 
+        private void updateBgAutoRestrictAbusiveApps() {
+            mBgAutoRestrictAbusiveApps = DeviceConfig.getBoolean(
+                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                    KEY_BG_AUTO_RESTRICT_ABUSIVE_APPS,
+                    DEFAULT_BG_AUTO_RESTRICT_ABUSIVE_APPS);
+        }
+
         private void updateBgAbusiveNotificationMinimalInterval() {
             mBgAbusiveNotificationMinIntervalMs = DeviceConfig.getLong(
                     DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1313,6 +1338,10 @@
             pw.print('=');
             pw.println(mBgAutoRestrictedBucket);
             pw.print(prefix);
+            pw.print(KEY_BG_AUTO_RESTRICT_ABUSIVE_APPS);
+            pw.print('=');
+            pw.println(mBgAutoRestrictAbusiveApps);
+            pw.print(prefix);
             pw.print(KEY_BG_ABUSIVE_NOTIFICATION_MINIMAL_INTERVAL);
             pw.print('=');
             pw.println(mBgAbusiveNotificationMinIntervalMs);
@@ -1772,6 +1801,14 @@
     }
 
     /**
+     * @return Whether or not to move the app to restricted level automatically
+     * when system detects it's abusive.
+     */
+    boolean isAutoRestrictAbusiveAppEnabled() {
+        return mConstantsObserver.mBgAutoRestrictAbusiveApps;
+    }
+
+    /**
      * @return The total foreground service durations for the given package/uid with given
      * foreground service type, or the total durations regardless the type if the given type is 0.
      */
@@ -2049,6 +2086,9 @@
         int curLevel;
         int prevReason;
         final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal();
+        if (trackerInfo == null) {
+            trackerInfo = mEmptyTrackerInfo;
+        }
         synchronized (mSettingsLock) {
             curLevel = getRestrictionLevel(uid, pkgName);
             if (curLevel == level) {
@@ -2101,14 +2141,21 @@
                         // It's currently active, enqueue it.
                         final int localReason = reason;
                         final int localSubReason = subReason;
-                        mActiveUids.add(uid, pkgName, () -> appStandbyInternal.restrictApp(
-                                pkgName, UserHandle.getUserId(uid), localReason, localSubReason));
+                        final TrackerInfo localTrackerInfo = trackerInfo;
+                        mActiveUids.add(uid, pkgName, () -> {
+                            appStandbyInternal.restrictApp(pkgName, UserHandle.getUserId(uid),
+                                    localReason, localSubReason);
+                            logAppBackgroundRestrictionInfo(pkgName, uid, curLevel, level,
+                                    localTrackerInfo, localReason);
+                        });
                         doIt = false;
                     }
                 }
                 if (doIt) {
                     appStandbyInternal.restrictApp(pkgName, UserHandle.getUserId(uid),
                             reason, subReason);
+                    logAppBackgroundRestrictionInfo(pkgName, uid, curLevel, level, trackerInfo,
+                            reason);
                 }
             }
         } else if (curLevel >= RESTRICTION_LEVEL_RESTRICTED_BUCKET
@@ -2123,11 +2170,14 @@
             appStandbyInternal.maybeUnrestrictApp(pkgName, UserHandle.getUserId(uid),
                     prevReason & REASON_MAIN_MASK, prevReason & REASON_SUB_MASK,
                     reason, subReason);
+            logAppBackgroundRestrictionInfo(pkgName, uid, curLevel, level, trackerInfo,
+                    reason);
         }
+    }
 
-        if (trackerInfo == null) {
-            trackerInfo = mEmptyTrackerInfo;
-        }
+    private void logAppBackgroundRestrictionInfo(String pkgName, int uid,
+            @RestrictionLevel int prevLevel, @RestrictionLevel int level,
+            @NonNull TrackerInfo trackerInfo, int reason) {
         FrameworkStatsLog.write(FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO, uid,
                 getRestrictionLevelStatsd(level),
                 getThresholdStatsd(reason),
@@ -2139,7 +2189,8 @@
                 getExemptionReasonStatsd(uid, level),
                 getOptimizationLevelStatsd(level),
                 getTargetSdkStatsd(pkgName),
-                ActivityManager.isLowRamDeviceStatic());
+                ActivityManager.isLowRamDeviceStatic(),
+                getRestrictionLevelStatsd(prevLevel));
     }
 
     private void handleBackgroundRestrictionChanged(int uid, String pkgName, boolean restricted) {
@@ -2398,6 +2449,22 @@
         }
 
         void postLongRunningFgsIfNecessary(String packageName, int uid) {
+            // Log the event in statsd.
+            FrameworkStatsLog.write(FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO,
+                    uid,
+                    mBgController.getRestrictionLevel(uid),
+                    AppBackgroundRestrictionsInfo.THRESHOLD_UNKNOWN,
+                    AppBackgroundRestrictionsInfo.FGS_TRACKER,
+                    mInjector.getAppFGSTracker().getTrackerInfoForStatsd(uid),
+                    null, // BatteryTrackerInfo
+                    null, // BroadcastEventsTrackerInfo
+                    null, // BindServiceEventsTrackerInfo
+                    getExemptionReasonForStatsd(
+                            mBgController.getBackgroundRestrictionExemptionReason(uid)),
+                    AppBackgroundRestrictionsInfo.UNKNOWN, // OptimizationLevel
+                    AppBackgroundRestrictionsInfo.SDK_UNKNOWN, // TargetSdk
+                    ActivityManager.isLowRamDeviceStatic(),
+                    mBgController.getRestrictionLevel(uid));
             PendingIntent pendingIntent;
             if (!mBgController.mConstantsObserver.mBgPromptFgsWithNotiOnLongRunning
                     && mBgController.hasForegroundServiceNotifications(packageName, uid)) {
diff --git a/services/core/java/com/android/server/am/BaseAppStateTimeSlotEventsTracker.java b/services/core/java/com/android/server/am/BaseAppStateTimeSlotEventsTracker.java
index b8aee13..ff78355 100644
--- a/services/core/java/com/android/server/am/BaseAppStateTimeSlotEventsTracker.java
+++ b/services/core/java/com/android/server/am/BaseAppStateTimeSlotEventsTracker.java
@@ -133,6 +133,15 @@
         mTmpPkgs.clear();
     }
 
+    @GuardedBy("mLock")
+    int getTotalEventsLocked(int uid, long now) {
+        final U events = getUidEventsLocked(uid);
+        if (events == null) {
+            return 0;
+        }
+        return events.getTotalEvents(now, SimpleAppStateTimeslotEvents.DEFAULT_INDEX);
+    }
+
     private void trimEvents() {
         final long now = SystemClock.elapsedRealtime();
         trim(Math.max(0, now - mInjector.getPolicy().getMaxTrackingDuration()));
@@ -301,6 +310,7 @@
                 @RestrictionLevel int maxLevel) {
             synchronized (mLock) {
                 final int level = mExcessiveEventPkgs.get(packageName, uid) == null
+                        || !mTracker.mAppRestrictionController.isAutoRestrictAbusiveAppEnabled()
                         ? RESTRICTION_LEVEL_ADAPTIVE_BUCKET
                         : RESTRICTION_LEVEL_RESTRICTED_BUCKET;
                 if (maxLevel > RESTRICTION_LEVEL_RESTRICTED_BUCKET) {
diff --git a/services/core/java/com/android/server/am/ComponentAliasResolver.java b/services/core/java/com/android/server/am/ComponentAliasResolver.java
index cf910d4..2db3b15 100644
--- a/services/core/java/com/android/server/am/ComponentAliasResolver.java
+++ b/services/core/java/com/android/server/am/ComponentAliasResolver.java
@@ -104,7 +104,10 @@
 
     private static final String OPT_IN_PROPERTY = "com.android.EXPERIMENTAL_COMPONENT_ALIAS_OPT_IN";
 
-    private static final String ALIAS_FILTER_ACTION = "android.intent.action.EXPERIMENTAL_IS_ALIAS";
+    private static final String ALIAS_FILTER_ACTION =
+            "com.android.intent.action.EXPERIMENTAL_IS_ALIAS";
+    private static final String ALIAS_FILTER_ACTION_ALT =
+            "android.intent.action.EXPERIMENTAL_IS_ALIAS";
     private static final String META_DATA_ALIAS_TARGET = "alias_target";
 
     private static final int PACKAGE_QUERY_FLAGS =
@@ -223,8 +226,16 @@
     @GuardedBy("mLock")
     private void loadFromMetadataLocked() {
         if (DEBUG) Slog.d(TAG, "Scanning service aliases...");
-        Intent i = new Intent(ALIAS_FILTER_ACTION);
 
+        // PM.queryInetntXxx() doesn't support "OR" queries, so we search for
+        // both the com.android... action and android... action on by one.
+        // It's okay if a single component handles both actions because the resulting aliases
+        // will be stored in a map and duplicates will naturally be removed.
+        loadFromMetadataLockedInner(new Intent(ALIAS_FILTER_ACTION_ALT));
+        loadFromMetadataLockedInner(new Intent(ALIAS_FILTER_ACTION));
+    }
+
+    private void loadFromMetadataLockedInner(Intent i) {
         final List<ResolveInfo> services = mContext.getPackageManager().queryIntentServicesAsUser(
                 i, PACKAGE_QUERY_FLAGS, UserHandle.USER_SYSTEM);
 
diff --git a/services/core/java/com/android/server/am/DropboxRateLimiter.java b/services/core/java/com/android/server/am/DropboxRateLimiter.java
index c517023..672736d 100644
--- a/services/core/java/com/android/server/am/DropboxRateLimiter.java
+++ b/services/core/java/com/android/server/am/DropboxRateLimiter.java
@@ -49,7 +49,7 @@
     }
 
     /** Determines whether dropbox entries of a specific tag and process should be rate limited. */
-    public boolean shouldRateLimit(String eventType, String processName) {
+    public RateLimitResult shouldRateLimit(String eventType, String processName) {
         // Rate-limit how often we're willing to do the heavy lifting to collect and record logs.
         final long now = mClock.uptimeMillis();
         synchronized (mErrorClusterRecords) {
@@ -60,17 +60,33 @@
             if (errRecord == null) {
                 errRecord = new ErrorRecord(now, 1);
                 mErrorClusterRecords.put(errorKey(eventType, processName), errRecord);
-            } else if (now - errRecord.getStartTime() > RATE_LIMIT_BUFFER_DURATION) {
+                return new RateLimitResult(false, 0);
+            }
+
+            if (now - errRecord.getStartTime() > RATE_LIMIT_BUFFER_DURATION) {
                 errRecord.setStartTime(now);
                 errRecord.setCount(1);
-            } else {
-                errRecord.incrementCount();
-                if (errRecord.getCount() > RATE_LIMIT_ALLOWED_ENTRIES) return true;
+                return new RateLimitResult(false, recentlyDroppedCount(errRecord));
+            }
+
+            errRecord.incrementCount();
+            if (errRecord.getCount() > RATE_LIMIT_ALLOWED_ENTRIES) {
+                return new RateLimitResult(true, recentlyDroppedCount(errRecord));
             }
         }
-        return false;
+        return new RateLimitResult(false, 0);
     }
 
+    /**
+     * Returns the number of entries of a certain type and process that have recenlty been
+     * dropped. Resets every RATE_LIMIT_BUFFER_DURATION if events are still actively created or
+     * RATE_LIMIT_BUFFER_EXPIRY if not. */
+    private int recentlyDroppedCount(ErrorRecord errRecord) {
+        if (errRecord == null || errRecord.getCount() < RATE_LIMIT_ALLOWED_ENTRIES) return 0;
+        return errRecord.getCount() - RATE_LIMIT_ALLOWED_ENTRIES;
+    }
+
+
     private void maybeRemoveExpiredRecords(long now) {
         if (now - mLastMapCleanUp <= RATE_LIMIT_BUFFER_EXPIRY) return;
 
@@ -87,6 +103,27 @@
         return eventType + processName;
     }
 
+    /** Holds information on whether we should rate limit and how many events have been dropped. */
+    public class RateLimitResult {
+        boolean mShouldRateLimit;
+        int mDroppedCountSinceRateLimitActivated;
+
+        public RateLimitResult(boolean shouldRateLimit, int droppedCountSinceRateLimitActivated) {
+            mShouldRateLimit = shouldRateLimit;
+            mDroppedCountSinceRateLimitActivated = droppedCountSinceRateLimitActivated;
+        }
+
+        /** Whether to rate limit. */
+        public boolean shouldRateLimit() {
+            return mShouldRateLimit;
+        }
+
+        /** The number of dropped events since rate limit was activated. */
+        public int droppedCountSinceRateLimitActivated() {
+            return mDroppedCountSinceRateLimitActivated;
+        }
+    }
+
     private class ErrorRecord {
         long mStartTime;
         int mCount;
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index c48ff9f..2dadcec 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -97,6 +97,7 @@
         DeviceConfig.NAMESPACE_SURFACE_FLINGER_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_SWCODEC_NATIVE,
         DeviceConfig.NAMESPACE_TETHERING,
+        DeviceConfig.NAMESPACE_VENDOR_SYSTEM_NATIVE,
         DeviceConfig.NAMESPACE_VIRTUALIZATION_FRAMEWORK_NATIVE,
         DeviceConfig.NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT,
     };
diff --git a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java
index 766283b..028288f 100644
--- a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java
+++ b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java
@@ -43,7 +43,6 @@
 import android.service.ambientcontext.AmbientContextDetectionResult;
 import android.service.ambientcontext.AmbientContextDetectionServiceStatus;
 import android.text.TextUtils;
-import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 import android.util.Slog;
 
@@ -54,7 +53,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Set;
 
 /**
  * Per-user manager service for {@link AmbientContextEvent}s.
@@ -69,19 +67,13 @@
     RemoteAmbientContextDetectionService mRemoteService;
 
     private ComponentName mComponentName;
-    private Set<PendingIntent> mExistingPendingIntents;
 
     AmbientContextManagerPerUserService(
             @NonNull AmbientContextManagerService master, Object lock, @UserIdInt int userId) {
         super(master, lock, userId);
-        mExistingPendingIntents = new ArraySet<>();
     }
 
     void destroyLocked() {
-        if (isVerbose()) {
-            Slog.v(TAG, "destroyLocked()");
-        }
-
         Slog.d(TAG, "Trying to cancel the remote request. Reason: Service destroyed.");
         if (mRemoteService != null) {
             synchronized (mLock) {
@@ -118,7 +110,19 @@
         if (mComponentName == null) {
             mComponentName = updateServiceInfoLocked();
         }
-        return mComponentName != null;
+        if (mComponentName == null) {
+            return false;
+        }
+
+        ServiceInfo serviceInfo;
+        try {
+            serviceInfo = AppGlobals.getPackageManager().getServiceInfo(
+                    mComponentName, 0, mUserId);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "RemoteException while setting up service");
+            return false;
+        }
+        return serviceInfo != null;
     }
 
     @Override
@@ -171,18 +175,10 @@
                 return;
             }
 
-            // Remove any existing PendingIntent for this package.
-            String callingPackage = pendingIntent.getCreatorPackage();
-            PendingIntent duplicatePendingIntent = findExistingRequestByPackage(callingPackage);
-            if (duplicatePendingIntent != null) {
-                Slog.d(TAG, "Replace duplicate request from " + callingPackage);
-                mExistingPendingIntents.remove(duplicatePendingIntent);
-            }
-
-            // Register package and add pendingIntent to mExistingPendingIntents
-            startDetection(request, callingPackage, createDetectionResultRemoteCallback(),
-                    getServerStatusCallback(clientStatusCallback));
-            mExistingPendingIntents.add(pendingIntent);
+            // Register package and add to existing ClientRequests cache
+            startDetection(request, pendingIntent.getCreatorPackage(),
+                    createDetectionResultRemoteCallback(), clientStatusCallback);
+            mMaster.newClientAdded(mUserId, request, pendingIntent, clientStatusCallback);
         }
     }
 
@@ -214,15 +210,17 @@
 
     @VisibleForTesting
     void startDetection(AmbientContextEventRequest request, String callingPackage,
-            RemoteCallback detectionResultCallback, RemoteCallback statusCallback) {
+            RemoteCallback detectionResultCallback, RemoteCallback clientStatusCallback) {
         Slog.d(TAG, "Requested detection of " + request.getEventTypes());
         synchronized (mLock) {
             if (setUpServiceIfNeeded()) {
                 ensureRemoteServiceInitiated();
                 mRemoteService.startDetection(request, callingPackage, detectionResultCallback,
-                        statusCallback);
+                        getServerStatusCallback(clientStatusCallback));
             } else {
                 Slog.w(TAG, "No valid component found for AmbientContextDetectionService");
+                sendStatusToCallback(clientStatusCallback,
+                        AmbientContextManager.STATUS_NOT_SUPPORTED);
             }
         }
     }
@@ -245,15 +243,8 @@
      */
     public void onUnregisterObserver(String callingPackage) {
         synchronized (mLock) {
-            PendingIntent pendingIntent = findExistingRequestByPackage(callingPackage);
-            if (pendingIntent == null) {
-                Slog.d(TAG, "No registration found for " + callingPackage);
-                return;
-            }
-
-            // Remove from existing requests
-            mExistingPendingIntents.remove(pendingIntent);
-            stopDetection(pendingIntent.getCreatorPackage());
+            stopDetection(callingPackage);
+            mMaster.clientRemoved(mUserId, callingPackage);
         }
     }
 
@@ -265,7 +256,7 @@
             if (!setUpServiceIfNeeded()) {
                 Slog.w(TAG, "Detection service is not available at this moment.");
                 sendStatusToCallback(statusCallback,
-                        AmbientContextManager.STATUS_SERVICE_UNAVAILABLE);
+                        AmbientContextManager.STATUS_NOT_SUPPORTED);
                 return;
             }
             ensureRemoteServiceInitiated();
@@ -382,16 +373,6 @@
         }
     }
 
-    @Nullable
-    private PendingIntent findExistingRequestByPackage(String callingPackage) {
-        for (PendingIntent pendingIntent : mExistingPendingIntents) {
-            if (pendingIntent.getCreatorPackage().equals(callingPackage)) {
-                return pendingIntent;
-            }
-        }
-        return null;
-    }
-
     /**
      * Sends out the Intent to the client after the event is detected.
      *
@@ -418,22 +399,22 @@
     }
 
     @NonNull
-    private RemoteCallback createDetectionResultRemoteCallback() {
+    RemoteCallback createDetectionResultRemoteCallback() {
         return new RemoteCallback(result -> {
             AmbientContextDetectionResult detectionResult =
                     (AmbientContextDetectionResult) result.get(
                             AmbientContextDetectionResult.RESULT_RESPONSE_BUNDLE_KEY);
+            String packageName = detectionResult.getPackageName();
+            PendingIntent pendingIntent = mMaster.getPendingIntent(mUserId, packageName);
+            if (pendingIntent == null) {
+                return;
+            }
+
             final long token = Binder.clearCallingIdentity();
             try {
-                for (PendingIntent pendingIntent : mExistingPendingIntents) {
-                    // Send PendingIntent to requesting packages
-                    String creatorPackage = pendingIntent.getCreatorPackage();
-                    if (detectionResult.getPackageName().equals(creatorPackage)) {
-                        sendDetectionResultIntent(pendingIntent, detectionResult);
-                        Slog.i(TAG, "Got detection result of " + detectionResult.getEvents()
-                                + " for " + creatorPackage);
-                    }
-                }
+                sendDetectionResultIntent(pendingIntent, detectionResult);
+                Slog.i(TAG, "Got detection result of " + detectionResult.getEvents()
+                        + " for " + packageName);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
diff --git a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
index cfca7ec..4206262 100644
--- a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
+++ b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
@@ -20,6 +20,7 @@
 
 import android.Manifest;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.PendingIntent;
 import android.app.ambientcontext.AmbientContextEvent;
@@ -34,6 +35,7 @@
 import android.os.ShellCallback;
 import android.os.UserHandle;
 import android.provider.DeviceConfig;
+import android.util.ArraySet;
 import android.util.Slog;
 
 import com.android.internal.R;
@@ -60,9 +62,50 @@
 
     /** Default value in absence of {@link DeviceConfig} override. */
     private static final boolean DEFAULT_SERVICE_ENABLED = true;
+    public static final int MAX_TEMPORARY_SERVICE_DURATION_MS = 30000;
+
+    static class ClientRequest {
+        private final int mUserId;
+        private final AmbientContextEventRequest mRequest;
+        private final PendingIntent mPendingIntent;
+        private final RemoteCallback mClientStatusCallback;
+
+        ClientRequest(int userId, AmbientContextEventRequest request,
+                PendingIntent pendingIntent, RemoteCallback clientStatusCallback) {
+            this.mUserId = userId;
+            this.mRequest = request;
+            this.mPendingIntent = pendingIntent;
+            this.mClientStatusCallback = clientStatusCallback;
+        }
+
+        String getPackageName() {
+            return mPendingIntent.getCreatorPackage();
+        }
+
+        AmbientContextEventRequest getRequest() {
+            return mRequest;
+        }
+
+        PendingIntent getPendingIntent() {
+            return mPendingIntent;
+        }
+
+        RemoteCallback getClientStatusCallback() {
+            return mClientStatusCallback;
+        }
+
+        boolean hasUserId(int userId) {
+            return mUserId == userId;
+        }
+
+        boolean hasUserIdAndPackageName(int userId, String packageName) {
+            return (userId == mUserId) && packageName.equals(getPackageName());
+        }
+    }
 
     private final Context mContext;
     boolean mIsServiceEnabled;
+    private Set<ClientRequest> mExistingClientRequests;
 
     public AmbientContextManagerService(Context context) {
         super(context,
@@ -73,6 +116,7 @@
                 PACKAGE_UPDATE_POLICY_REFRESH_EAGER
                         | /*To avoid high latency*/ PACKAGE_RESTART_POLICY_REFRESH_EAGER);
         mContext = context;
+        mExistingClientRequests = new ArraySet<>();
     }
 
     @Override
@@ -94,6 +138,44 @@
         }
     }
 
+    void newClientAdded(int userId, AmbientContextEventRequest request,
+            PendingIntent pendingIntent, RemoteCallback clientStatusCallback) {
+        Slog.d(TAG, "New client added: " + pendingIntent.getCreatorPackage());
+
+        // Remove any existing ClientRequest for this user and package.
+        mExistingClientRequests.removeAll(
+                findExistingRequests(userId, pendingIntent.getCreatorPackage()));
+
+        // Add to existing ClientRequests
+        mExistingClientRequests.add(
+                new ClientRequest(userId, request, pendingIntent, clientStatusCallback));
+    }
+
+    void clientRemoved(int userId, String packageName) {
+        Slog.d(TAG, "Remove client: " + packageName);
+        mExistingClientRequests.removeAll(findExistingRequests(userId, packageName));
+    }
+
+    private Set<ClientRequest> findExistingRequests(int userId, String packageName) {
+        Set<ClientRequest> existingRequests = new ArraySet<>();
+        for (ClientRequest clientRequest : mExistingClientRequests) {
+            if (clientRequest.hasUserIdAndPackageName(userId, packageName)) {
+                existingRequests.add(clientRequest);
+            }
+        }
+        return existingRequests;
+    }
+
+    @Nullable
+    PendingIntent getPendingIntent(int userId, String packageName) {
+        for (ClientRequest clientRequest : mExistingClientRequests) {
+            if (clientRequest.hasUserIdAndPackageName(userId, packageName)) {
+                return clientRequest.getPendingIntent();
+            }
+        }
+        return null;
+    }
+
     private void onDeviceConfigChange(@NonNull Set<String> keys) {
         if (keys.contains(KEY_SERVICE_ENABLED)) {
             mIsServiceEnabled = DeviceConfig.getBoolean(
@@ -111,9 +193,33 @@
     @Override
     protected void onServiceRemoved(
             AmbientContextManagerPerUserService service, @UserIdInt int userId) {
+        Slog.d(TAG, "onServiceRemoved");
         service.destroyLocked();
     }
 
+    @Override
+    protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
+        Slog.d(TAG, "Restoring remote request. Reason: Service package restarted.");
+        restorePreviouslyEnabledClients(userId);
+    }
+
+    @Override
+    protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+        Slog.d(TAG, "Restoring remote request. Reason: Service package updated.");
+        restorePreviouslyEnabledClients(userId);
+    }
+
+    @Override
+    protected void enforceCallingPermissionForManagement() {
+        getContext().enforceCallingPermission(
+                Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG);
+    }
+
+    @Override
+    protected int getMaximumTemporaryServiceDurationMs() {
+        return MAX_TEMPORARY_SERVICE_DURATION_MS;
+    }
+
     /** Returns {@code true} if the detection service is configured on this device. */
     public static boolean isDetectionServiceConfigured() {
         final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
@@ -182,6 +288,22 @@
         }
     }
 
+    private void restorePreviouslyEnabledClients(int userId) {
+        synchronized (mLock) {
+            final AmbientContextManagerPerUserService service = getServiceForUserLocked(userId);
+            for (ClientRequest clientRequest : mExistingClientRequests) {
+                // Start detection for previously enabled clients
+                if (clientRequest.hasUserId(userId)) {
+                    Slog.d(TAG, "Restoring detection for " + clientRequest.getPackageName());
+                    service.startDetection(clientRequest.getRequest(),
+                            clientRequest.getPackageName(),
+                            service.createDetectionResultRemoteCallback(),
+                            clientRequest.getClientStatusCallback());
+                }
+            }
+        }
+    }
+
     /**
      * Returns the AmbientContextManagerPerUserService component for this user.
      */
diff --git a/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java b/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java
index a76eb8f..90b1b63 100644
--- a/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java
+++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java
@@ -20,9 +20,11 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityTaskManager;
+import android.app.IActivityTaskManager;
 import android.content.Context;
 import android.content.Intent;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.service.games.GameService;
 import android.service.games.GameSessionService;
 import android.service.games.IGameService;
@@ -47,14 +49,17 @@
     @Override
     public GameServiceProviderInstance create(
             @NonNull GameServiceComponentConfiguration configuration) {
+        final UserHandle userHandle = configuration.getUserHandle();
+        final IActivityTaskManager activityTaskManager = ActivityTaskManager.getService();
         return new GameServiceProviderInstanceImpl(
-                configuration.getUserHandle(),
+                userHandle,
                 BackgroundThread.getExecutor(),
                 mContext,
-                new GameClassifierImpl(mContext.getPackageManager()),
+                new GameTaskInfoProvider(userHandle, activityTaskManager,
+                        new GameClassifierImpl(mContext.getPackageManager())),
                 ActivityManager.getService(),
                 LocalServices.getService(ActivityManagerInternal.class),
-                ActivityTaskManager.getService(),
+                activityTaskManager,
                 (WindowManagerService) ServiceManager.getService(Context.WINDOW_SERVICE),
                 LocalServices.getService(WindowManagerInternal.class),
                 new GameServiceConnector(mContext, configuration),
diff --git a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
index b38195a..a200067 100644
--- a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
+++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
@@ -64,7 +64,6 @@
 import com.android.server.wm.WindowManagerInternal.TaskSystemBarsListener;
 import com.android.server.wm.WindowManagerService;
 
-import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
@@ -218,7 +217,7 @@
     private final UserHandle mUserHandle;
     private final Executor mBackgroundExecutor;
     private final Context mContext;
-    private final GameClassifier mGameClassifier;
+    private final GameTaskInfoProvider mGameTaskInfoProvider;
     private final IActivityManager mActivityManager;
     private final ActivityManagerInternal mActivityManagerInternal;
     private final IActivityTaskManager mActivityTaskManager;
@@ -244,7 +243,7 @@
             @NonNull UserHandle userHandle,
             @NonNull Executor backgroundExecutor,
             @NonNull Context context,
-            @NonNull GameClassifier gameClassifier,
+            @NonNull GameTaskInfoProvider gameTaskInfoProvider,
             @NonNull IActivityManager activityManager,
             @NonNull ActivityManagerInternal activityManagerInternal,
             @NonNull IActivityTaskManager activityTaskManager,
@@ -256,7 +255,7 @@
         mUserHandle = userHandle;
         mBackgroundExecutor = backgroundExecutor;
         mContext = context;
-        mGameClassifier = gameClassifier;
+        mGameTaskInfoProvider = gameTaskInfoProvider;
         mActivityManager = activityManager;
         mActivityManagerInternal = activityManagerInternal;
         mActivityTaskManager = activityTaskManager;
@@ -344,13 +343,14 @@
     }
 
     private void onTaskCreated(int taskId, @NonNull ComponentName componentName) {
-        String packageName = componentName.getPackageName();
-        if (!mGameClassifier.isGame(packageName, mUserHandle)) {
+        final GameTaskInfo taskInfo = mGameTaskInfoProvider.get(taskId, componentName);
+
+        if (!taskInfo.mIsGameTask) {
             return;
         }
 
         synchronized (mLock) {
-            gameTaskStartedLocked(taskId, componentName);
+            gameTaskStartedLocked(taskInfo);
         }
     }
 
@@ -367,7 +367,17 @@
         }
 
         final GameSessionRecord gameSessionRecord = mGameSessions.get(taskId);
-        if (gameSessionRecord == null || gameSessionRecord.getGameSession() == null) {
+        if (gameSessionRecord == null) {
+            if (focused) {
+                // The game session for a game task may have been destroyed when the game task
+                // was put into the background by pressing the back button. If the task is restored
+                // via the Recents UI there will be no TaskStackListener#onCreated call for the
+                // restoration, so this focus event is the first opportunity to re-create the game
+                // session.
+                maybeCreateGameSessionForFocusedTaskLocked(taskId);
+            }
+            return;
+        } else if (gameSessionRecord.getGameSession() == null) {
             return;
         }
 
@@ -379,30 +389,50 @@
     }
 
     @GuardedBy("mLock")
-    private void gameTaskStartedLocked(int taskId, @NonNull ComponentName componentName) {
+    private void maybeCreateGameSessionForFocusedTaskLocked(int taskId) {
         if (DEBUG) {
-            Slog.i(TAG, "gameStartedLocked() id: " + taskId + " component: " + componentName);
+            Slog.d(TAG, "maybeRecreateGameSessionForFocusedTaskLocked() id: " + taskId);
+        }
+
+        final GameTaskInfo taskInfo = mGameTaskInfoProvider.get(taskId);
+        if (taskInfo == null) {
+            Slog.w(TAG, "No task info for focused task: " + taskId);
+            return;
+        }
+
+        if (!taskInfo.mIsGameTask) {
+            return;
+        }
+
+        gameTaskStartedLocked(taskInfo);
+    }
+
+    @GuardedBy("mLock")
+    private void gameTaskStartedLocked(@NonNull GameTaskInfo gameTaskInfo) {
+        if (DEBUG) {
+            Slog.i(TAG, "gameStartedLocked(): " + gameTaskInfo);
         }
 
         if (!mIsRunning) {
             return;
         }
 
-        GameSessionRecord existingGameSessionRecord = mGameSessions.get(taskId);
+        GameSessionRecord existingGameSessionRecord = mGameSessions.get(gameTaskInfo.mTaskId);
         if (existingGameSessionRecord != null) {
-            Slog.w(TAG, "Existing game session found for task (id: " + taskId
+            Slog.w(TAG, "Existing game session found for task (id: " + gameTaskInfo.mTaskId
                     + ") creation. Ignoring.");
             return;
         }
 
         GameSessionRecord gameSessionRecord = GameSessionRecord.awaitingGameSessionRequest(
-                taskId, componentName);
-        mGameSessions.put(taskId, gameSessionRecord);
+                gameTaskInfo.mTaskId, gameTaskInfo.mComponentName);
+        mGameSessions.put(gameTaskInfo.mTaskId, gameSessionRecord);
 
         AndroidFuture<Void> unusedPostGameStartedFuture = mGameServiceConnector.post(
                 gameService -> {
                     gameService.gameStarted(
-                            new GameStartedEvent(taskId, componentName.getPackageName()));
+                            new GameStartedEvent(gameTaskInfo.mTaskId,
+                                    gameTaskInfo.mComponentName.getPackageName()));
                 });
     }
 
@@ -769,7 +799,7 @@
 
     @Nullable
     private GameSessionViewHostConfiguration createViewHostConfigurationForTask(int taskId) {
-        RunningTaskInfo runningTaskInfo = getRunningTaskInfoForTask(taskId);
+        RunningTaskInfo runningTaskInfo = mGameTaskInfoProvider.getRunningTaskInfo(taskId);
         if (runningTaskInfo == null) {
             return null;
         }
@@ -781,28 +811,6 @@
                 bounds.height());
     }
 
-    @Nullable
-    private RunningTaskInfo getRunningTaskInfoForTask(int taskId) {
-        List<RunningTaskInfo> runningTaskInfos;
-        try {
-            runningTaskInfos = mActivityTaskManager.getTasks(
-                    /* maxNum= */ Integer.MAX_VALUE,
-                    /* filterOnlyVisibleRecents= */ true,
-                    /* keepIntentExtra= */ false);
-        } catch (RemoteException ex) {
-            Slog.w(TAG, "Failed to fetch running tasks");
-            return null;
-        }
-
-        for (RunningTaskInfo taskInfo : runningTaskInfos) {
-            if (taskInfo.taskId == taskId) {
-                return taskInfo;
-            }
-        }
-
-        return null;
-    }
-
     @VisibleForTesting
     void takeScreenshot(int taskId, @NonNull AndroidFuture callback) {
         GameSessionRecord gameSessionRecord;
@@ -834,7 +842,8 @@
             } else {
                 final Bundle bundle = ScreenshotHelper.HardwareBitmapBundler.hardwareBitmapToBundle(
                         bitmap);
-                final RunningTaskInfo runningTaskInfo = getRunningTaskInfoForTask(taskId);
+                final RunningTaskInfo runningTaskInfo =
+                        mGameTaskInfoProvider.getRunningTaskInfo(taskId);
                 if (runningTaskInfo == null) {
                     Slog.w(TAG, "Could not get running task info for id: " + taskId);
                     callback.complete(GameScreenshotResult.createInternalErrorResult());
diff --git a/services/core/java/com/android/server/app/GameTaskInfo.java b/services/core/java/com/android/server/app/GameTaskInfo.java
new file mode 100644
index 0000000..7548dbd
--- /dev/null
+++ b/services/core/java/com/android/server/app/GameTaskInfo.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.app;
+
+import android.content.ComponentName;
+
+import java.util.Objects;
+
+final class GameTaskInfo {
+    final int mTaskId;
+    final boolean mIsGameTask;
+    final ComponentName mComponentName;
+
+    GameTaskInfo(int taskId, boolean isGameTask, ComponentName componentName) {
+        mTaskId = taskId;
+        mIsGameTask = isGameTask;
+        mComponentName = componentName;
+    }
+
+    @Override
+    public String toString() {
+        return "GameTaskInfo{"
+                + "mTaskId="
+                + mTaskId
+                + ", mIsGameTask="
+                + mIsGameTask
+                + ", mComponentName="
+                + mComponentName
+                + '}';
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof GameTaskInfo)) {
+            return false;
+        }
+
+        GameTaskInfo that = (GameTaskInfo) o;
+        return mTaskId == that.mTaskId
+                && mIsGameTask == that.mIsGameTask
+                && mComponentName.equals(that.mComponentName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mTaskId, mIsGameTask, mComponentName);
+    }
+}
diff --git a/services/core/java/com/android/server/app/GameTaskInfoProvider.java b/services/core/java/com/android/server/app/GameTaskInfoProvider.java
new file mode 100644
index 0000000..f078d98
--- /dev/null
+++ b/services/core/java/com/android/server/app/GameTaskInfoProvider.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.app;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.IActivityTaskManager;
+import android.content.ComponentName;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.LruCache;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.List;
+
+final class GameTaskInfoProvider {
+    private static final String TAG = "GameTaskInfoProvider";
+    private static final int TASK_INFO_CACHE_MAX_SIZE = 50;
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private final LruCache<Integer, GameTaskInfo> mGameTaskInfoCache = new LruCache<>(
+            TASK_INFO_CACHE_MAX_SIZE);
+
+    private final UserHandle mUserHandle;
+    private final IActivityTaskManager mActivityTaskManager;
+    private final GameClassifier mGameClassifier;
+
+    GameTaskInfoProvider(@NonNull UserHandle userHandle,
+            @NonNull IActivityTaskManager activityTaskManager,
+            @NonNull GameClassifier gameClassifier) {
+        mUserHandle = userHandle;
+        mActivityTaskManager = activityTaskManager;
+        mGameClassifier = gameClassifier;
+    }
+
+    @Nullable
+    GameTaskInfo get(int taskId) {
+        synchronized (mLock) {
+            final GameTaskInfo cachedTaskInfo = mGameTaskInfoCache.get(taskId);
+            if (cachedTaskInfo != null) {
+                return cachedTaskInfo;
+            }
+        }
+
+        final RunningTaskInfo runningTaskInfo = getRunningTaskInfo(taskId);
+        if (runningTaskInfo == null || runningTaskInfo.baseActivity == null) {
+            return null;
+        }
+
+        return generateGameInfo(taskId, runningTaskInfo.baseActivity);
+    }
+
+    GameTaskInfo get(int taskId, @NonNull ComponentName componentName) {
+        synchronized (mLock) {
+            final GameTaskInfo cachedTaskInfo = mGameTaskInfoCache.get(taskId);
+            if (cachedTaskInfo != null) {
+                if (cachedTaskInfo.mComponentName.equals(componentName)) {
+                    Slog.w(TAG, "Found cached task info for taskId " + taskId
+                            + " but cached component name " + cachedTaskInfo.mComponentName
+                            + " does not match " + componentName);
+                } else {
+                    return cachedTaskInfo;
+                }
+            }
+        }
+
+        return generateGameInfo(taskId, componentName);
+    }
+
+    @Nullable
+    RunningTaskInfo getRunningTaskInfo(int taskId) {
+        List<RunningTaskInfo> runningTaskInfos;
+        try {
+            runningTaskInfos = mActivityTaskManager.getTasks(
+                    /* maxNum= */ Integer.MAX_VALUE,
+                    /* filterOnlyVisibleRecents= */ false,
+                    /* keepIntentExtra= */ false);
+        } catch (RemoteException ex) {
+            Slog.w(TAG, "Failed to fetch running tasks");
+            return null;
+        }
+
+        for (RunningTaskInfo taskInfo : runningTaskInfos) {
+            if (taskInfo.taskId == taskId) {
+                return taskInfo;
+            }
+        }
+
+        return null;
+    }
+
+    private GameTaskInfo generateGameInfo(int taskId, @NonNull ComponentName componentName) {
+        final GameTaskInfo gameTaskInfo = new GameTaskInfo(taskId,
+                mGameClassifier.isGame(componentName.getPackageName(), mUserHandle), componentName);
+
+        synchronized (mLock) {
+            mGameTaskInfoCache.put(taskId, gameTaskInfo);
+        }
+
+        return gameTaskInfo;
+    }
+}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 361629b..3e97b91 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -69,6 +69,7 @@
 import static android.app.AppOpsManager.makeKey;
 import static android.app.AppOpsManager.modeToName;
 import static android.app.AppOpsManager.opAllowSystemBypassRestriction;
+import static android.app.AppOpsManager.opRestrictsRead;
 import static android.app.AppOpsManager.opToName;
 import static android.app.AppOpsManager.opToPublicName;
 import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState;
@@ -2875,6 +2876,10 @@
             // features may require permissions our remote caller does not have.
             final long identity = Binder.clearCallingIdentity();
             try {
+                if (shouldIgnoreCallback(switchedCode, callback.mCallingPid,
+                        callback.mCallingUid)) {
+                    continue;
+                }
                 callback.mCallback.opChanged(switchedCode, uid, packageName);
             } catch (RemoteException e) {
                 /* ignore */
@@ -4205,6 +4210,9 @@
             for (int i = 0; i < callbackCount; i++) {
                 final ActiveCallback callback = callbacks.valueAt(i);
                 try {
+                    if (shouldIgnoreCallback(code, callback.mCallingPid, callback.mCallingUid)) {
+                        continue;
+                    }
                     callback.mCallback.opActiveChanged(code, uid, packageName, attributionTag,
                             active, attributionFlags, attributionChainId);
                 } catch (RemoteException e) {
@@ -4258,6 +4266,9 @@
             for (int i = 0; i < callbackCount; i++) {
                 final StartedCallback callback = callbacks.valueAt(i);
                 try {
+                    if (shouldIgnoreCallback(code, callback.mCallingPid, callback.mCallingUid)) {
+                        continue;
+                    }
                     callback.mCallback.opStarted(code, uid, packageName, attributionTag, flags,
                             result, startedType, attributionFlags, attributionChainId);
                 } catch (RemoteException e) {
@@ -4306,6 +4317,9 @@
             for (int i = 0; i < callbackCount; i++) {
                 final NotedCallback callback = callbacks.valueAt(i);
                 try {
+                    if (shouldIgnoreCallback(code, callback.mCallingPid, callback.mCallingUid)) {
+                        continue;
+                    }
                     callback.mCallback.opNoted(code, uid, packageName, attributionTag, flags,
                             result);
                 } catch (RemoteException e) {
@@ -4370,8 +4384,20 @@
                 Binder.getCallingPid(), Binder.getCallingUid(), null);
     }
 
+    private boolean shouldIgnoreCallback(int op, int watcherPid, int watcherUid) {
+        // If it's a restricted read op, ignore it if watcher doesn't have manage ops permission,
+        // as watcher should not use this to signal if the value is changed.
+        return opRestrictsRead(op) && mContext.checkPermission(Manifest.permission.MANAGE_APPOPS,
+                watcherPid, watcherUid) != PackageManager.PERMISSION_GRANTED;
+    }
+
     private void verifyIncomingOp(int op) {
         if (op >= 0 && op < AppOpsManager._NUM_OP) {
+            // Enforce manage appops permission if it's a restricted read op.
+            if (opRestrictsRead(op)) {
+                mContext.enforcePermission(Manifest.permission.MANAGE_APPOPS,
+                        Binder.getCallingPid(), Binder.getCallingUid(), "verifyIncomingOp");
+            }
             return;
         }
         throw new IllegalArgumentException("Bad operation #" + op);
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index e145270..dbe4fb8 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -862,8 +862,8 @@
     }
 
      /*package*/ void disconnectLeAudio(int device) {
-        if (device != AudioSystem.DEVICE_OUT_BLE_HEADSET ||
-                    device != AudioSystem.DEVICE_OUT_BLE_BROADCAST) {
+        if (device != AudioSystem.DEVICE_OUT_BLE_HEADSET
+                && device != AudioSystem.DEVICE_OUT_BLE_BROADCAST) {
             Log.e(TAG, "disconnectLeAudio: Can't disconnect not LE Audio device " + device);
             return;
         }
@@ -879,6 +879,8 @@
             new MediaMetrics.Item(mMetricsId + "disconnectLeAudio")
                     .record();
             if (toRemove.size() > 0) {
+                final int delay = checkSendBecomingNoisyIntentInt(device, 0,
+                        AudioSystem.DEVICE_NONE);
                 toRemove.stream().forEach(deviceAddress ->
                         makeLeAudioDeviceUnavailable(deviceAddress, device)
                 );
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index d10ed55..0aa9a2b 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -462,6 +462,7 @@
         mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.HEADSET);
         mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.HEARING_AID);
         mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.LE_AUDIO);
+        mDeviceBroker.postBtProfileDisconnected(BluetoothProfile.LE_AUDIO_BROADCAST);
     }
 
     // @GuardedBy("AudioDeviceBroker.mSetModeLock")
@@ -687,6 +688,7 @@
                         case BluetoothProfile.HEADSET:
                         case BluetoothProfile.HEARING_AID:
                         case BluetoothProfile.LE_AUDIO:
+                        case BluetoothProfile.LE_AUDIO_BROADCAST:
                             mDeviceBroker.postBtProfileDisconnected(profile);
                             break;
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 6d68772..1002229 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -105,7 +105,7 @@
         mIsStrongBiometric = isStrongBiometric;
         mOperationId = operationId;
         mRequireConfirmation = requireConfirmation;
-        mActivityTaskManager = ActivityTaskManager.getInstance();
+        mActivityTaskManager = getActivityTaskManager();
         mBiometricManager = context.getSystemService(BiometricManager.class);
         mTaskStackListener = taskStackListener;
         mLockoutTracker = lockoutTracker;
@@ -133,6 +133,10 @@
         return mStartTimeMs;
     }
 
+    protected ActivityTaskManager getActivityTaskManager() {
+        return ActivityTaskManager.getInstance();
+    }
+
     @Override
     public void binderDied() {
         final boolean clearListener = !isBiometricPrompt();
@@ -310,45 +314,50 @@
                     sendCancelOnly(listener);
                 }
             });
-        } else {
-            // Allow system-defined limit of number of attempts before giving up
-            final @LockoutTracker.LockoutMode int lockoutMode =
-                    handleFailedAttempt(getTargetUserId());
-            if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
-                markAlreadyDone();
+        } else { // not authenticated
+            if (isBackgroundAuth) {
+                Slog.e(TAG, "cancelling due to background auth");
+                cancel();
+            } else {
+                // Allow system-defined limit of number of attempts before giving up
+                final @LockoutTracker.LockoutMode int lockoutMode =
+                        handleFailedAttempt(getTargetUserId());
+                if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
+                    markAlreadyDone();
+                }
+
+                final CoexCoordinator coordinator = CoexCoordinator.getInstance();
+                coordinator.onAuthenticationRejected(SystemClock.uptimeMillis(), this, lockoutMode,
+                        new CoexCoordinator.Callback() {
+                            @Override
+                            public void sendAuthenticationResult(boolean addAuthTokenIfStrong) {
+                                if (listener != null) {
+                                    try {
+                                        listener.onAuthenticationFailed(getSensorId());
+                                    } catch (RemoteException e) {
+                                        Slog.e(TAG, "Unable to notify listener", e);
+                                    }
+                                }
+                            }
+
+                            @Override
+                            public void sendHapticFeedback() {
+                                if (listener != null && mShouldVibrate) {
+                                    vibrateError();
+                                }
+                            }
+
+                            @Override
+                            public void handleLifecycleAfterAuth() {
+                                AuthenticationClient.this.handleLifecycleAfterAuth(false /* authenticated */);
+                            }
+
+                            @Override
+                            public void sendAuthenticationCanceled() {
+                                sendCancelOnly(listener);
+                            }
+                        });
             }
-
-            final CoexCoordinator coordinator = CoexCoordinator.getInstance();
-            coordinator.onAuthenticationRejected(SystemClock.uptimeMillis(), this, lockoutMode,
-                    new CoexCoordinator.Callback() {
-                @Override
-                public void sendAuthenticationResult(boolean addAuthTokenIfStrong) {
-                    if (listener != null) {
-                        try {
-                            listener.onAuthenticationFailed(getSensorId());
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "Unable to notify listener", e);
-                        }
-                    }
-                }
-
-                @Override
-                public void sendHapticFeedback() {
-                    if (listener != null && mShouldVibrate) {
-                        vibrateError();
-                    }
-                }
-
-                @Override
-                public void handleLifecycleAfterAuth() {
-                    AuthenticationClient.this.handleLifecycleAfterAuth(false /* authenticated */);
-                }
-
-                @Override
-                public void sendAuthenticationCanceled() {
-                    sendCancelOnly(listener);
-                }
-            });
         }
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
index 5aa9b79..c8a90e7 100644
--- a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
@@ -92,7 +92,7 @@
         void sendHapticFeedback();
     }
 
-    private static CoexCoordinator sInstance;
+    private static final CoexCoordinator sInstance = new CoexCoordinator();
 
     @VisibleForTesting
     public static class SuccessfulAuth {
@@ -147,14 +147,9 @@
         }
     }
 
-    /**
-     * @return a singleton instance.
-     */
+    /** The singleton instance. */
     @NonNull
     public static CoexCoordinator getInstance() {
-        if (sInstance == null) {
-            sInstance = new CoexCoordinator();
-        }
         return sInstance;
     }
 
@@ -339,18 +334,8 @@
                         auth.mCallback.sendHapticFeedback();
                         auth.mCallback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
                         auth.mCallback.handleLifecycleAfterAuth();
-                    } else if (isFaceScanning()) {
-                        // UDFPS rejected but face is still scanning
-                        Slog.d(TAG, "UDFPS rejected in multi-sensor auth, face: " + face);
-                        callback.handleLifecycleAfterAuth();
-
-                        // TODO(b/193089985): Enforce/ensure that face auth finishes (whether
-                        //  accept/reject) within X amount of time. Otherwise users will be stuck
-                        //  waiting with their finger down for a long time.
                     } else {
-                        // Face not scanning, and was not found in the queue. Most likely, face
-                        // auth was too long ago.
-                        Slog.d(TAG, "UDFPS rejected in multi-sensor auth, face not scanning");
+                        Slog.d(TAG, "UDFPS rejected in multi-sensor auth");
                         callback.sendHapticFeedback();
                         callback.handleLifecycleAfterAuth();
                     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 97efc78..a26535f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -344,12 +344,12 @@
                     provider.second.getSensorProperties(sensorId);
             if (!isKeyguard && !Utils.isSettings(getContext(), opPackageName)
                     && sensorProps != null && sensorProps.isAnyUdfpsType()) {
-                final long identity2 = Binder.clearCallingIdentity();
                 try {
                     return authenticateWithPrompt(operationId, sensorProps, userId, receiver,
-                            ignoreEnrollmentState);
-                } finally {
-                    Binder.restoreCallingIdentity(identity2);
+                            opPackageName, ignoreEnrollmentState);
+                } catch (PackageManager.NameNotFoundException e) {
+                    Slog.e(TAG, "Invalid package", e);
+                    return -1;
                 }
             }
             return provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
@@ -362,12 +362,15 @@
                 @NonNull final FingerprintSensorPropertiesInternal props,
                 final int userId,
                 final IFingerprintServiceReceiver receiver,
-                boolean ignoreEnrollmentState) {
+                final String opPackageName,
+                boolean ignoreEnrollmentState) throws PackageManager.NameNotFoundException {
 
             final Context context = getUiContext();
+            final Context promptContext = context.createPackageContextAsUser(
+                    opPackageName, 0 /* flags */, UserHandle.getUserHandleForUid(userId));
             final Executor executor = context.getMainExecutor();
 
-            final BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(context)
+            final BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(promptContext)
                     .setTitle(context.getString(R.string.biometric_dialog_default_title))
                     .setSubtitle(context.getString(R.string.fingerprint_dialog_default_subtitle))
                     .setNegativeButton(
@@ -381,8 +384,7 @@
                                     Slog.e(TAG, "Remote exception in negative button onClick()", e);
                                 }
                             })
-                    .setAllowedSensorIds(new ArrayList<>(
-                            Collections.singletonList(props.sensorId)))
+                    .setIsForLegacyFingerprintManager(props.sensorId)
                     .setIgnoreEnrollmentState(ignoreEnrollmentState)
                     .build();
 
@@ -436,8 +438,8 @@
                         }
                     };
 
-            return biometricPrompt.authenticateUserForOperation(
-                    new CancellationSignal(), executor, promptCallback, userId, operationId);
+            return biometricPrompt.authenticateForOperation(
+                    new CancellationSignal(), executor, promptCallback, operationId);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index d0e39cc..03e18a0 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -43,6 +43,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
@@ -59,7 +60,9 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.Optional;
+import java.util.Set;
 import java.util.WeakHashMap;
 
 /**
@@ -139,6 +142,8 @@
     @GuardedBy("mLock")
     private final SparseArray<ProcessRecord> mProcessRecords = new SparseArray<>();
 
+    private Set<Integer> mDeviceStatesAvailableForAppRequests;
+
     public DeviceStateManagerService(@NonNull Context context) {
         this(context, DeviceStatePolicy.Provider
                 .fromResources(context.getResources())
@@ -164,6 +169,10 @@
     public void onStart() {
         publishBinderService(Context.DEVICE_STATE_SERVICE, mBinderService);
         publishLocalService(DeviceStateManagerInternal.class, new LocalService());
+
+        synchronized (mLock) {
+            readStatesAvailableForRequestFromApps();
+        }
     }
 
     @VisibleForTesting
@@ -626,21 +635,78 @@
 
     /**
      * Allow top processes to request or cancel a device state change. If the calling process ID is
-     * not the top app, then check if this process holds the CONTROL_DEVICE_STATE permission.
-     * @param callingPid
+     * not the top app, then check if this process holds the
+     * {@link android.Manifest.permission.CONTROL_DEVICE_STATE} permission. If the calling process
+     * is the top app, check to verify they are requesting a state we've deemed to be able to be
+     * available for an app process to request. States that can be requested are based around
+     * features that we've created that require specific device state overrides.
+     * @param callingPid Process ID that is requesting this state change
+     * @param state state that is being requested.
      */
-    private void checkCanControlDeviceState(int callingPid) {
-        // Allow top processes to request a device state change
-        // If the calling process ID is not the top app, then we check if this process
-        // holds a permission to CONTROL_DEVICE_STATE
+    private void assertCanRequestDeviceState(int callingPid, int state) {
+        final WindowProcessController topApp = mActivityTaskManagerInternal.getTopApp();
+        if (topApp == null || topApp.getPid() != callingPid
+                || !isStateAvailableForAppRequests(state)) {
+            getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
+                    "Permission required to request device state, "
+                            + "or the call must come from the top app "
+                            + "and be a device state that is available for apps to request.");
+        }
+    }
+
+    /**
+     * Checks if the process can control the device state. If the calling process ID is
+     * not the top app, then check if this process holds the CONTROL_DEVICE_STATE permission.
+     *
+     * @param callingPid Process ID that is requesting this state change
+     */
+    private void assertCanControlDeviceState(int callingPid) {
         final WindowProcessController topApp = mActivityTaskManagerInternal.getTopApp();
         if (topApp == null || topApp.getPid() != callingPid) {
             getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
                     "Permission required to request device state, "
-                            + "or the call must come from the top focused app.");
+                            + "or the call must come from the top app.");
         }
     }
 
+    private boolean isStateAvailableForAppRequests(int state) {
+        synchronized (mLock) {
+            return mDeviceStatesAvailableForAppRequests.contains(state);
+        }
+    }
+
+    /**
+     * Adds device state values that are available to be requested by the top level app.
+     */
+    @GuardedBy("mLock")
+    private void readStatesAvailableForRequestFromApps() {
+        mDeviceStatesAvailableForAppRequests = new HashSet<>();
+        String[] availableAppStatesConfigIdentifiers = getContext().getResources()
+                .getStringArray(R.array.config_deviceStatesAvailableForAppRequests);
+        for (int i = 0; i < availableAppStatesConfigIdentifiers.length; i++) {
+            String identifierToFetch = availableAppStatesConfigIdentifiers[i];
+            int configValueIdentifier = getContext().getResources()
+                    .getIdentifier(identifierToFetch, "integer", "android");
+            int state = getContext().getResources().getInteger(configValueIdentifier);
+            if (isValidState(state)) {
+                mDeviceStatesAvailableForAppRequests.add(state);
+            } else {
+                Slog.e(TAG, "Invalid device state was found in the configuration file. State id: "
+                        + state);
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private boolean isValidState(int state) {
+        for (int i = 0; i < mDeviceStates.size(); i++) {
+            if (state == mDeviceStates.valueAt(i).getIdentifier()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private final class DeviceStateProviderListener implements DeviceStateProvider.Listener {
         @Override
         public void onSupportedDeviceStatesChanged(DeviceState[] newDeviceStates) {
@@ -777,7 +843,7 @@
             // Allow top processes to request a device state change
             // If the calling process ID is not the top app, then we check if this process
             // holds a permission to CONTROL_DEVICE_STATE
-            checkCanControlDeviceState(callingPid);
+            assertCanRequestDeviceState(callingPid, state);
 
             if (token == null) {
                 throw new IllegalArgumentException("Request token must not be null.");
@@ -797,7 +863,7 @@
             // Allow top processes to cancel a device state change
             // If the calling process ID is not the top app, then we check if this process
             // holds a permission to CONTROL_DEVICE_STATE
-            checkCanControlDeviceState(callingPid);
+            assertCanControlDeviceState(callingPid);
 
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 698f41f..80ff834 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1389,12 +1389,10 @@
                 // Brightness throttling is needed, so do so quickly.
                 // Later, when throttling is removed, we let other mechanisms decide on speed.
                 slowChange = false;
-                updateScreenBrightnessSetting = true;
             }
             mAppliedThrottling = true;
         } else if (mAppliedThrottling) {
             mAppliedThrottling = false;
-            updateScreenBrightnessSetting = true;
         }
 
         if (updateScreenBrightnessSetting) {
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 34e3ce1..b813995 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -948,7 +948,7 @@
                     pw.println(": ");
                     final List<S> services = mServicesCacheList.valueAt(i);
                     for (int j = 0; j < services.size(); j++) {
-                        S service = services.get(i);
+                        S service = services.get(j);
                         synchronized (service.mLock) {
                             service.dumpLocked(prefix2, pw);
                         }
diff --git a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
index 7bb0d48..e4e9d01 100644
--- a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
@@ -158,6 +158,7 @@
             Collection<GnssListenerRegistration> registrations) {
         boolean fullTracking = false;
         boolean enableCorrVecOutputs = false;
+        int intervalMillis = Integer.MAX_VALUE;
 
         if (mSettingsHelper.isGnssMeasurementsFullTrackingEnabled()) {
             fullTracking = true;
@@ -171,11 +172,13 @@
             if (request.isCorrelationVectorOutputsEnabled()) {
                 enableCorrVecOutputs = true;
             }
+            intervalMillis = Math.min(intervalMillis, request.getIntervalMillis());
         }
 
         return new GnssMeasurementRequest.Builder()
                     .setFullTracking(fullTracking)
                     .setCorrelationVectorOutputsEnabled(enableCorrVecOutputs)
+                    .setIntervalMillis(intervalMillis)
                     .build();
     }
 
diff --git a/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java b/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java
index 4a66516..8732065 100644
--- a/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java
+++ b/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java
@@ -73,7 +73,6 @@
     private final WakeLock mWakeLock;
     private final Handler mHandler;
 
-    @GuardedBy("this")
     private final InjectNtpTimeCallback mCallback;
 
     // flags to trigger NTP when network becomes available
@@ -129,6 +128,8 @@
             return;
         }
         if (!isNetworkConnected()) {
+            // try to inject the cached NTP time
+            injectCachedNtpTime();
             // try again when network is up
             mInjectNtpTimeState = STATE_PENDING_NETWORK;
             return;
@@ -157,23 +158,7 @@
 
             // only update when NTP time is fresh
             // If refreshSuccess is false, cacheAge does not drop down.
-            ntpResult = mNtpTime.getCachedTimeResult();
-            if (ntpResult != null && ntpResult.getAgeMillis() < NTP_INTERVAL) {
-                long time = ntpResult.getTimeMillis();
-                long timeReference = ntpResult.getElapsedRealtimeMillis();
-                long certainty = ntpResult.getCertaintyMillis();
-
-                if (DEBUG) {
-                    long now = System.currentTimeMillis();
-                    Log.d(TAG, "NTP server returned: "
-                            + time + " (" + new Date(time) + ")"
-                            + " ntpResult: " + ntpResult
-                            + " system time offset: " + (time - now));
-                }
-
-                // Ok to cast to int, as can't rollover in practice
-                mHandler.post(() -> mCallback.injectTime(time, timeReference, (int) certainty));
-
+            if (injectCachedNtpTime()) {
                 delay = NTP_INTERVAL;
                 mNtpBackOff.reset();
             } else {
@@ -201,4 +186,26 @@
         // release wake lock held by task
         mWakeLock.release();
     }
+
+    /** Returns true if successfully inject cached NTP time. */
+    private synchronized boolean injectCachedNtpTime() {
+        NtpTrustedTime.TimeResult ntpResult = mNtpTime.getCachedTimeResult();
+        if (ntpResult == null || ntpResult.getAgeMillis() >= NTP_INTERVAL) {
+            return false;
+        }
+
+        long time = ntpResult.getTimeMillis();
+        long timeReference = ntpResult.getElapsedRealtimeMillis();
+        long certainty = ntpResult.getCertaintyMillis();
+
+        if (DEBUG) {
+            long now = System.currentTimeMillis();
+            Log.d(TAG, "NTP server returned: " + time + " (" + new Date(time) + ")"
+                    + " ntpResult: " + ntpResult + " system time offset: " + (time - now));
+        }
+
+        // Ok to cast to int, as can't rollover in practice
+        mHandler.post(() -> mCallback.injectTime(time, timeReference, (int) certainty));
+        return true;
+    }
 }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 549b566..1ea949e 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -174,6 +174,7 @@
 import android.net.INetworkManagementEventObserver;
 import android.net.INetworkPolicyListener;
 import android.net.INetworkPolicyManager;
+import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkIdentity;
@@ -236,6 +237,7 @@
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 import android.util.SparseLongArray;
+import android.util.SparseSetArray;
 import android.util.TypedXmlPullParser;
 import android.util.TypedXmlSerializer;
 import android.util.Xml;
@@ -624,6 +626,9 @@
     /** Map from network ID to last observed roaming state */
     @GuardedBy("mNetworkPoliciesSecondLock")
     private final SparseBooleanArray mNetworkRoaming = new SparseBooleanArray();
+    /** Map from network ID to the last ifaces on it */
+    @GuardedBy("mNetworkPoliciesSecondLock")
+    private SparseSetArray<String> mNetworkToIfaces = new SparseSetArray<>();
 
     /** Map from netId to subId as of last update */
     @GuardedBy("mNetworkPoliciesSecondLock")
@@ -1328,11 +1333,28 @@
         return changed;
     }
 
+    @GuardedBy("mNetworkPoliciesSecondLock")
+    private boolean updateNetworkToIfacesNL(int netId, @NonNull ArraySet<String> newIfaces) {
+        // TODO: Add a facility SparseSetArray.contains(key) to return whether the key exists.
+        final ArraySet<String> lastIfaces = mNetworkToIfaces.get(netId);
+        final boolean changed = lastIfaces == null ? true : !lastIfaces.equals(newIfaces);
+
+        if (changed) {
+            // Changed on the same network should remove last ifaces and add new ifaces.
+            // TODO: Add a facility SparseSetArray.put(key, value) for replacing the
+            //       value for a given key.
+            mNetworkToIfaces.remove(netId);
+            for (String iface : newIfaces) {
+                mNetworkToIfaces.add(netId, iface);
+            }
+        }
+        return changed;
+    }
+
     private final NetworkCallback mNetworkCallback = new NetworkCallback() {
         @Override
-        public void onCapabilitiesChanged(Network network,
-                NetworkCapabilities networkCapabilities) {
-            if (network == null || networkCapabilities == null) return;
+        public void onCapabilitiesChanged(@NonNull Network network,
+                @NonNull NetworkCapabilities networkCapabilities) {
 
             synchronized (mNetworkPoliciesSecondLock) {
                 final boolean newMetered = !networkCapabilities
@@ -1351,6 +1373,25 @@
                 }
             }
         }
+
+        @Override
+        public void onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkProperties lp) {
+            synchronized (mNetworkPoliciesSecondLock) {
+                final ArraySet<String> newIfaces = new ArraySet<>(lp.getAllInterfaceNames());
+                final boolean ifacesChanged = updateNetworkToIfacesNL(network.getNetId(),
+                        newIfaces);
+                if (ifacesChanged) {
+                    updateNetworkRulesNL();
+                }
+            }
+        }
+
+        @Override
+        public void onLost(@NonNull Network network) {
+            synchronized (mNetworkPoliciesSecondLock) {
+                mNetworkToIfaces.remove(network.getNetId());
+            }
+        }
     };
 
     /**
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 0309ddf..0c11d8f 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -252,6 +252,7 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 import android.util.StatsEvent;
 import android.util.TypedXmlPullParser;
 import android.util.TypedXmlSerializer;
@@ -284,6 +285,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.util.function.TriPredicate;
+import com.android.internal.widget.LockPatternUtils;
 import com.android.server.DeviceIdleInternal;
 import com.android.server.EventLogTags;
 import com.android.server.IoThread;
@@ -1923,6 +1925,54 @@
     private SettingsObserver mSettingsObserver;
     protected ZenModeHelper mZenModeHelper;
 
+    protected class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
+
+        SparseBooleanArray mUserInLockDownMode = new SparseBooleanArray();
+        boolean mIsInLockDownMode = false;
+
+        StrongAuthTracker(Context context) {
+            super(context);
+        }
+
+        private boolean containsFlag(int haystack, int needle) {
+            return (haystack & needle) != 0;
+        }
+
+        public boolean isInLockDownMode() {
+            return mIsInLockDownMode;
+        }
+
+        @Override
+        public synchronized void onStrongAuthRequiredChanged(int userId) {
+            boolean userInLockDownModeNext = containsFlag(getStrongAuthForUser(userId),
+                    STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+            mUserInLockDownMode.put(userId, userInLockDownModeNext);
+            boolean isInLockDownModeNext = mUserInLockDownMode.indexOfValue(true) != -1;
+
+            if (mIsInLockDownMode == isInLockDownModeNext) {
+                return;
+            }
+
+            if (isInLockDownModeNext) {
+                cancelNotificationsWhenEnterLockDownMode();
+            }
+
+            // When the mIsInLockDownMode is true, both notifyPostedLocked and
+            // notifyRemovedLocked will be dismissed. So we shall call
+            // cancelNotificationsWhenEnterLockDownMode before we set mIsInLockDownMode
+            // as true and call postNotificationsWhenExitLockDownMode after we set
+            // mIsInLockDownMode as false.
+            mIsInLockDownMode = isInLockDownModeNext;
+
+            if (!isInLockDownModeNext) {
+                postNotificationsWhenExitLockDownMode();
+            }
+        }
+    }
+
+    private LockPatternUtils mLockPatternUtils;
+    private StrongAuthTracker mStrongAuthTracker;
+
     public NotificationManagerService(Context context) {
         this(context,
                 new NotificationRecordLoggerImpl(),
@@ -1952,6 +2002,11 @@
     }
 
     @VisibleForTesting
+    void setStrongAuthTracker(StrongAuthTracker strongAuthTracker) {
+        mStrongAuthTracker = strongAuthTracker;
+    }
+
+    @VisibleForTesting
     void setKeyguardManager(KeyguardManager keyguardManager) {
         mKeyguardManager = keyguardManager;
     }
@@ -2145,6 +2200,8 @@
         mPlatformCompat = IPlatformCompat.Stub.asInterface(
                 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
 
+        mLockPatternUtils = new LockPatternUtils(getContext());
+        mStrongAuthTracker = new StrongAuthTracker(getContext());
         mUiHandler = new Handler(UiThread.get().getLooper());
         String[] extractorNames;
         try {
@@ -2641,6 +2698,7 @@
                 bubbsExtractor.setShortcutHelper(mShortcutHelper);
             }
             registerNotificationPreferencesPullers();
+            mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
         } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
             // This observer will force an update when observe is called, causing us to
             // bind to listener services.
@@ -9537,6 +9595,29 @@
         }
     }
 
+    private void cancelNotificationsWhenEnterLockDownMode() {
+        synchronized (mNotificationLock) {
+            int numNotifications = mNotificationList.size();
+            for (int i = 0; i < numNotifications; i++) {
+                NotificationRecord rec = mNotificationList.get(i);
+                mListeners.notifyRemovedLocked(rec, REASON_CANCEL_ALL,
+                        rec.getStats());
+            }
+
+        }
+    }
+
+    private void postNotificationsWhenExitLockDownMode() {
+        synchronized (mNotificationLock) {
+            int numNotifications = mNotificationList.size();
+            for (int i = 0; i < numNotifications; i++) {
+                NotificationRecord rec = mNotificationList.get(i);
+                mListeners.notifyPostedLocked(rec, rec);
+            }
+
+        }
+    }
+
     private void updateNotificationPulse() {
         synchronized (mNotificationLock) {
             updateLightsLocked();
@@ -9753,6 +9834,10 @@
                 rankings.toArray(new NotificationListenerService.Ranking[0]));
     }
 
+    boolean isInLockDownMode() {
+        return mStrongAuthTracker.isInLockDownMode();
+    }
+
     boolean hasCompanionDevice(ManagedServiceInfo info) {
         if (mCompanionManager == null) {
             mCompanionManager = getCompanionManager();
@@ -10804,8 +10889,12 @@
          *                           targetting <= O_MR1
          */
         @GuardedBy("mNotificationLock")
-        private void notifyPostedLocked(NotificationRecord r, NotificationRecord old,
+        void notifyPostedLocked(NotificationRecord r, NotificationRecord old,
                 boolean notifyAllListeners) {
+            if (isInLockDownMode()) {
+                return;
+            }
+
             try {
                 // Lazily initialized snapshots of the notification.
                 StatusBarNotification sbn = r.getSbn();
@@ -10908,6 +10997,10 @@
         @GuardedBy("mNotificationLock")
         public void notifyRemovedLocked(NotificationRecord r, int reason,
                 NotificationStats notificationStats) {
+            if (isInLockDownMode()) {
+                return;
+            }
+
             final StatusBarNotification sbn = r.getSbn();
 
             // make a copy in case changes are made to the underlying Notification object
@@ -10953,6 +11046,10 @@
          */
         @GuardedBy("mNotificationLock")
         public void notifyRankingUpdateLocked(List<NotificationRecord> changedHiddenNotifications) {
+            if (isInLockDownMode()) {
+                return;
+            }
+
             boolean isHiddenRankingUpdate = changedHiddenNotifications != null
                     && changedHiddenNotifications.size() > 0;
             // TODO (b/73052211): if the ranking update changed the notification type,
diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java
index dff7100..f757405 100644
--- a/services/core/java/com/android/server/pm/AppsFilterImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java
@@ -61,6 +61,7 @@
 import com.android.server.pm.pkg.component.ParsedIntentInfo;
 import com.android.server.pm.pkg.component.ParsedMainComponent;
 import com.android.server.pm.pkg.component.ParsedProvider;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
 import com.android.server.utils.Snappable;
 import com.android.server.utils.SnapshotCache;
 import com.android.server.utils.Watchable;
@@ -179,7 +180,6 @@
     private final boolean mSystemAppsQueryable;
     private final FeatureConfig mFeatureConfig;
     private final OverlayReferenceMapper mOverlayReferenceMapper;
-    private final StateProvider mStateProvider;
     private SigningDetails mSystemSigningDetails;
 
     @GuardedBy("mLock")
@@ -189,10 +189,13 @@
 
     private final Object mCacheLock = new Object();
 
+    private final boolean mIsSnapshot;
+
     /**
      * This structure maps uid -> uid and indicates whether access from the first should be
      * filtered to the second. It's essentially a cache of the
-     * {@link #shouldFilterApplicationInternal(int, Object, PackageStateInternal, int)} call.
+     * {@link #shouldFilterApplicationInternal(PackageDataSnapshot, int, Object,
+     * PackageStateInternal, int)} call.
      * NOTE: It can only be relied upon after the system is ready to avoid unnecessary update on
      * initial scam and is empty until {@link #mSystemReady} is true.
      */
@@ -282,8 +285,7 @@
     }
 
     @VisibleForTesting(visibility = PRIVATE)
-    AppsFilterImpl(StateProvider stateProvider,
-            FeatureConfig featureConfig,
+    AppsFilterImpl(FeatureConfig featureConfig,
             String[] forceQueryableList,
             boolean systemAppsQueryable,
             @Nullable OverlayReferenceMapper.Provider overlayProvider,
@@ -293,7 +295,6 @@
         mSystemAppsQueryable = systemAppsQueryable;
         mOverlayReferenceMapper = new OverlayReferenceMapper(true /*deferRebuild*/,
                 overlayProvider);
-        mStateProvider = stateProvider;
         mBackgroundExecutor = backgroundExecutor;
         mShouldFilterCache = new WatchedSparseBooleanMatrix();
         mShouldFilterCacheSnapshot = new SnapshotCache.Auto<>(
@@ -323,6 +324,7 @@
                 mProtectedBroadcasts, mProtectedBroadcasts, "AppsFilter.mProtectedBroadcasts");
 
         mSnapshot = makeCache();
+        mIsSnapshot = false;
     }
 
     /**
@@ -352,7 +354,6 @@
         mSystemAppsQueryable = orig.mSystemAppsQueryable;
         mFeatureConfig = orig.mFeatureConfig;
         mOverlayReferenceMapper = orig.mOverlayReferenceMapper;
-        mStateProvider = orig.mStateProvider;
         mSystemSigningDetails = orig.mSystemSigningDetails;
         synchronized (orig.mCacheLock) {
             mShouldFilterCache = orig.mShouldFilterCacheSnapshot.snapshot();
@@ -361,7 +362,8 @@
 
         mBackgroundExecutor = null;
         mSnapshot = new SnapshotCache.Sealed<>();
-        mSystemReady = true;
+        mSystemReady = orig.mSystemReady;
+        mIsSnapshot = true;
     }
 
     /**
@@ -373,23 +375,6 @@
         return mSnapshot.snapshot();
     }
 
-    /**
-     * Provides system state to AppsFilter via {@link CurrentStateCallback} after properly guarding
-     * the data with the package lock.
-     *
-     * Don't call {@link #runWithState} with {@link #mCacheLock} held.
-     */
-    @VisibleForTesting(visibility = PRIVATE)
-    public interface StateProvider {
-        void runWithState(CurrentStateCallback callback);
-
-        interface CurrentStateCallback {
-            void currentState(ArrayMap<String, ? extends PackageStateInternal> settings,
-                    Collection<SharedUserSetting> sharedUserSettings,
-                    UserInfo[] users);
-        }
-    }
-
     @VisibleForTesting(visibility = PRIVATE)
     public interface FeatureConfig {
 
@@ -517,12 +502,13 @@
 
         @Override
         public void onCompatChange(String packageName) {
-            AndroidPackage pkg = mPmInternal.getPackage(packageName);
+            PackageDataSnapshot snapshot = mPmInternal.snapshot();
+            AndroidPackage pkg = snapshot.getPackage(packageName);
             if (pkg == null) {
                 return;
             }
             updateEnabledState(pkg);
-            mAppsFilter.updateShouldFilterCacheForPackage(packageName);
+            mAppsFilter.updateShouldFilterCacheForPackage(snapshot, packageName);
         }
 
         private void updateEnabledState(@NonNull AndroidPackage pkg) {
@@ -574,14 +560,7 @@
                 forcedQueryablePackageNames[i] = forcedQueryablePackageNames[i].intern();
             }
         }
-        final StateProvider stateProvider = command -> {
-            synchronized (injector.getLock()) {
-                command.currentState(injector.getSettings().getPackagesLocked().untrackedStorage(),
-                        injector.getSettings().getAllSharedUsersLPw(),
-                        injector.getUserManagerInternal().getUserInfos());
-            }
-        };
-        AppsFilterImpl appsFilter = new AppsFilterImpl(stateProvider, featureConfig,
+        AppsFilterImpl appsFilter = new AppsFilterImpl(featureConfig,
                 forcedQueryablePackageNames, forceSystemAppsQueryable, null,
                 injector.getBackgroundExecutor());
         featureConfig.setAppsFilter(appsFilter);
@@ -754,12 +733,11 @@
         return changed;
     }
 
-    public void onSystemReady() {
+    public void onSystemReady(PackageManagerInternal pmInternal) {
         mOverlayReferenceMapper.rebuildIfDeferred();
         mFeatureConfig.onSystemReady();
 
-        updateEntireShouldFilterCacheAsync();
-        onChanged();
+        updateEntireShouldFilterCacheAsync(pmInternal);
         mSystemReady = true;
     }
 
@@ -769,39 +747,41 @@
      * @param newPkgSetting the new setting being added
      * @param isReplace     if the package is being replaced and may need extra cleanup.
      */
-    public void addPackage(PackageStateInternal newPkgSetting, boolean isReplace) {
+    public void addPackage(PackageDataSnapshot snapshot, PackageStateInternal newPkgSetting,
+            boolean isReplace) {
         if (DEBUG_TRACING) {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage");
         }
         try {
             if (isReplace) {
                 // let's first remove any prior rules for this package
-                removePackage(newPkgSetting, true /*isReplace*/);
+                removePackage(snapshot, newPkgSetting, true /*isReplace*/);
             }
-            mStateProvider.runWithState((settings, sharedUserSettings, users) -> {
-                ArraySet<String> additionalChangedPackages =
-                        addPackageInternal(newPkgSetting, settings);
-                if (mSystemReady) {
-                    updateShouldFilterCacheForPackage(null, newPkgSetting,
+            final ArrayMap<String, ? extends PackageStateInternal> settings =
+                    snapshot.getPackageStates();
+            final UserInfo[] users = snapshot.getUserInfos();
+            final ArraySet<String> additionalChangedPackages =
+                    addPackageInternal(newPkgSetting, settings);
+            if (mSystemReady) {
+                synchronized (mCacheLock) {
+                    updateShouldFilterCacheForPackage(snapshot, null, newPkgSetting,
                             settings, users, USER_ALL, settings.size());
                     if (additionalChangedPackages != null) {
                         for (int index = 0; index < additionalChangedPackages.size(); index++) {
                             String changedPackage = additionalChangedPackages.valueAt(index);
-                            PackageStateInternal changedPkgSetting =
-                                    settings.get(changedPackage);
+                            PackageStateInternal changedPkgSetting = settings.get(changedPackage);
                             if (changedPkgSetting == null) {
                                 // It's possible for the overlay mapper to know that an actor
                                 // package changed via an explicit reference, even if the actor
                                 // isn't installed, so skip if that's the case.
                                 continue;
                             }
-
-                            updateShouldFilterCacheForPackage(null, changedPkgSetting,
+                            updateShouldFilterCacheForPackage(snapshot, null, changedPkgSetting,
                                     settings, users, USER_ALL, settings.size());
                         }
                     }
-                } // else, rebuild entire cache when system is ready
-            });
+                }
+            } // else, rebuild entire cache when system is ready
         } finally {
             onChanged();
             if (DEBUG_TRACING) {
@@ -941,30 +921,32 @@
         }
     }
 
-    private void updateEntireShouldFilterCache() {
-        updateEntireShouldFilterCache(USER_ALL);
+    private void updateEntireShouldFilterCache(PackageDataSnapshot snapshot) {
+        updateEntireShouldFilterCache(snapshot, USER_ALL);
     }
 
-    private void updateEntireShouldFilterCache(int subjectUserId) {
-        mStateProvider.runWithState((settings, sharedUserSettings, users) -> {
-            int userId = USER_NULL;
-            for (int u = 0; u < users.length; u++) {
-                if (subjectUserId == users[u].id) {
-                    userId = subjectUserId;
-                    break;
-                }
+    private void updateEntireShouldFilterCache(PackageDataSnapshot snapshot, int subjectUserId) {
+        final ArrayMap<String, ? extends PackageStateInternal> settings =
+                snapshot.getPackageStates();
+        final UserInfo[] users = snapshot.getUserInfos();
+        int userId = USER_NULL;
+        for (int u = 0; u < users.length; u++) {
+            if (subjectUserId == users[u].id) {
+                userId = subjectUserId;
+                break;
             }
-            if (userId == USER_NULL) {
-                Slog.e(TAG, "We encountered a new user that isn't a member of known users, "
-                        + "updating the whole cache");
-                userId = USER_ALL;
-            }
-            updateEntireShouldFilterCacheInner(settings, users, userId);
-        });
+        }
+        if (userId == USER_NULL) {
+            Slog.e(TAG, "We encountered a new user that isn't a member of known users, "
+                    + "updating the whole cache");
+            userId = USER_ALL;
+        }
+        updateEntireShouldFilterCacheInner(snapshot, settings, users, userId);
+
         onChanged();
     }
 
-    private void updateEntireShouldFilterCacheInner(
+    private void updateEntireShouldFilterCacheInner(PackageDataSnapshot snapshot,
             ArrayMap<String, ? extends PackageStateInternal> settings,
             UserInfo[] users,
             int subjectUserId) {
@@ -973,67 +955,42 @@
                 mShouldFilterCache.clear();
             }
             mShouldFilterCache.setCapacity(users.length * settings.size());
-        }
-        for (int i = settings.size() - 1; i >= 0; i--) {
-            updateShouldFilterCacheForPackage(
-                    null /*skipPackage*/, settings.valueAt(i), settings, users,
-                    subjectUserId, i);
+            for (int i = settings.size() - 1; i >= 0; i--) {
+                updateShouldFilterCacheForPackage(snapshot,
+                        null /*skipPackage*/, settings.valueAt(i), settings, users,
+                        subjectUserId, i);
+            }
         }
     }
 
-    private void updateEntireShouldFilterCacheAsync() {
+    private void updateEntireShouldFilterCacheAsync(PackageManagerInternal pmInternal) {
         mBackgroundExecutor.execute(() -> {
-            final ArrayMap<String, PackageStateInternal> settingsCopy = new ArrayMap<>();
-            final Collection<SharedUserSetting> sharedUserSettingsCopy = new ArraySet<>();
             final ArrayMap<String, AndroidPackage> packagesCache = new ArrayMap<>();
             final UserInfo[][] usersRef = new UserInfo[1][];
-            mStateProvider.runWithState((settings, sharedUserSettings, users) -> {
-                packagesCache.ensureCapacity(settings.size());
-                settingsCopy.putAll(settings);
-                usersRef[0] = users;
-                // store away the references to the immutable packages, since settings are retained
-                // during updates.
-                for (int i = 0, max = settings.size(); i < max; i++) {
-                    final AndroidPackage pkg = settings.valueAt(i).getPkg();
-                    packagesCache.put(settings.keyAt(i), pkg);
-                }
-                sharedUserSettingsCopy.addAll(sharedUserSettings);
-            });
+            final PackageDataSnapshot snapshot = pmInternal.snapshot();
+            final ArrayMap<String, ? extends PackageStateInternal> settings =
+                    snapshot.getPackageStates();
+            final UserInfo[] users = snapshot.getUserInfos();
 
-            boolean[] changed = new boolean[1];
-            // We have a cache, let's make sure the world hasn't changed out from under us.
-            mStateProvider.runWithState((settings, sharedUserSettings, users) -> {
-                if (settings.size() != settingsCopy.size()) {
-                    changed[0] = true;
-                    return;
-                }
-                for (int i = 0, max = settings.size(); i < max; i++) {
-                    final AndroidPackage pkg = settings.valueAt(i).getPkg();
-                    if (!Objects.equals(pkg, packagesCache.get(settings.keyAt(i)))) {
-                        changed[0] = true;
-                        return;
-                    }
-                }
-            });
-            if (changed[0]) {
-                // Something has changed, just update the cache inline with the lock held
-                updateEntireShouldFilterCache();
-                if (DEBUG_LOGGING) {
-                    Slog.i(TAG, "Rebuilding cache with lock due to package change.");
-                }
-            } else {
-                updateEntireShouldFilterCacheInner(settingsCopy,
-                        usersRef[0], USER_ALL);
-                onChanged();
+            packagesCache.ensureCapacity(settings.size());
+            usersRef[0] = users;
+            // store away the references to the immutable packages, since settings are retained
+            // during updates.
+            for (int i = 0, max = settings.size(); i < max; i++) {
+                final AndroidPackage pkg = settings.valueAt(i).getPkg();
+                packagesCache.put(settings.keyAt(i), pkg);
             }
+
+            updateEntireShouldFilterCacheInner(snapshot, settings, usersRef[0], USER_ALL);
+            onChanged();
         });
     }
 
-    public void onUserCreated(int newUserId) {
+    public void onUserCreated(PackageDataSnapshot snapshot, int newUserId) {
         if (!mSystemReady) {
             return;
         }
-        updateEntireShouldFilterCache(newUserId);
+        updateEntireShouldFilterCache(snapshot, newUserId);
     }
 
     public void onUserDeleted(@UserIdInt int userId) {
@@ -1044,19 +1001,24 @@
         onChanged();
     }
 
-    private void updateShouldFilterCacheForPackage(String packageName) {
-        mStateProvider.runWithState((settings, sharedUserSettings, users) -> {
-            if (!mSystemReady) {
-                return;
-            }
-            updateShouldFilterCacheForPackage(null /* skipPackage */,
+    private void updateShouldFilterCacheForPackage(PackageDataSnapshot snapshot,
+            String packageName) {
+        if (!mSystemReady) {
+            return;
+        }
+        final ArrayMap<String, ? extends PackageStateInternal> settings =
+                snapshot.getPackageStates();
+        final UserInfo[] users = snapshot.getUserInfos();
+        synchronized (mCacheLock) {
+            updateShouldFilterCacheForPackage(snapshot, null /* skipPackage */,
                     settings.get(packageName), settings, users, USER_ALL,
                     settings.size() /*maxIndex*/);
-        });
+        }
         onChanged();
     }
 
-    private void updateShouldFilterCacheForPackage(
+    @GuardedBy("mCacheLock")
+    private void updateShouldFilterCacheForPackage(PackageDataSnapshot snapshot,
             @Nullable String skipPackageName, PackageStateInternal subjectSetting, ArrayMap<String,
             ? extends PackageStateInternal> allSettings, UserInfo[] allUsers, int subjectUserId,
             int maxIndex) {
@@ -1072,31 +1034,30 @@
             }
             if (subjectUserId == USER_ALL) {
                 for (int su = 0; su < allUsers.length; su++) {
-                    updateShouldFilterCacheForUser(subjectSetting, allUsers, otherSetting,
+                    updateShouldFilterCacheForUser(snapshot, subjectSetting, allUsers, otherSetting,
                             allUsers[su].id);
                 }
             } else {
-                updateShouldFilterCacheForUser(subjectSetting, allUsers, otherSetting,
+                updateShouldFilterCacheForUser(snapshot, subjectSetting, allUsers, otherSetting,
                         subjectUserId);
             }
         }
     }
 
-    private void updateShouldFilterCacheForUser(
+    @GuardedBy("mCacheLock")
+    private void updateShouldFilterCacheForUser(PackageDataSnapshot snapshot,
             PackageStateInternal subjectSetting, UserInfo[] allUsers,
             PackageStateInternal otherSetting, int subjectUserId) {
         for (int ou = 0; ou < allUsers.length; ou++) {
             int otherUser = allUsers[ou].id;
             int subjectUid = UserHandle.getUid(subjectUserId, subjectSetting.getAppId());
             int otherUid = UserHandle.getUid(otherUser, otherSetting.getAppId());
-            final boolean shouldFilterSubjectToOther = shouldFilterApplicationInternal(
+            final boolean shouldFilterSubjectToOther = shouldFilterApplicationInternal(snapshot,
                     subjectUid, subjectSetting, otherSetting, otherUser);
-            final boolean shouldFilterOtherToSubject = shouldFilterApplicationInternal(
+            final boolean shouldFilterOtherToSubject = shouldFilterApplicationInternal(snapshot,
                     otherUid, otherSetting, subjectSetting, subjectUserId);
-            synchronized (mCacheLock) {
-                mShouldFilterCache.put(subjectUid, otherUid, shouldFilterSubjectToOther);
-                mShouldFilterCache.put(otherUid, subjectUid, shouldFilterOtherToSubject);
-            }
+            mShouldFilterCache.put(subjectUid, otherUid, shouldFilterSubjectToOther);
+            mShouldFilterCache.put(otherUid, subjectUid, shouldFilterOtherToSubject);
         }
     }
 
@@ -1179,14 +1140,17 @@
             }
         }
         mQueriesViaComponentRequireRecompute = false;
+        onChanged();
     }
 
     /**
-     * See {@link AppsFilterSnapshot#getVisibilityAllowList(PackageStateInternal, int[], ArrayMap)}
+     * See {@link AppsFilterSnapshot#getVisibilityAllowList(PackageDataSnapshot,
+     * PackageStateInternal, int[], ArrayMap)}
      */
     @Override
     @Nullable
-    public SparseArray<int[]> getVisibilityAllowList(PackageStateInternal setting, int[] users,
+    public SparseArray<int[]> getVisibilityAllowList(PackageDataSnapshot snapshot,
+            PackageStateInternal setting, int[] users,
             ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
         synchronized (mLock) {
             if (mForceQueryable.contains(setting.getAppId())) {
@@ -1211,7 +1175,8 @@
                     continue;
                 }
                 final int existingUid = UserHandle.getUid(userId, existingAppId);
-                if (!shouldFilterApplication(existingUid, existingSetting, setting, userId)) {
+                if (!shouldFilterApplication(snapshot, existingUid, existingSetting, setting,
+                        userId)) {
                     if (buffer == null) {
                         buffer = new int[appIds.length];
                     }
@@ -1232,19 +1197,21 @@
      */
     @VisibleForTesting(visibility = PRIVATE)
     @Nullable
-    SparseArray<int[]> getVisibilityAllowList(PackageStateInternal setting, int[] users,
+    SparseArray<int[]> getVisibilityAllowList(PackageDataSnapshot snapshot,
+            PackageStateInternal setting, int[] users,
             WatchedArrayMap<String, ? extends PackageStateInternal> existingSettings) {
-        return getVisibilityAllowList(setting, users, existingSettings.untrackedStorage());
+        return getVisibilityAllowList(snapshot, setting, users,
+                existingSettings.untrackedStorage());
     }
 
     /**
-     * Equivalent to calling {@link #addPackage(PackageStateInternal, boolean)} with
-     * {@code isReplace} equal to {@code false}.
+     * Equivalent to calling {@link #addPackage(PackageDataSnapshot, PackageStateInternal, boolean)}
+     * with {@code isReplace} equal to {@code false}.
      *
-     * @see AppsFilterImpl#addPackage(PackageStateInternal, boolean)
+     * @see AppsFilterImpl#addPackage(PackageDataSnapshot, PackageStateInternal, boolean)
      */
-    public void addPackage(PackageStateInternal newPkgSetting) {
-        addPackage(newPkgSetting, false /* isReplace */);
+    public void addPackage(PackageDataSnapshot snapshot, PackageStateInternal newPkgSetting) {
+        addPackage(snapshot, newPkgSetting, false /* isReplace */);
     }
 
     /**
@@ -1253,119 +1220,122 @@
      * @param setting   the setting of the package being removed.
      * @param isReplace if the package is being replaced.
      */
-    public void removePackage(PackageStateInternal setting, boolean isReplace) {
-        mStateProvider.runWithState((settings, sharedUserSettings, users) -> {
-            final ArraySet<String> additionalChangedPackages;
-            final int userCount = users.length;
-            synchronized (mLock) {
-                for (int u = 0; u < userCount; u++) {
-                    final int userId = users[u].id;
-                    final int removingUid = UserHandle.getUid(userId, setting.getAppId());
-                    mImplicitlyQueryable.remove(removingUid);
-                    for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) {
-                        mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i),
-                                removingUid);
-                    }
-
-                    if (isReplace) {
-                        continue;
-                    }
-
-                    mRetainedImplicitlyQueryable.remove(removingUid);
-                    for (int i = mRetainedImplicitlyQueryable.size() - 1; i >= 0; i--) {
-                        mRetainedImplicitlyQueryable.remove(
-                                mRetainedImplicitlyQueryable.keyAt(i), removingUid);
-                    }
+    public void removePackage(PackageDataSnapshot snapshot, PackageStateInternal setting,
+            boolean isReplace) {
+        final ArraySet<String> additionalChangedPackages;
+        final ArrayMap<String, ? extends PackageStateInternal> settings =
+                snapshot.getPackageStates();
+        final UserInfo[] users = snapshot.getUserInfos();
+        final Collection<SharedUserSetting> sharedUserSettings = snapshot.getAllSharedUsers();
+        final int userCount = users.length;
+        synchronized (mLock) {
+            for (int u = 0; u < userCount; u++) {
+                final int userId = users[u].id;
+                final int removingUid = UserHandle.getUid(userId, setting.getAppId());
+                mImplicitlyQueryable.remove(removingUid);
+                for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) {
+                    mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i),
+                            removingUid);
                 }
 
-                if (!mQueriesViaComponentRequireRecompute) {
-                    mQueriesViaComponent.remove(setting.getAppId());
-                    for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
-                        mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i),
-                                setting.getAppId());
-                    }
-                }
-                mQueriesViaPackage.remove(setting.getAppId());
-                for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
-                    mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i),
-                            setting.getAppId());
-                }
-                mQueryableViaUsesLibrary.remove(setting.getAppId());
-                for (int i = mQueryableViaUsesLibrary.size() - 1; i >= 0; i--) {
-                    mQueryableViaUsesLibrary.remove(mQueryableViaUsesLibrary.keyAt(i),
-                            setting.getAppId());
+                if (isReplace) {
+                    continue;
                 }
 
-                mForceQueryable.remove(setting.getAppId());
-
-                if (setting.getPkg() != null
-                        && !setting.getPkg().getProtectedBroadcasts().isEmpty()) {
-                    final String removingPackageName = setting.getPkg().getPackageName();
-                    final ArrayList<String> protectedBroadcasts = new ArrayList<>();
-                    protectedBroadcasts.addAll(mProtectedBroadcasts.untrackedStorage());
-                    collectProtectedBroadcasts(settings, removingPackageName);
-                    if (!mProtectedBroadcasts.containsAll(protectedBroadcasts)) {
-                        mQueriesViaComponentRequireRecompute = true;
-                    }
+                mRetainedImplicitlyQueryable.remove(removingUid);
+                for (int i = mRetainedImplicitlyQueryable.size() - 1; i >= 0; i--) {
+                    mRetainedImplicitlyQueryable.remove(
+                            mRetainedImplicitlyQueryable.keyAt(i), removingUid);
                 }
             }
 
-            additionalChangedPackages = mOverlayReferenceMapper.removePkg(setting.getPackageName());
-            mFeatureConfig.updatePackageState(setting, true /*removed*/);
-
-            // After removing all traces of the package, if it's part of a shared user,
-            // re-add other
-            // shared user members to re-establish visibility between them and other
-            // packages.
-            // NOTE: this must come after all removals from data structures but before we
-            // update the
-            //       cache
-            if (setting.hasSharedUser()) {
-                final ArraySet<? extends PackageStateInternal> sharedUserPackages =
-                        getSharedUserPackages(setting.getSharedUserAppId(), sharedUserSettings);
-                for (int i = sharedUserPackages.size() - 1; i >= 0; i--) {
-                    if (sharedUserPackages.valueAt(i) == setting) {
-                        continue;
-                    }
-                    addPackageInternal(
-                            sharedUserPackages.valueAt(i), settings);
+            if (!mQueriesViaComponentRequireRecompute) {
+                mQueriesViaComponent.remove(setting.getAppId());
+                for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
+                    mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i),
+                            setting.getAppId());
                 }
             }
+            mQueriesViaPackage.remove(setting.getAppId());
+            for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
+                mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i),
+                        setting.getAppId());
+            }
+            mQueryableViaUsesLibrary.remove(setting.getAppId());
+            for (int i = mQueryableViaUsesLibrary.size() - 1; i >= 0; i--) {
+                mQueryableViaUsesLibrary.remove(mQueryableViaUsesLibrary.keyAt(i),
+                        setting.getAppId());
+            }
 
-            removeAppIdFromVisibilityCache(setting.getAppId());
-            if (mSystemReady && setting.hasSharedUser()) {
-                final ArraySet<? extends PackageStateInternal> sharedUserPackages =
-                        getSharedUserPackages(setting.getSharedUserAppId(), sharedUserSettings);
-                for (int i = sharedUserPackages.size() - 1; i >= 0; i--) {
-                    PackageStateInternal siblingSetting =
-                            sharedUserPackages.valueAt(i);
-                    if (siblingSetting == setting) {
-                        continue;
-                    }
-                    updateShouldFilterCacheForPackage(
+            mForceQueryable.remove(setting.getAppId());
+
+            if (setting.getPkg() != null
+                    && !setting.getPkg().getProtectedBroadcasts().isEmpty()) {
+                final String removingPackageName = setting.getPkg().getPackageName();
+                final ArrayList<String> protectedBroadcasts = new ArrayList<>();
+                protectedBroadcasts.addAll(mProtectedBroadcasts.untrackedStorage());
+                collectProtectedBroadcasts(settings, removingPackageName);
+                if (!mProtectedBroadcasts.containsAll(protectedBroadcasts)) {
+                    mQueriesViaComponentRequireRecompute = true;
+                }
+            }
+        }
+
+        additionalChangedPackages = mOverlayReferenceMapper.removePkg(setting.getPackageName());
+        mFeatureConfig.updatePackageState(setting, true /*removed*/);
+
+        // After removing all traces of the package, if it's part of a shared user, re-add other
+        // shared user members to re-establish visibility between them and other packages.
+        // NOTE: this must come after all removals from data structures but before we update the
+        // cache
+        if (setting.hasSharedUser()) {
+            final ArraySet<? extends PackageStateInternal> sharedUserPackages =
+                    getSharedUserPackages(setting.getSharedUserAppId(), sharedUserSettings);
+            for (int i = sharedUserPackages.size() - 1; i >= 0; i--) {
+                if (sharedUserPackages.valueAt(i) == setting) {
+                    continue;
+                }
+                addPackageInternal(
+                        sharedUserPackages.valueAt(i), settings);
+            }
+        }
+
+        removeAppIdFromVisibilityCache(setting.getAppId());
+        if (mSystemReady && setting.hasSharedUser()) {
+            final ArraySet<? extends PackageStateInternal> sharedUserPackages =
+                    getSharedUserPackages(setting.getSharedUserAppId(), sharedUserSettings);
+            for (int i = sharedUserPackages.size() - 1; i >= 0; i--) {
+                PackageStateInternal siblingSetting =
+                        sharedUserPackages.valueAt(i);
+                if (siblingSetting == setting) {
+                    continue;
+                }
+                synchronized (mCacheLock) {
+                    updateShouldFilterCacheForPackage(snapshot,
                             setting.getPackageName(), siblingSetting, settings,
                             users, USER_ALL, settings.size());
                 }
             }
+        }
 
-            if (mSystemReady) {
-                if (additionalChangedPackages != null) {
-                    for (int index = 0; index < additionalChangedPackages.size(); index++) {
-                        String changedPackage = additionalChangedPackages.valueAt(index);
-                        PackageStateInternal changedPkgSetting = settings.get(changedPackage);
-                        if (changedPkgSetting == null) {
-                            // It's possible for the overlay mapper to know that an actor
-                            // package changed via an explicit reference, even if the actor
-                            // isn't installed, so skip if that's the case.
-                            continue;
-                        }
-
-                        updateShouldFilterCacheForPackage(null, changedPkgSetting,
+        if (mSystemReady) {
+            if (additionalChangedPackages != null) {
+                for (int index = 0; index < additionalChangedPackages.size(); index++) {
+                    String changedPackage = additionalChangedPackages.valueAt(index);
+                    PackageStateInternal changedPkgSetting = settings.get(changedPackage);
+                    if (changedPkgSetting == null) {
+                        // It's possible for the overlay mapper to know that an actor
+                        // package changed via an explicit reference, even if the actor
+                        // isn't installed, so skip if that's the case.
+                        continue;
+                    }
+                    synchronized (mCacheLock) {
+                        updateShouldFilterCacheForPackage(snapshot, null, changedPkgSetting,
                                 settings, users, USER_ALL, settings.size());
                     }
                 }
             }
-        });
+        }
         onChanged();
     }
 
@@ -1382,12 +1352,12 @@
 
     /**
      * See
-     * {@link AppsFilterSnapshot#shouldFilterApplication(int, Object, PackageStateInternal,
-     * int)}
+     * {@link AppsFilterSnapshot#shouldFilterApplication(PackageDataSnapshot, int, Object,
+     * PackageStateInternal, int)}
      */
     @Override
-    public boolean shouldFilterApplication(int callingUid, @Nullable Object callingSetting,
-            PackageStateInternal targetPkgSetting, int userId) {
+    public boolean shouldFilterApplication(PackageDataSnapshot snapshot, int callingUid,
+            @Nullable Object callingSetting, PackageStateInternal targetPkgSetting, int userId) {
         if (DEBUG_TRACING) {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication");
         }
@@ -1405,7 +1375,7 @@
                     return false;
                 }
             } else {
-                if (!shouldFilterApplicationInternal(
+                if (!shouldFilterApplicationInternal(snapshot,
                         callingUid, callingSetting, targetPkgSetting, userId)) {
                     return false;
                 }
@@ -1440,8 +1410,9 @@
         }
     }
 
-    private boolean shouldFilterApplicationInternal(int callingUid, Object callingSetting,
-            PackageStateInternal targetPkgSetting, int targetUserId) {
+    @SuppressWarnings("GuardedBy")
+    private boolean shouldFilterApplicationInternal(PackageDataSnapshot snapshot, int callingUid,
+            Object callingSetting, PackageStateInternal targetPkgSetting, int targetUserId) {
         if (DEBUG_TRACING) {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal");
         }
@@ -1467,9 +1438,8 @@
                 final PackageStateInternal packageState = (PackageStateInternal) callingSetting;
                 if (packageState.hasSharedUser()) {
                     callingPkgSetting = null;
-                    mStateProvider.runWithState((settings, sharedUserSettings, users) ->
-                            callingSharedPkgSettings.addAll(getSharedUserPackages(
-                                    packageState.getSharedUserAppId(), sharedUserSettings)));
+                    callingSharedPkgSettings.addAll(getSharedUserPackages(
+                            packageState.getSharedUserAppId(), snapshot.getAllSharedUsers()));
 
                 } else {
                     callingPkgSetting = packageState;
@@ -1599,20 +1569,53 @@
                 if (DEBUG_TRACING) {
                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent");
                 }
-                if (mQueriesViaComponentRequireRecompute) {
-                    final ArrayMap<String, PackageStateInternal> settingsCopy = new ArrayMap<>();
-                    mStateProvider.runWithState((settings, sharedUserSettings, users) -> {
-                        settingsCopy.putAll(settings);
-                    });
-                    recomputeComponentVisibility(settingsCopy);
-                    onChanged();
-                }
-                synchronized (mLock) {
-                    if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
-                        if (DEBUG_LOGGING) {
-                            log(callingSetting, targetPkgSetting, "queries component");
+                if (!mQueriesViaComponentRequireRecompute) {
+                    synchronized (mLock) {
+                        if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
+                            if (DEBUG_LOGGING) {
+                                log(callingSetting, targetPkgSetting, "queries component");
+                            }
+                            return false;
                         }
-                        return false;
+                    }
+                } else { // mQueriesViaComponent is stale
+                    if (!mIsSnapshot) {
+                        // Only recompute mQueriesViaComponent if not in snapshot
+                        recomputeComponentVisibility(snapshot.getPackageStates());
+                        synchronized (mLock) {
+                            if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
+                                if (DEBUG_LOGGING) {
+                                    log(callingSetting, targetPkgSetting, "queries component");
+                                }
+                                return false;
+                            }
+                        }
+                    } else {
+                        // Do no recompute or use mQueriesViaComponent if it's stale in snapshot
+                        // Since we know we are in the snapshot, no need to acquire mLock because
+                        // mProtectedBroadcasts will not change
+                        if (callingPkgSetting != null) {
+                            if (callingPkgSetting.getPkg() != null
+                                    && canQueryViaComponents(callingPkgSetting.getPkg(), targetPkg,
+                                    mProtectedBroadcasts)) {
+                                if (DEBUG_LOGGING) {
+                                    log(callingSetting, targetPkgSetting, "queries component");
+                                }
+                                return false;
+                            }
+                        } else {
+                            for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
+                                final AndroidPackage pkg =
+                                        callingSharedPkgSettings.valueAt(i).getPkg();
+                                if (pkg != null && canQueryViaComponents(pkg, targetPkg,
+                                        mProtectedBroadcasts)) {
+                                    if (DEBUG_LOGGING) {
+                                        log(callingSetting, targetPkgSetting, "queries component");
+                                    }
+                                    return false;
+                                }
+                            }
+                        }
                     }
                 }
             } finally {
diff --git a/services/core/java/com/android/server/pm/AppsFilterSnapshot.java b/services/core/java/com/android/server/pm/AppsFilterSnapshot.java
index cb8c649..de037f3 100644
--- a/services/core/java/com/android/server/pm/AppsFilterSnapshot.java
+++ b/services/core/java/com/android/server/pm/AppsFilterSnapshot.java
@@ -25,6 +25,7 @@
 import com.android.internal.util.function.QuadFunction;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
 
 import java.io.PrintWriter;
 
@@ -40,27 +41,30 @@
      * If the setting is visible to all UIDs, null is returned. If an app is not visible to any
      * applications, the int array will be empty.
      *
+     * @param snapshot         the snapshot of the computer that contains all package information
      * @param users            the set of users that should be evaluated for this calculation
      * @param existingSettings the set of all package settings that currently exist on device
      * @return a SparseArray mapping userIds to a sorted int array of appIds that may view the
      * provided setting or null if the app is visible to all and no allow list should be
      * applied.
      */
-    SparseArray<int[]> getVisibilityAllowList(PackageStateInternal setting, int[] users,
+    SparseArray<int[]> getVisibilityAllowList(PackageDataSnapshot snapshot,
+            PackageStateInternal setting, int[] users,
             ArrayMap<String, ? extends PackageStateInternal> existingSettings);
 
     /**
      * Returns true if the calling package should not be able to see the target package, false if no
      * filtering should be done.
      *
+     * @param snapshot         the snapshot of the computer that contains all package information
      * @param callingUid       the uid of the caller attempting to access a package
      * @param callingSetting   the setting attempting to access a package or null if it could not be
      *                         found
      * @param targetPkgSetting the package being accessed
      * @param userId           the user in which this access is being attempted
      */
-    boolean shouldFilterApplication(int callingUid, @Nullable Object callingSetting,
-            PackageStateInternal targetPkgSetting, int userId);
+    boolean shouldFilterApplication(PackageDataSnapshot snapshot, int callingUid,
+            @Nullable Object callingSetting, PackageStateInternal targetPkgSetting, int userId);
 
     /**
      * Returns whether the querying package is allowed to see the target package.
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index c259797..db48a1f 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -59,6 +59,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 
@@ -128,6 +129,7 @@
      */
     ActivityInfo getActivityInfoInternal(ComponentName component, long flags,
             int filterCallingUid, int userId);
+    @Override
     AndroidPackage getPackage(String packageName);
     AndroidPackage getPackage(int uid);
     ApplicationInfo generateApplicationInfoFromSettings(String packageName, long flags,
@@ -289,6 +291,7 @@
     PreferredIntentResolver getPreferredActivities(@UserIdInt int userId);
 
     @NonNull
+    @Override
     ArrayMap<String, ? extends PackageStateInternal> getPackageStates();
 
     @Nullable
@@ -602,4 +605,12 @@
 
     @NonNull
     List<? extends PackageStateInternal> getVolumePackages(@NonNull String volumeUuid);
+
+    @Override
+    @NonNull
+    UserInfo[] getUserInfos();
+
+    @Override
+    @NonNull
+    Collection<SharedUserSetting> getAllSharedUsers();
 }
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 80d61b5..bf9f4fa 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -1348,7 +1348,7 @@
                 PackageStateInternal resolvedSetting =
                         getPackageStateInternal(info.activityInfo.packageName, 0);
                 if (resolveForStart
-                        || !mAppsFilter.shouldFilterApplication(
+                        || !mAppsFilter.shouldFilterApplication(this,
                         filterCallingUid, callingSetting, resolvedSetting, userId)) {
                     continue;
                 }
@@ -1382,7 +1382,7 @@
                         mSettings.getSettingBase(UserHandle.getAppId(filterCallingUid));
                 PackageStateInternal resolvedSetting =
                         getPackageStateInternal(info.serviceInfo.packageName, 0);
-                if (!mAppsFilter.shouldFilterApplication(
+                if (!mAppsFilter.shouldFilterApplication(this,
                         filterCallingUid, callingSetting, resolvedSetting, userId)) {
                     continue;
                 }
@@ -2730,7 +2730,7 @@
         }
         int appId = UserHandle.getAppId(callingUid);
         final SettingBase callingPs = mSettings.getSettingBase(appId);
-        return mAppsFilter.shouldFilterApplication(callingUid, callingPs, ps, userId);
+        return mAppsFilter.shouldFilterApplication(this, callingUid, callingPs, ps, userId);
     }
 
     /**
@@ -5036,7 +5036,7 @@
         if (setting == null) {
             return null;
         }
-        return mAppsFilter.getVisibilityAllowList(setting, userIds, getPackageStates());
+        return mAppsFilter.getVisibilityAllowList(this, setting, userIds, getPackageStates());
     }
 
     @Nullable
@@ -5323,7 +5323,7 @@
         if (ps == null) {
             return null;
         }
-        final SparseArray<int[]> visibilityAllowList = mAppsFilter.getVisibilityAllowList(ps,
+        final SparseArray<int[]> visibilityAllowList = mAppsFilter.getVisibilityAllowList(this, ps,
                 new int[]{userId}, getPackageStates());
         return visibilityAllowList != null ? visibilityAllowList.get(userId) : null;
     }
@@ -5823,4 +5823,16 @@
     public List<? extends PackageStateInternal> getVolumePackages(@NonNull String volumeUuid) {
         return mSettings.getVolumePackages(volumeUuid);
     }
+
+    @Override
+    @NonNull
+    public Collection<SharedUserSetting> getAllSharedUsers() {
+        return mSettings.getAllSharedUsers();
+    }
+
+    @Override
+    @NonNull
+    public UserInfo[] getUserInfos() {
+        return mInjector.getUserManagerInternal().getUserInfos();
+    }
 }
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index d3d291e..cb38d52 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -543,8 +543,9 @@
         synchronized (mPm.mLock) {
             if (outInfo != null) {
                 outInfo.mUid = ps.getAppId();
-                outInfo.mBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList(ps,
-                        allUserHandles, mPm.mSettings.getPackagesLocked());
+                outInfo.mBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList(
+                        mPm.snapshotComputer(), ps, allUserHandles,
+                        mPm.mSettings.getPackagesLocked());
             }
         }
 
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index 249099d..8c33dd9 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -432,8 +432,8 @@
         // Whoever is calling forceDexOpt wants a compiled package.
         // Don't use profiles since that may cause compilation to be skipped.
         final int res = performDexOptInternalWithDependenciesLI(pkg, packageState,
-                new DexoptOptions(packageName,
-                        getDefaultCompilerFilter(),
+                new DexoptOptions(packageName, REASON_CMDLINE,
+                        getDefaultCompilerFilter(), null /* splitName */,
                         DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
 
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -442,10 +442,13 @@
         }
     }
 
-    public boolean performDexOptMode(String packageName,
+    public boolean performDexOptMode(@NonNull Computer snapshot, String packageName,
             boolean checkProfiles, String targetCompilerFilter, boolean force,
             boolean bootComplete, String splitName) {
-        PackageManagerServiceUtils.enforceSystemOrRootOrShell("performDexOptMode");
+        if (!PackageManagerServiceUtils.isSystemOrRootOrShell()
+                && !isCallerInstallerForPackage(snapshot, packageName)) {
+            throw new SecurityException("performDexOptMode");
+        }
 
         int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0)
                 | (force ? DexoptOptions.DEXOPT_FORCE : 0)
@@ -454,6 +457,22 @@
                 targetCompilerFilter, splitName, flags));
     }
 
+    private boolean isCallerInstallerForPackage(@NonNull Computer snapshot, String packageName) {
+        final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
+        if (packageState == null) {
+            return false;
+        }
+        final InstallSource installSource = packageState.getInstallSource();
+
+        final PackageStateInternal installerPackageState =
+                snapshot.getPackageStateInternal(installSource.installerPackageName);
+        if (installerPackageState == null) {
+            return false;
+        }
+        final AndroidPackage installerPkg = installerPackageState.getPkg();
+        return installerPkg.getUid() == Binder.getCallingUid();
+    }
+
     public boolean performDexOptSecondary(String packageName, String compilerFilter,
             boolean force) {
         int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
index ba7309f..0436613 100644
--- a/services/core/java/com/android/server/pm/IPackageManagerBase.java
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -972,8 +972,9 @@
     public final boolean performDexOptMode(String packageName,
             boolean checkProfiles, String targetCompilerFilter, boolean force,
             boolean bootComplete, String splitName) {
-        return mDexOptHelper.performDexOptMode(packageName, checkProfiles, targetCompilerFilter,
-                force, bootComplete, splitName);
+        final Computer snapshot = snapshot();
+        return mDexOptHelper.performDexOptMode(snapshot, packageName, checkProfiles,
+                targetCompilerFilter, force, bootComplete, splitName);
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index bbdb7eb..2d8d4f5 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -464,9 +464,9 @@
             KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService();
             ksms.addScannedPackageLPw(pkg);
 
-            mPm.mComponentResolver.addAllComponents(pkg, chatty, mPm.mSetupWizardPackage,
-                    mPm.snapshotComputer());
-            mPm.mAppsFilter.addPackage(pkgSetting, isReplace);
+            final Computer snapshot = mPm.snapshotComputer();
+            mPm.mComponentResolver.addAllComponents(pkg, chatty, mPm.mSetupWizardPackage, snapshot);
+            mPm.mAppsFilter.addPackage(snapshot, pkgSetting, isReplace);
             mPm.addAllPackageProperties(pkg);
 
             if (oldPkgSetting == null || oldPkgSetting.getPkg() == null) {
@@ -1916,7 +1916,7 @@
                         .setLastUpdateTime(System.currentTimeMillis());
 
                 res.mRemovedInfo.mBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList(
-                        reconciledPkg.mPkgSetting, request.mAllUsers,
+                        mPm.snapshotComputer(), reconciledPkg.mPkgSetting, request.mAllUsers,
                         mPm.mSettings.getPackagesLocked());
                 if (reconciledPkg.mPrepareResult.mSystem) {
                     // Remove existing system package
@@ -2545,7 +2545,6 @@
         ArrayList<String>[] components;
         int size = 0;
         int[] uids;
-        Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
 
         synchronized (mPm.mLock) {
             final SparseArray<ArrayMap<String, ArrayList<String>>> userIdToPackagesToComponents =
@@ -2584,7 +2583,6 @@
             mPm.sendPackageChangedBroadcast(snapshot, packages[i], true /* dontKillApp */,
                     components[i], uids[i], null /* reason */);
         }
-        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
     }
 
     void handlePackagePostInstall(PackageInstalledInfo res, InstallArgs installArgs,
@@ -2712,9 +2710,9 @@
                 // Send to all running apps.
                 final SparseArray<int[]> newBroadcastAllowList;
                 synchronized (mPm.mLock) {
-                    newBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList(
-                            mPm.snapshotComputer()
-                                    .getPackageStateInternal(packageName, Process.SYSTEM_UID),
+                    final Computer snapshot = mPm.snapshotComputer();
+                    newBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList(snapshot,
+                            snapshot.getPackageStateInternal(packageName, Process.SYSTEM_UID),
                             updateUserIds, mPm.mSettings.getPackagesLocked());
                 }
                 mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index e8faca9..0dfa31c 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -75,7 +75,7 @@
         try {
             doHandleMessage(msg);
         } finally {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
         }
     }
 
@@ -136,19 +136,13 @@
                 }
             } break;
             case WRITE_SETTINGS: {
-                Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
                 mPm.writeSettings();
-                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
             } break;
             case WRITE_PACKAGE_RESTRICTIONS: {
-                Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
                 mPm.writePendingRestrictions();
-                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
             } break;
             case WRITE_PACKAGE_LIST: {
-                Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
                 mPm.writePackageList(msg.arg1);
-                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
             } break;
             case CHECK_PENDING_VERIFICATION: {
                 final int verificationId = msg.arg1;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7fd28f6..2cef35f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1413,7 +1413,9 @@
         t.traceBegin("create package manager");
         final PackageManagerTracedLock lock = new PackageManagerTracedLock();
         final Object installLock = new Object();
-        HandlerThread backgroundThread = new HandlerThread("PackageManagerBg");
+
+        HandlerThread backgroundThread = new ServiceThread("PackageManagerBg",
+                Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
         backgroundThread.start();
         Handler backgroundHandler = new Handler(backgroundThread.getLooper());
 
@@ -1430,7 +1432,7 @@
                 (i, pm) -> new Settings(Environment.getDataDirectory(),
                         RuntimePermissionsPersistence.createInstance(),
                         i.getPermissionManagerServiceInternal(),
-                        domainVerificationService, lock),
+                        domainVerificationService, backgroundHandler, lock),
                 (i, pm) -> AppsFilterImpl.create(i,
                         i.getLocalService(PackageManagerInternal.class)),
                 (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),
@@ -1467,7 +1469,7 @@
                 (i, pm) -> domainVerificationService,
                 (i, pm) -> {
                     HandlerThread thread = new ServiceThread(TAG,
-                            Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
+                            Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
                     thread.start();
                     return new PackageHandler(thread.getLooper(), pm);
                 },
@@ -2992,7 +2994,7 @@
         if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
             return;
         }
-        SparseArray<int[]> broadcastAllowList = mAppsFilter.getVisibilityAllowList(
+        SparseArray<int[]> broadcastAllowList = mAppsFilter.getVisibilityAllowList(snapshot,
                 snapshot.getPackageStateInternal(packageName, Process.SYSTEM_UID),
                 userIds, snapshot.getPackageStates());
         mHandler.post(() -> mBroadcastHelper.sendPackageAddedForNewUsers(
@@ -4013,7 +4015,7 @@
                 .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
         co.onChange(true);
 
-        mAppsFilter.onSystemReady();
+        mAppsFilter.onSystemReady(LocalServices.getService(PackageManagerInternal.class));
 
         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
         // disabled after already being started.
@@ -4226,7 +4228,7 @@
         synchronized (mLock) {
             scheduleWritePackageRestrictions(userId);
             scheduleWritePackageListLocked(userId);
-            mAppsFilter.onUserCreated(userId);
+            mAppsFilter.onUserCreated(snapshotComputer(), userId);
         }
     }
 
@@ -5751,7 +5753,7 @@
                     targetPackageState = snapshotComputer().getPackageStateInternal(targetPackage);
                     mSettings.addInstallerPackageNames(targetPackageState.getInstallSource());
                 }
-                mAppsFilter.addPackage(targetPackageState);
+                mAppsFilter.addPackage(snapshotComputer(), targetPackageState);
                 scheduleWriteSettings();
             }
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 2a1a990..4d11b13 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -1245,13 +1245,20 @@
      * @throws SecurityException if the caller is not system or shell
      */
     public static void enforceSystemOrRootOrShell(String message) {
-        final int uid = Binder.getCallingUid();
-        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID && uid != Process.SHELL_UID) {
+        if (!isSystemOrRootOrShell()) {
             throw new SecurityException(message);
         }
     }
 
     /**
+     * Check if the Binder caller is system UID, root's UID, or shell's UID.
+     */
+    public static boolean isSystemOrRootOrShell() {
+        final int uid = Binder.getCallingUid();
+        return uid == Process.SYSTEM_UID || uid == Process.ROOT_UID || uid == Process.SHELL_UID;
+    }
+
+    /**
      * Check if the Binder caller is system UID or root's UID.
      */
     public static boolean isSystemOrRoot() {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 78a600e..6b10d4c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -159,13 +159,14 @@
     private static final Map<String, Integer> SUPPORTED_PERMISSION_FLAGS = new ArrayMap<>();
     private static final List<String> SUPPORTED_PERMISSION_FLAGS_LIST;
     static {
+        SUPPORTED_PERMISSION_FLAGS_LIST = List.of("review-required", "revoked-compat",
+                "revoke-when-requested", "user-fixed", "user-set");
         SUPPORTED_PERMISSION_FLAGS.put("user-set", FLAG_PERMISSION_USER_SET);
         SUPPORTED_PERMISSION_FLAGS.put("user-fixed", FLAG_PERMISSION_USER_FIXED);
         SUPPORTED_PERMISSION_FLAGS.put("revoked-compat", FLAG_PERMISSION_REVOKED_COMPAT);
         SUPPORTED_PERMISSION_FLAGS.put("review-required", FLAG_PERMISSION_REVIEW_REQUIRED);
         SUPPORTED_PERMISSION_FLAGS.put("revoke-when-requested",
                 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
-        SUPPORTED_PERMISSION_FLAGS_LIST = new ArrayList<>(SUPPORTED_PERMISSION_FLAGS.keySet());
     }
 
     final IPackageManager mInterface;
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index baa3a9d..65d3430 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -274,8 +274,9 @@
             synchronized (mPm.mLock) {
                 mPm.mDomainVerificationManager.clearPackage(deletedPs.getPackageName());
                 mPm.mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName);
-                mPm.mAppsFilter.removePackage(mPm.snapshotComputer()
-                                .getPackageStateInternal(packageName), false /* isReplace */);
+                final Computer snapshot = mPm.snapshotComputer();
+                mPm.mAppsFilter.removePackage(snapshot,
+                        snapshot.getPackageStateInternal(packageName), false /* isReplace */);
                 removedAppId = mPm.mSettings.removePackageLPw(packageName);
                 if (outInfo != null) {
                     outInfo.mRemovedAppId = removedAppId;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index e6d59d4..ba4d09f 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -164,6 +164,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import java.util.Random;
 import java.util.Set;
 import java.util.UUID;
 import java.util.function.Consumer;
@@ -360,6 +361,8 @@
     private static final String ATTR_VALUE = "value";
     private static final String ATTR_FIRST_INSTALL_TIME = "first-install-time";
 
+    private final Handler mHandler;
+
     private final PackageManagerTracedLock mLock;
 
     @Watched(manual = true)
@@ -583,6 +586,8 @@
                                          "Settings.mInstallerPackages");
         mKeySetManagerService = new KeySetManagerService(mPackages);
 
+        // Test-only handler working on background thread.
+        mHandler = new Handler(BackgroundThread.getHandler().getLooper());
         mLock = new PackageManagerTracedLock();
         mPackages.putAll(pkgSettings);
         mAppIds = new AppIdSettingMap();
@@ -607,6 +612,7 @@
     Settings(File dataDir, RuntimePermissionsPersistence runtimePermissionsPersistence,
             LegacyPermissionDataProvider permissionDataProvider,
             @NonNull DomainVerificationManagerInternal domainVerificationManager,
+            @NonNull Handler handler,
             @NonNull PackageManagerTracedLock lock)  {
         mPackages = new WatchedArrayMap<>();
         mPackagesSnapshot  =
@@ -620,6 +626,7 @@
                                          "Settings.mInstallerPackages");
         mKeySetManagerService = new KeySetManagerService(mPackages);
 
+        mHandler = handler;
         mLock = lock;
         mAppIds = new AppIdSettingMap();
         mPermissions = new LegacyPermissionSettings(lock);
@@ -627,10 +634,8 @@
                 runtimePermissionsPersistence, new Consumer<Integer>() {
             @Override
             public void accept(Integer userId) {
-                synchronized (mLock) {
-                    mRuntimePermissionsPersistence.writeStateForUserSync(userId,
-                            mPermissionDataProvider, mPackages, mSharedUsers);
-                }
+                mRuntimePermissionsPersistence.writeStateForUser(userId, mPermissionDataProvider,
+                        mPackages, mSharedUsers, mHandler, mLock, /*sync=*/false);
             }
         });
         mPermissionDataProvider = permissionDataProvider;
@@ -679,6 +684,7 @@
         // needed by the read-only methods.  Note especially that the lock
         // is not required because this clone is meant to support lock-free
         // read-only methods.
+        mHandler = null;
         mLock = null;
         mRuntimePermissionsPersistence = r.mRuntimePermissionsPersistence;
         mSettingsFilename = null;
@@ -5286,8 +5292,8 @@
 
     public void writePermissionStateForUserLPr(int userId, boolean sync) {
         if (sync) {
-            mRuntimePermissionsPersistence.writeStateForUserSync(userId, mPermissionDataProvider,
-                    mPackages, mSharedUsers);
+            mRuntimePermissionsPersistence.writeStateForUser(userId, mPermissionDataProvider,
+                    mPackages, mSharedUsers, /*handler=*/null, mLock, /*sync=*/true);
         } else {
             mRuntimePermissionsPersistence.writeStateForUserAsync(userId);
         }
@@ -5365,17 +5371,27 @@
     }
 
     private static final class RuntimePermissionPersistence {
-        private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
+        // 200-400ms delay to avoid monopolizing PMS lock when written for multiple users.
+        private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 300;
+        private static final double WRITE_PERMISSIONS_DELAY_JITTER = 0.3;
+
         private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
 
         private static final int UPGRADE_VERSION = -1;
         private static final int INITIAL_VERSION = 0;
 
+        private static final Random sRandom = new Random();
+
         private String mExtendedFingerprint;
 
+        @GuardedBy("mPersistenceLock")
         private final RuntimePermissionsPersistence mPersistence;
+        private final Object mPersistenceLock = new Object();
 
-        private final Handler mHandler = new MyHandler();
+        // Low-priority handlers running on SystemBg thread.
+        private final Handler mAsyncHandler = new MyHandler();
+        private final Handler mPersistenceHandler = new Handler(
+                BackgroundThread.getHandler().getLooper());
 
         private final Object mLock = new Object();
 
@@ -5387,6 +5403,11 @@
         private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
 
         @GuardedBy("mLock")
+        // Tracking the mutations that haven't yet been written to legacy state.
+        // This avoids unnecessary work when writing settings for multiple users.
+        private boolean mIsLegacyPermissionStateStale = false;
+
+        @GuardedBy("mLock")
         // The mapping keys are user ids.
         private final SparseIntArray mVersions = new SparseIntArray();
 
@@ -5398,6 +5419,11 @@
         // The mapping keys are user ids.
         private final SparseBooleanArray mPermissionUpgradeNeeded = new SparseBooleanArray();
 
+        @GuardedBy("mLock")
+        // Staging area for states prepared to be written.
+        private final SparseArray<RuntimePermissionsState> mPendingStatesToWrite =
+                new SparseArray<>();
+
         // This is a hack to allow this class to invoke a write using Settings's data structures,
         // to facilitate moving to a finer scoped lock without a significant refactor.
         private final Consumer<Integer> mInvokeWriteUserStateAsyncCallback;
@@ -5457,12 +5483,25 @@
             return PackagePartitions.FINGERPRINT + "?pc_version=" + version;
         }
 
+        private static long uniformRandom(double low, double high) {
+            double mag = high - low;
+            return (long) (sRandom.nextDouble() * mag + low);
+        }
+
+        private static long nextWritePermissionDelayMillis() {
+            final long delay = WRITE_PERMISSIONS_DELAY_MILLIS;
+            final double jitter = WRITE_PERMISSIONS_DELAY_JITTER;
+            return delay + uniformRandom(-jitter * delay, jitter * delay);
+        }
+
         public void writeStateForUserAsync(int userId) {
             synchronized (mLock) {
+                mIsLegacyPermissionStateStale = true;
                 final long currentTimeMillis = SystemClock.uptimeMillis();
+                final long writePermissionDelayMillis = nextWritePermissionDelayMillis();
 
                 if (mWriteScheduled.get(userId)) {
-                    mHandler.removeMessages(userId);
+                    mAsyncHandler.removeMessages(userId);
 
                     // If enough time passed, write without holding off anymore.
                     final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis
@@ -5471,77 +5510,126 @@
                             - lastNotWrittenMutationTimeMillis;
                     if (timeSinceLastNotWrittenMutationMillis
                             >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) {
-                        mHandler.obtainMessage(userId).sendToTarget();
+                        mAsyncHandler.obtainMessage(userId).sendToTarget();
                         return;
                     }
 
                     // Hold off a bit more as settings are frequently changing.
                     final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis
                             + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0);
-                    final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS,
+                    final long writeDelayMillis = Math.min(writePermissionDelayMillis,
                             maxDelayMillis);
 
-                    Message message = mHandler.obtainMessage(userId);
-                    mHandler.sendMessageDelayed(message, writeDelayMillis);
+                    Message message = mAsyncHandler.obtainMessage(userId);
+                    mAsyncHandler.sendMessageDelayed(message, writeDelayMillis);
                 } else {
                     mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis);
-                    Message message = mHandler.obtainMessage(userId);
-                    mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS);
+                    Message message = mAsyncHandler.obtainMessage(userId);
+                    mAsyncHandler.sendMessageDelayed(message, writePermissionDelayMillis);
                     mWriteScheduled.put(userId, true);
                 }
             }
         }
 
-        public void writeStateForUserSync(int userId, @NonNull LegacyPermissionDataProvider
+        public void writeStateForUser(int userId, @NonNull LegacyPermissionDataProvider
                 legacyPermissionDataProvider,
                 @NonNull WatchedArrayMap<String, ? extends PackageStateInternal> packageStates,
-                @NonNull WatchedArrayMap<String, SharedUserSetting> sharedUsers) {
+                @NonNull WatchedArrayMap<String, SharedUserSetting> sharedUsers,
+                @Nullable Handler pmHandler, @NonNull Object pmLock,
+                boolean sync) {
+            final int version;
+            final String fingerprint;
+            final boolean isLegacyPermissionStateStale;
             synchronized (mLock) {
-                mHandler.removeMessages(userId);
+                mAsyncHandler.removeMessages(userId);
                 mWriteScheduled.delete(userId);
 
-                legacyPermissionDataProvider.writeLegacyPermissionStateTEMP();
+                version = mVersions.get(userId, INITIAL_VERSION);
+                fingerprint = mFingerprints.get(userId);
+                isLegacyPermissionStateStale = mIsLegacyPermissionStateStale;
+                mIsLegacyPermissionStateStale = false;
+            }
 
-                int version = mVersions.get(userId, INITIAL_VERSION);
+            Runnable writer = () -> {
+                final RuntimePermissionsState runtimePermissions;
+                synchronized (pmLock) {
+                    if (sync || isLegacyPermissionStateStale) {
+                        legacyPermissionDataProvider.writeLegacyPermissionStateTEMP();
+                    }
 
-                String fingerprint = mFingerprints.get(userId);
+                    Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions =
+                            new ArrayMap<>();
+                    int packagesSize = packageStates.size();
+                    for (int i = 0; i < packagesSize; i++) {
+                        String packageName = packageStates.keyAt(i);
+                        PackageStateInternal packageState = packageStates.valueAt(i);
+                        if (!packageState.hasSharedUser()) {
+                            List<RuntimePermissionsState.PermissionState> permissions =
+                                    getPermissionsFromPermissionsState(
+                                            packageState.getLegacyPermissionState(), userId);
+                            if (permissions.isEmpty()
+                                    && !packageState.isInstallPermissionsFixed()) {
+                                // Storing an empty state means the package is known to the
+                                // system and its install permissions have been granted and fixed.
+                                // If this is not the case, we should not store anything.
+                                continue;
+                            }
+                            packagePermissions.put(packageName, permissions);
+                        }
+                    }
 
-                Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions =
-                        new ArrayMap<>();
-                int packagesSize = packageStates.size();
-                for (int i = 0; i < packagesSize; i++) {
-                    String packageName = packageStates.keyAt(i);
-                    PackageStateInternal packageState = packageStates.valueAt(i);
-                    if (!packageState.hasSharedUser()) {
+                    Map<String, List<RuntimePermissionsState.PermissionState>>
+                            sharedUserPermissions =
+                            new ArrayMap<>();
+                    final int sharedUsersSize = sharedUsers.size();
+                    for (int i = 0; i < sharedUsersSize; i++) {
+                        String sharedUserName = sharedUsers.keyAt(i);
+                        SharedUserSetting sharedUserSetting = sharedUsers.valueAt(i);
                         List<RuntimePermissionsState.PermissionState> permissions =
                                 getPermissionsFromPermissionsState(
-                                        packageState.getLegacyPermissionState(), userId);
-                        if (permissions.isEmpty() && !packageState.isInstallPermissionsFixed()) {
-                            // Storing an empty state means the package is known to the system and
-                            // its install permissions have been granted and fixed. If this is not
-                            // the case, we should not store anything.
-                            continue;
-                        }
-                        packagePermissions.put(packageName, permissions);
+                                        sharedUserSetting.getLegacyPermissionState(), userId);
+                        sharedUserPermissions.put(sharedUserName, permissions);
                     }
+
+                    runtimePermissions = new RuntimePermissionsState(version,
+                            fingerprint, packagePermissions, sharedUserPermissions);
                 }
-
-                Map<String, List<RuntimePermissionsState.PermissionState>> sharedUserPermissions =
-                        new ArrayMap<>();
-                final int sharedUsersSize = sharedUsers.size();
-                for (int i = 0; i < sharedUsersSize; i++) {
-                    String sharedUserName = sharedUsers.keyAt(i);
-                    SharedUserSetting sharedUserSetting = sharedUsers.valueAt(i);
-                    List<RuntimePermissionsState.PermissionState> permissions =
-                            getPermissionsFromPermissionsState(
-                                    sharedUserSetting.getLegacyPermissionState(), userId);
-                    sharedUserPermissions.put(sharedUserName, permissions);
+                synchronized (mLock) {
+                    mPendingStatesToWrite.put(userId, runtimePermissions);
                 }
+                if (pmHandler != null) {
+                    // Async version.
+                    mPersistenceHandler.post(() -> writePendingStates());
+                } else {
+                    // Sync version.
+                    writePendingStates();
+                }
+            };
 
-                RuntimePermissionsState runtimePermissions = new RuntimePermissionsState(version,
-                        fingerprint, packagePermissions, sharedUserPermissions);
+            if (pmHandler != null) {
+                // Async version, use pmHandler.
+                pmHandler.post(writer);
+            } else {
+                // Sync version, use caller's thread.
+                writer.run();
+            }
+        }
 
-                mPersistence.writeForUser(runtimePermissions, UserHandle.of(userId));
+        private void writePendingStates() {
+            while (true) {
+                final RuntimePermissionsState runtimePermissions;
+                final int userId;
+                synchronized (mLock) {
+                    if (mPendingStatesToWrite.size() == 0) {
+                        break;
+                    }
+                    userId = mPendingStatesToWrite.keyAt(0);
+                    runtimePermissions = mPendingStatesToWrite.valueAt(0);
+                    mPendingStatesToWrite.removeAt(0);
+                }
+                synchronized (mPersistenceLock) {
+                    mPersistence.writeForUser(runtimePermissions, UserHandle.of(userId));
+                }
             }
         }
 
@@ -5563,7 +5651,7 @@
         private void onUserRemoved(int userId) {
             synchronized (mLock) {
                 // Make sure we do not
-                mHandler.removeMessages(userId);
+                mAsyncHandler.removeMessages(userId);
 
                 mPermissionUpgradeNeeded.delete(userId);
                 mVersions.delete(userId);
@@ -5572,7 +5660,7 @@
         }
 
         public void deleteUserRuntimePermissionsFile(int userId) {
-            synchronized (mLock) {
+            synchronized (mPersistenceLock) {
                 mPersistence.deleteForUser(UserHandle.of(userId));
             }
         }
@@ -5581,16 +5669,17 @@
                 @NonNull WatchedArrayMap<String, PackageSetting> packageSettings,
                 @NonNull WatchedArrayMap<String, SharedUserSetting> sharedUsers,
                 @NonNull File userRuntimePermissionsFile) {
+            final RuntimePermissionsState runtimePermissions;
+            synchronized (mPersistenceLock) {
+                runtimePermissions = mPersistence.readForUser(UserHandle.of(userId));
+            }
+            if (runtimePermissions == null) {
+                readLegacyStateForUserSync(userId, userRuntimePermissionsFile, packageSettings,
+                        sharedUsers);
+                writeStateForUserAsync(userId);
+                return;
+            }
             synchronized (mLock) {
-                RuntimePermissionsState runtimePermissions = mPersistence.readForUser(UserHandle.of(
-                        userId));
-                if (runtimePermissions == null) {
-                    readLegacyStateForUserSync(userId, userRuntimePermissionsFile, packageSettings,
-                            sharedUsers);
-                    writeStateForUserAsync(userId);
-                    return;
-                }
-
                 // If the runtime permissions file exists but the version is not set this is
                 // an upgrade from P->Q. Hence mark it with the special UPGRADE_VERSION.
                 int version = runtimePermissions.getVersion();
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index b3723fb..f57eaae 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -894,8 +894,12 @@
 
         // Get the list of all dynamic shortcuts in this package.
         final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
+        // Pass callingLauncher to ensure pinned flag marked by system ui, e.g. ShareSheet, are
+        // included in the result
         findAll(shortcuts, ShortcutInfo::isNonManifestVisible,
-                ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION);
+                ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION,
+                mShortcutUser.mService.mContext.getPackageName(),
+                0, /*getPinnedByAnyLauncher=*/ false);
 
         final List<ShortcutManager.ShareShortcutInfo> result = new ArrayList<>();
         for (int i = 0; i < shortcuts.size(); i++) {
diff --git a/services/core/java/com/android/server/pm/SuspendPackageHelper.java b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
index 860c54c..29c926c 100644
--- a/services/core/java/com/android/server/pm/SuspendPackageHelper.java
+++ b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
@@ -598,7 +598,7 @@
             final String pkgName = pkgList[i];
             final int uid = uidList[i];
             SparseArray<int[]> allowList = mInjector.getAppsFilter().getVisibilityAllowList(
-                    snapshot.getPackageStateInternal(pkgName, SYSTEM_UID),
+                    snapshot, snapshot.getPackageStateInternal(pkgName, SYSTEM_UID),
                     userIds, snapshot.getPackageStates());
             if (allowList == null) {
                 allowList = new SparseArray<>(0);
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 0311524..284c29e 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -21,6 +21,7 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.DownloadManager;
 import android.app.SearchManager;
@@ -1093,6 +1094,14 @@
         }
     }
 
+    public void grantDefaultPermissionsToCarrierServiceApp(@NonNull String packageName,
+            @UserIdInt int userId) {
+        Log.i(TAG, "Grant permissions to Carrier Service app " + packageName + " for user:"
+                + userId);
+        grantPermissionsToPackage(NO_PM_CACHE, packageName, userId, /* ignoreSystemPackage */ false,
+               /* whitelistRestricted */ true, NOTIFICATION_PERMISSIONS);
+    }
+
     private String getDefaultSystemHandlerActivityPackage(PackageManagerWrapper pm,
             String intentAction, int userId) {
         return getDefaultSystemHandlerActivityPackage(pm, new Intent(intentAction), userId);
diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java
index ea554d3..360a04f 100644
--- a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.AppOpsManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
@@ -248,6 +249,15 @@
     }
 
     @Override
+    public void grantDefaultPermissionsToCarrierServiceApp(@NonNull String packageName,
+            @UserIdInt int userId) {
+        PackageManagerServiceUtils.enforceSystemOrRoot(
+                "grantDefaultPermissionsForCarrierServiceApp");
+        Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                .grantDefaultPermissionsToCarrierServiceApp(packageName, userId));
+    }
+
+    @Override
     public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
         final int callingUid = Binder.getCallingUid();
         PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 74f6296..d9e74f8 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -195,11 +195,6 @@
 
     /** All storage permissions */
     private static final List<String> STORAGE_PERMISSIONS = new ArrayList<>();
-
-    private static final Set<String> READ_MEDIA_AURAL_PERMISSIONS = new ArraySet<>();
-
-    private static final Set<String> READ_MEDIA_VISUAL_PERMISSIONS = new ArraySet<>();
-
     /** All nearby devices permissions */
     private static final List<String> NEARBY_DEVICES_PERMISSIONS = new ArrayList<>();
 
@@ -227,10 +222,10 @@
                 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
         STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
         STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
-        READ_MEDIA_AURAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_AUDIO);
-        READ_MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VIDEO);
-        READ_MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_IMAGES);
-        READ_MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
+        STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
+        STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_AUDIO);
+        STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_IMAGES);
+        STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VIDEO);
         NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_ADVERTISE);
         NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_CONNECT);
         NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_SCAN);
@@ -772,8 +767,8 @@
             flagValues &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
             flagValues &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
             flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
-            // REVIEW_REQUIRED can only be set by non-system apps for POST_NOTIFICATIONS, or by the
-            // shell or root UID.
+            // REVIEW_REQUIRED can be set on any permission by the shell or the root uid, or by
+            // any app for the POST_NOTIFICATIONS permission specifically.
             if (!POST_NOTIFICATIONS.equals(permName) && callingUid != Process.SHELL_UID
                     && callingUid != Process.ROOT_UID) {
                 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
@@ -2075,10 +2070,7 @@
                 PermissionInfo permInfo = getPermissionInfo(
                         newPackage.getRequestedPermissions().get(i),
                         newPackage.getPackageName(), 0);
-                boolean isStorageOrMedia = STORAGE_PERMISSIONS.contains(permInfo.name)
-                        || READ_MEDIA_AURAL_PERMISSIONS.contains(permInfo.name)
-                        || READ_MEDIA_VISUAL_PERMISSIONS.contains(permInfo.name);
-                if (permInfo == null || !isStorageOrMedia) {
+                if (permInfo == null || !STORAGE_PERMISSIONS.contains(permInfo.name)) {
                     continue;
                 }
 
@@ -3152,9 +3144,7 @@
                 }
                 if (bp.isRuntime()) {
 
-                    if (!(newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)
-                            || READ_MEDIA_AURAL_PERMISSIONS.contains(newPerm)
-                            || READ_MEDIA_VISUAL_PERMISSIONS.contains(newPerm))) {
+                    if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
                         ps.updatePermissionFlags(bp,
                                 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
                                 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
diff --git a/services/core/java/com/android/server/pm/snapshot/PackageDataSnapshot.java b/services/core/java/com/android/server/pm/snapshot/PackageDataSnapshot.java
index b091445..e1e2222 100644
--- a/services/core/java/com/android/server/pm/snapshot/PackageDataSnapshot.java
+++ b/services/core/java/com/android/server/pm/snapshot/PackageDataSnapshot.java
@@ -16,5 +16,22 @@
 
 package com.android.server.pm.snapshot;
 
+import android.annotation.NonNull;
+import android.content.pm.UserInfo;
+import android.util.ArrayMap;
+
+import com.android.server.pm.SharedUserSetting;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.pkg.PackageStateInternal;
+
+import java.util.Collection;
+
 public interface PackageDataSnapshot {
+    @NonNull
+    ArrayMap<String, ? extends PackageStateInternal> getPackageStates();
+    @NonNull
+    UserInfo[] getUserInfos();
+    @NonNull
+    Collection<SharedUserSetting> getAllSharedUsers();
+    AndroidPackage getPackage(String packageName);
 }
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 89ac9e7..14abc9a 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -66,11 +66,13 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.permission.LegacyPermissionManager;
 import android.permission.PermissionControllerManager;
 import android.permission.PermissionManager;
 import android.provider.Settings;
 import android.provider.Telephony;
 import android.telecom.TelecomManager;
+import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
@@ -106,6 +108,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 
 /**
@@ -163,6 +166,7 @@
     private PackageManagerInternal mPackageManagerInternal;
     private PermissionManagerServiceInternal mPermissionManagerInternal;
     private NotificationManagerInternal mNotificationManager;
+    private TelephonyManager mTelephonyManager;
     private final KeyguardManager mKeyguardManager;
     private final PackageManager mPackageManager;
     private final Handler mHandler;
@@ -384,6 +388,13 @@
     public void onBootPhase(int phase) {
         if (DEBUG) Slog.i(LOG_TAG, "onBootPhase(" + phase + ")");
 
+        if (phase == PHASE_DEVICE_SPECIFIC_SERVICES_READY) {
+            registerCarrierPrivilegesCallbacks();
+            IntentFilter filter =
+                    new IntentFilter(TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED);
+            mContext.registerReceiver(mSimConfigBroadcastReceiver, filter);
+        }
+
         if (phase == PHASE_ACTIVITY_MANAGER_READY) {
             final UserManagerInternal um = LocalServices.getService(UserManagerInternal.class);
 
@@ -408,6 +419,94 @@
 
     }
 
+    private void initTelephonyManagerIfNeeded() {
+        if (mTelephonyManager == null) {
+            mTelephonyManager = TelephonyManager.from(mContext);
+        }
+    }
+
+    private void registerCarrierPrivilegesCallbacks() {
+        initTelephonyManagerIfNeeded();
+        if (mTelephonyManager == null) {
+            return;
+        }
+
+        int numPhones = mTelephonyManager.getActiveModemCount();
+        for (int i = 0; i < numPhones; i++) {
+            PhoneCarrierPrivilegesCallback callback = new PhoneCarrierPrivilegesCallback(i);
+            mPhoneCarrierPrivilegesCallbacks.add(callback);
+            mTelephonyManager.registerCarrierPrivilegesCallback(i, mContext.getMainExecutor(),
+                    callback);
+        }
+    }
+
+    private void unregisterCarrierPrivilegesCallback() {
+        initTelephonyManagerIfNeeded();
+        if (mTelephonyManager == null) {
+            return;
+        }
+
+        for (int i = 0; i < mPhoneCarrierPrivilegesCallbacks.size(); i++) {
+            PhoneCarrierPrivilegesCallback callback = mPhoneCarrierPrivilegesCallbacks.get(i);
+            if (callback != null) {
+                mTelephonyManager.unregisterCarrierPrivilegesCallback(callback);
+            }
+        }
+        mPhoneCarrierPrivilegesCallbacks.clear();
+    }
+
+    private final class PhoneCarrierPrivilegesCallback
+            implements TelephonyManager.CarrierPrivilegesCallback {
+        private int mPhoneId;
+
+        PhoneCarrierPrivilegesCallback(int phoneId) {
+            mPhoneId = phoneId;
+        }
+        @Override
+        public void onCarrierPrivilegesChanged(
+                @NonNull Set<String> privilegedPackageNames,
+                @NonNull Set<Integer> privilegedUids) {
+            initTelephonyManagerIfNeeded();
+            if (mTelephonyManager == null) {
+                Log.e(LOG_TAG, "Cannot grant default permissions to Carrier Service app. "
+                        + "TelephonyManager is null");
+                return;
+            }
+
+            String servicePkg = mTelephonyManager.getCarrierServicePackageNameForLogicalSlot(
+                    mPhoneId);
+            if (servicePkg == null) {
+                return;
+            }
+            int[] users = LocalServices.getService(UserManagerInternal.class).getUserIds();
+            LegacyPermissionManager legacyPermManager =
+                    mContext.getSystemService(LegacyPermissionManager.class);
+            for (int i = 0; i < users.length; i++) {
+                try {
+                    mPackageManager.getPackageInfoAsUser(servicePkg, 0, users[i]);
+                    legacyPermManager.grantDefaultPermissionsToCarrierServiceApp(
+                            servicePkg, users[i]);
+                } catch (PackageManager.NameNotFoundException e) {
+                    // Do nothing if the package does not exist for the specified user
+                }
+            }
+        }
+    }
+
+    private final ArrayList<PhoneCarrierPrivilegesCallback> mPhoneCarrierPrivilegesCallbacks =
+            new ArrayList<>();
+
+    private final BroadcastReceiver mSimConfigBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED.equals(intent.getAction())) {
+                return;
+            }
+            unregisterCarrierPrivilegesCallback();
+            registerCarrierPrivilegesCallbacks();
+        }
+    };
+
     /**
      * @return Whether the user is started but not yet stopped
      */
diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
index ae23b9e..5db4a7b 100644
--- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
@@ -268,9 +268,17 @@
     }
 
     private boolean componentMapsToRecognitionService(@NonNull ComponentName serviceComponent) {
-        List<ResolveInfo> resolveInfos =
-                getContext().getPackageManager().queryIntentServicesAsUser(
-                        new Intent(RecognitionService.SERVICE_INTERFACE), 0, getUserId());
+        List<ResolveInfo> resolveInfos;
+
+        final long identityToken = Binder.clearCallingIdentity();
+        try {
+            resolveInfos =
+                    getContext().getPackageManager().queryIntentServicesAsUser(
+                            new Intent(RecognitionService.SERVICE_INTERFACE), 0, getUserId());
+        } finally {
+            Binder.restoreCallingIdentity(identityToken);
+        }
+
         if (resolveInfos == null) {
             return false;
         }
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f91e9c9..c4c3740 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -322,6 +322,7 @@
 import android.view.WindowManager.LayoutParams;
 import android.view.WindowManager.TransitionOldType;
 import android.view.animation.Animation;
+import android.window.ITaskFragmentOrganizer;
 import android.window.RemoteTransition;
 import android.window.SizeConfigurationBuckets;
 import android.window.SplashScreen;
@@ -635,6 +636,13 @@
     // host Activity the launch-into-pip Activity is originated from.
     private ActivityRecord mLaunchIntoPipHostActivity;
 
+    /**
+     * Sets to the previous {@link ITaskFragmentOrganizer} of the {@link TaskFragment} that the
+     * activity is embedded in before it is reparented to a new Task due to picture-in-picture.
+     */
+    @Nullable
+    ITaskFragmentOrganizer mLastTaskFragmentOrganizerBeforePip;
+
     boolean firstWindowDrawn;
     /** Whether the visible window(s) of this activity is drawn. */
     private boolean mReportedDrawn;
@@ -653,10 +661,19 @@
 
     /**
      * The activity is opaque and fills the entire space of this task.
-     * @see WindowContainer#fillsParent()
+     * @see #occludesParent()
      */
     private boolean mOccludesParent;
 
+    /**
+     * Unlike {@link #mOccludesParent} which can be changed at runtime. This is a static attribute
+     * from the style of activity. Because we don't want {@link WindowContainer#getOrientation()}
+     * to be affected by the temporal state of {@link ActivityClientController#convertToTranslucent}
+     * when running ANIM_SCENE_TRANSITION.
+     * @see WindowContainer#fillsParent()
+     */
+    private final boolean mFillsParent;
+
     // The input dispatching timeout for this application token in milliseconds.
     long mInputDispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
 
@@ -1531,7 +1548,10 @@
 
         updateAnimatingActivityRegistry();
 
-        if (task == mLastParentBeforePip) {
+        if (task == mLastParentBeforePip && task != null) {
+            // Notify the TaskFragmentOrganizer that the activity is reparented back from pip.
+            mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController
+                    .onActivityReparentToTask(this);
             // Activity's reparented back from pip, clear the links once established
             clearLastParentBeforePip();
         }
@@ -1654,6 +1674,12 @@
                 : launchIntoPipHostActivity.getTask();
         mLastParentBeforePip.mChildPipActivity = this;
         mLaunchIntoPipHostActivity = launchIntoPipHostActivity;
+        final TaskFragment organizedTf = launchIntoPipHostActivity == null
+                ? getOrganizedTaskFragment()
+                : launchIntoPipHostActivity.getOrganizedTaskFragment();
+        mLastTaskFragmentOrganizerBeforePip = organizedTf != null
+                ? organizedTf.getTaskFragmentOrganizer()
+                : null;
     }
 
     private void clearLastParentBeforePip() {
@@ -1662,6 +1688,7 @@
             mLastParentBeforePip = null;
         }
         mLaunchIntoPipHostActivity = null;
+        mLastTaskFragmentOrganizerBeforePip = null;
     }
 
     @Nullable Task getLastParentBeforePip() {
@@ -1938,8 +1965,10 @@
                     // This style is propagated to the main window attributes with
                     // FLAG_SHOW_WALLPAPER from PhoneWindow#generateLayout.
                     || ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
+            mFillsParent = mOccludesParent;
             noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
         } else {
+            mFillsParent = mOccludesParent = true;
             noDisplay = false;
         }
 
@@ -2452,20 +2481,29 @@
             // Obsoleted snapshot.
             return false;
         }
-        final Rect taskBounds = task.getBounds();
-        final Point taskSize = snapshot.getTaskSize();
-        // Task size has changed? e.g. foldable device.
-        if (Math.abs(((float) taskSize.x / Math.max(taskSize.y, 1))
-                - ((float) taskBounds.width() / Math.max(taskBounds.height(), 1))) > 0.01f) {
-            return false;
-        }
         final int rotation = mDisplayContent.rotationForActivityInDifferentOrientation(this);
+        final int currentRotation = task.getWindowConfiguration().getRotation();
         final int targetRotation = rotation != ROTATION_UNDEFINED
                 // The display may rotate according to the orientation of this activity.
                 ? rotation
                 // The activity won't change display orientation.
-                : task.getWindowConfiguration().getRotation();
-        return snapshot.getRotation() == targetRotation;
+                : currentRotation;
+        if (snapshot.getRotation() != targetRotation) {
+            return false;
+        }
+        final Rect taskBounds = task.getBounds();
+        int w = taskBounds.width();
+        int h = taskBounds.height();
+        final Point taskSize = snapshot.getTaskSize();
+        if ((Math.abs(currentRotation - targetRotation) % 2) == 1) {
+            // Flip the size if the activity will show in 90 degree difference.
+            final int t = w;
+            w = h;
+            h = t;
+        }
+        // Task size might be changed with the same rotation such as on a foldable device.
+        return Math.abs(((float) taskSize.x / Math.max(taskSize.y, 1))
+                - ((float) w / Math.max(h, 1))) <= 0.01f;
     }
 
     /**
@@ -2825,7 +2863,7 @@
 
     @Override
     boolean fillsParent() {
-        return occludesParent(true /* includingFinishing */);
+        return mFillsParent;
     }
 
     /** Returns true if this activity is not finishing, is opaque and fills the entire space of
@@ -5518,8 +5556,8 @@
     }
 
     /** @return {@code true} if this activity should be made visible. */
-    private boolean shouldBeVisible(boolean behindFullscreenActivity, boolean ignoringKeyguard) {
-        updateVisibilityIgnoringKeyguard(behindFullscreenActivity);
+    private boolean shouldBeVisible(boolean behindOccludedContainer, boolean ignoringKeyguard) {
+        updateVisibilityIgnoringKeyguard(behindOccludedContainer);
 
         if (ignoringKeyguard) {
             return visibleIgnoringKeyguard;
@@ -5577,20 +5615,20 @@
         return differentUidOverlayActivity != null;
     }
 
-    void updateVisibilityIgnoringKeyguard(boolean behindFullscreenActivity) {
-        visibleIgnoringKeyguard = (!behindFullscreenActivity || mLaunchTaskBehind)
+    void updateVisibilityIgnoringKeyguard(boolean behindOccludedContainer) {
+        visibleIgnoringKeyguard = (!behindOccludedContainer || mLaunchTaskBehind)
                 && showToCurrentUser();
     }
 
     boolean shouldBeVisible() {
-        final Task rootTask = getRootTask();
-        if (rootTask == null) {
+        final Task task = getTask();
+        if (task == null) {
             return false;
         }
 
-        final boolean behindFullscreenActivity = !rootTask.shouldBeVisible(null /* starting */)
-                || rootTask.getOccludingActivityAbove(this) != null;
-        return shouldBeVisible(behindFullscreenActivity, false /* ignoringKeyguard */);
+        final boolean behindOccludedContainer = !task.shouldBeVisible(null /* starting */)
+                || task.getOccludingActivityAbove(this) != null;
+        return shouldBeVisible(behindOccludedContainer, false /* ignoringKeyguard */);
     }
 
     void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 5438c92..d443201 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2815,11 +2815,6 @@
             }
         }
 
-        if (mPreferredWindowingMode != WINDOWING_MODE_UNDEFINED
-                && intentTask.getWindowingMode() != mPreferredWindowingMode) {
-            intentTask.setWindowingMode(mPreferredWindowingMode);
-        }
-
         // Update the target's launch cookie to those specified in the options if set
         if (mStartActivity.mLaunchCookie != null) {
             intentActivity.mLaunchCookie = mStartActivity.mLaunchCookie;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index d997707..d254aaf 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -3331,7 +3331,7 @@
             }
             userId = activity.mUserId;
         }
-        return DevicePolicyCache.getInstance().isScreenCaptureAllowed(userId, false);
+        return DevicePolicyCache.getInstance().isScreenCaptureAllowed(userId);
     }
 
     private void onLocalVoiceInteractionStartedLocked(IBinder activity,
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 68a09a6..4f015d8 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -683,6 +683,9 @@
         } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
             a = mTransitionAnimation.loadAppTransitionAnimation(mNextAppTransitionPackage,
                     enter ? mNextAppTransitionEnter : mNextAppTransitionExit);
+            if (mNextAppTransitionBackgroundColor != 0) {
+                a.setBackdropColor(mNextAppTransitionBackgroundColor);
+            }
             ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
                     "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s "
                             + "isEntrance=%b Callers=%s",
@@ -842,10 +845,6 @@
         }
         setAppTransitionFinishedCallbackIfNeeded(a);
 
-        if (mNextAppTransitionBackgroundColor != 0) {
-            a.setBackdropColor(mNextAppTransitionBackgroundColor);
-        }
-
         return a;
     }
 
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index cefc871..3bda2e6 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -562,9 +562,6 @@
                 leafTask = null;
                 break;
             }
-            // The activity may be a child of embedded Task, but we want to find the owner Task.
-            // As a result, find the organized TaskFragment first.
-            final TaskFragment organizedTaskFragment = r.getOrganizedTaskFragment();
             // There are also cases where the Task contains non-embedded activity, such as launching
             // split TaskFragments from a non-embedded activity.
             // The hierarchy may looks like this:
@@ -575,10 +572,9 @@
             //    - TaskFragment
             //       - Activity
             // We also want to have the organizer handle the transition for such case.
-            final Task task = organizedTaskFragment != null
-                    ? organizedTaskFragment.getTask()
-                    : r.getTask();
-            if (task == null) {
+            final Task task = r.getTask();
+            // We don't support embedding in PiP, leave the animation to the PipTaskOrganizer.
+            if (task == null || task.inPinnedWindowingMode()) {
                 leafTask = null;
                 break;
             }
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index 67eb9c8..c3b25f7 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -19,7 +19,7 @@
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SYNC_ENGINE;
-import static com.android.server.wm.WindowManagerService.H.WINDOW_STATE_BLAST_SYNC_TIMEOUT;
+import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION;
 
 import android.annotation.NonNull;
 import android.os.Trace;
@@ -173,7 +173,7 @@
                 }
             };
             merged.addTransactionCommittedListener((r) -> { r.run(); }, callback::run);
-            mWm.mH.postDelayed(callback, WINDOW_STATE_BLAST_SYNC_TIMEOUT);
+            mWm.mH.postDelayed(callback, BLAST_TIMEOUT_DURATION);
 
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "onTransactionReady");
             mListener.onTransactionReady(mSyncId, merged);
@@ -261,7 +261,7 @@
     }
 
     int startSyncSet(TransactionReadyListener listener) {
-        return startSyncSet(listener, WindowState.BLAST_TIMEOUT_DURATION, "");
+        return startSyncSet(listener, BLAST_TIMEOUT_DURATION, "");
     }
 
     int startSyncSet(TransactionReadyListener listener, long timeoutMs, String name) {
@@ -271,7 +271,7 @@
     }
 
     void startSyncSet(SyncGroup s) {
-        startSyncSet(s, WindowState.BLAST_TIMEOUT_DURATION);
+        startSyncSet(s, BLAST_TIMEOUT_DURATION);
     }
 
     void startSyncSet(SyncGroup s, long timeoutMs) {
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index dfa3b74..863782a 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -78,8 +78,11 @@
      * Whether this {@link DisplayArea} should ignore fixed-orientation request. If {@code true}, it
      * can never specify orientation, but shows the fixed-orientation apps below it in the
      * letterbox; otherwise, it rotates based on the fixed-orientation request.
+     *
+     * <p>Note: use {@link #getIgnoreOrientationRequest} to access outside of {@link
+     * #setIgnoreOrientationRequest} since the value can be overridden at runtime on a device level.
      */
-    protected boolean mIgnoreOrientationRequest;
+    protected boolean mSetIgnoreOrientationRequest;
 
     DisplayArea(WindowManagerService wms, Type type, String name) {
         this(wms, type, name, FEATURE_UNDEFINED);
@@ -140,7 +143,7 @@
     @Override
     int getOrientation(int candidate) {
         mLastOrientationSource = null;
-        if (mIgnoreOrientationRequest) {
+        if (getIgnoreOrientationRequest()) {
             return SCREEN_ORIENTATION_UNSET;
         }
 
@@ -149,14 +152,15 @@
 
     @Override
     boolean handlesOrientationChangeFromDescendant() {
-        return !mIgnoreOrientationRequest && super.handlesOrientationChangeFromDescendant();
+        return !getIgnoreOrientationRequest()
+                && super.handlesOrientationChangeFromDescendant();
     }
 
     @Override
     boolean onDescendantOrientationChanged(WindowContainer requestingContainer) {
         // If this is set to ignore the orientation request, we don't propagate descendant
         // orientation request.
-        return !mIgnoreOrientationRequest
+        return !getIgnoreOrientationRequest()
                 && super.onDescendantOrientationChanged(requestingContainer);
     }
 
@@ -167,10 +171,10 @@
      * @return Whether the display orientation changed after calling this method.
      */
     boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) {
-        if (mIgnoreOrientationRequest == ignoreOrientationRequest) {
+        if (mSetIgnoreOrientationRequest == ignoreOrientationRequest) {
             return false;
         }
-        mIgnoreOrientationRequest = ignoreOrientationRequest;
+        mSetIgnoreOrientationRequest = ignoreOrientationRequest;
 
         // Check whether we should notify Display to update orientation.
         if (mDisplayContent == null) {
@@ -204,7 +208,11 @@
     }
 
     boolean getIgnoreOrientationRequest() {
-        return mIgnoreOrientationRequest;
+        // Adding an exception for when ignoreOrientationRequest is overridden at runtime for all
+        // DisplayArea-s. For example, this is needed for the Kids Mode since many Kids apps aren't
+        // optimised to support both orientations and it will be hard for kids to understand the
+        // app compat mode.
+        return mSetIgnoreOrientationRequest && !mWmService.isIgnoreOrientationRequestDisabled();
     }
 
     /**
@@ -289,8 +297,8 @@
     @Override
     void dump(PrintWriter pw, String prefix, boolean dumpAll) {
         super.dump(pw, prefix, dumpAll);
-        if (mIgnoreOrientationRequest) {
-            pw.println(prefix + "mIgnoreOrientationRequest=true");
+        if (mSetIgnoreOrientationRequest) {
+            pw.println(prefix + "mSetIgnoreOrientationRequest=true");
         }
         if (hasRequestedOverrideConfiguration()) {
             pw.println(prefix + "overrideConfig=" + getRequestedOverrideConfiguration());
@@ -600,7 +608,7 @@
         @Override
         int getOrientation(int candidate) {
             mLastOrientationSource = null;
-            if (mIgnoreOrientationRequest) {
+            if (getIgnoreOrientationRequest()) {
                 return SCREEN_ORIENTATION_UNSET;
             }
 
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2a0dfa8..285ad83 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1489,7 +1489,8 @@
 
     @Override
     boolean handlesOrientationChangeFromDescendant() {
-        return !mIgnoreOrientationRequest && !getDisplayRotation().isFixedToUserRotation();
+        return !getIgnoreOrientationRequest()
+                && !getDisplayRotation().isFixedToUserRotation();
     }
 
     /**
@@ -4909,7 +4910,7 @@
 
         @Override
         int getOrientation(int candidate) {
-            if (mIgnoreOrientationRequest) {
+            if (getIgnoreOrientationRequest()) {
                 return SCREEN_ORIENTATION_UNSET;
             }
 
@@ -6148,14 +6149,29 @@
 
     @Override
     boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) {
-        if (mIgnoreOrientationRequest == ignoreOrientationRequest) return false;
+        if (mSetIgnoreOrientationRequest == ignoreOrientationRequest) return false;
         final boolean rotationChanged = super.setIgnoreOrientationRequest(ignoreOrientationRequest);
         mWmService.mDisplayWindowSettings.setIgnoreOrientationRequest(
-                this, mIgnoreOrientationRequest);
+                this, mSetIgnoreOrientationRequest);
         return rotationChanged;
     }
 
     /**
+     * Updates orientation if necessary after ignore orientation request override logic in {@link
+     * WindowManagerService#isIgnoreOrientationRequestDisabled} changes at runtime.
+     */
+    void onIsIgnoreOrientationRequestDisabledChanged() {
+        if (mFocusedApp != null) {
+            // We record the last focused TDA that respects orientation request, check if this
+            // change may affect it.
+            onLastFocusedTaskDisplayAreaChanged(mFocusedApp.getDisplayArea());
+        }
+        if (mSetIgnoreOrientationRequest) {
+            updateOrientation();
+        }
+    }
+
+    /**
      * Locates the appropriate target window for scroll capture. The search progresses top to
      * bottom.
      * If {@code searchBehind} is non-null, the search will only consider windows behind this one.
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 2d7d705..62998cb 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -138,8 +138,8 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.policy.ForceShowNavBarSettingsObserver;
 import com.android.internal.policy.GestureNavigationSettingsObserver;
-import com.android.internal.policy.KidsModeSettingsObserver;
 import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.internal.policy.SystemBarUtils;
 import com.android.internal.protolog.common.ProtoLog;
@@ -300,10 +300,6 @@
     // needs to be opaque.
     private WindowState mNavBarBackgroundWindow;
 
-    // The window that draws fake rounded corners and should provide insets to calculate the correct
-    // rounded corner insets.
-    private WindowState mRoundedCornerWindow;
-
     /**
      * A collection of {@link AppearanceRegion} to indicate that which region of status bar applies
      * which appearance.
@@ -378,7 +374,7 @@
 
     private final WindowManagerInternal.AppTransitionListener mAppTransitionListener;
 
-    private final KidsModeSettingsObserver mKidsModeSettingsObserver;
+    private final ForceShowNavBarSettingsObserver mForceShowNavBarSettingsObserver;
     private boolean mForceShowNavigationBarEnabled;
 
     private class PolicyHandler extends Handler {
@@ -653,17 +649,17 @@
         });
         mHandler.post(mGestureNavigationSettingsObserver::register);
 
-        mKidsModeSettingsObserver = new KidsModeSettingsObserver(
+        mForceShowNavBarSettingsObserver = new ForceShowNavBarSettingsObserver(
                 mHandler, mContext);
-        mKidsModeSettingsObserver.setOnChangeRunnable(() -> {
+        mForceShowNavBarSettingsObserver.setOnChangeRunnable(() -> {
             synchronized (mLock) {
                 mForceShowNavigationBarEnabled =
-                        mKidsModeSettingsObserver.isEnabled();
+                        mForceShowNavBarSettingsObserver.isEnabled();
                 updateSystemBarAttributes();
             }
         });
-        mForceShowNavigationBarEnabled = mKidsModeSettingsObserver.isEnabled();
-        mHandler.post(mKidsModeSettingsObserver::register);
+        mForceShowNavigationBarEnabled = mForceShowNavBarSettingsObserver.isEnabled();
+        mHandler.post(mForceShowNavBarSettingsObserver::register);
     }
 
     /**
@@ -970,16 +966,10 @@
             mExtraNavBarAltPosition = getAltBarPosition(attrs);
         }
 
-        if (attrs.insetsRoundedCornerFrame) {
-            // Currently, only support one rounded corner window which is the TaskBar.
-            if (mRoundedCornerWindow != null && mRoundedCornerWindow != win) {
-                throw new IllegalArgumentException("Found multiple rounded corner window :"
-                        + " current = " + mRoundedCornerWindow
-                        + " new = " + win);
-            }
-            mRoundedCornerWindow = win;
-        } else if (mRoundedCornerWindow == win) {
-            mRoundedCornerWindow = null;
+        final InsetsSourceProvider provider = win.getControllableInsetProvider();
+        if (provider != null && provider.getSource().getInsetsRoundedCornerFrame()
+                != attrs.insetsRoundedCornerFrame) {
+            provider.getSource().setInsetsRoundedCornerFrame(attrs.insetsRoundedCornerFrame);
         }
     }
 
@@ -1326,9 +1316,6 @@
         if (mLastFocusedWindow == win) {
             mLastFocusedWindow = null;
         }
-        if (mRoundedCornerWindow == win) {
-            mRoundedCornerWindow = null;
-        }
 
         mInsetsSourceWindowsExceptIme.remove(win);
     }
@@ -1360,10 +1347,6 @@
         return mNavigationBar != null ? mNavigationBar : mNavigationBarAlt;
     }
 
-    WindowState getRoundedCornerWindow() {
-        return mRoundedCornerWindow;
-    }
-
     /**
      * Control the animation to run when a window's state changes.  Return a positive number to
      * force the animation to a specific resource ID, {@link #ANIMATION_STYLEABLE} to use the
@@ -2861,7 +2844,7 @@
     void release() {
         mDisplayContent.mTransitionController.unregisterLegacyListener(mAppTransitionListener);
         mHandler.post(mGestureNavigationSettingsObserver::unregister);
-        mHandler.post(mKidsModeSettingsObserver::unregister);
+        mHandler.post(mForceShowNavBarSettingsObserver::unregister);
         mImmersiveModeConfirmation.release();
     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 43ff580..f833773 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -702,17 +702,17 @@
     }
 
     boolean canRotateSeamlessly(int oldRotation, int newRotation) {
+        // If the navigation bar can't change sides, then it will jump when we change orientations
+        // and we don't rotate seamlessly - unless that is allowed, eg. with gesture navigation
+        // where the navbar is low-profile enough that this isn't very noticeable.
+        if (mAllowSeamlessRotationDespiteNavBarMoving || mDisplayPolicy.navigationBarCanMove()) {
+            return true;
+        }
         // For the upside down rotation we don't rotate seamlessly as the navigation bar moves
         // position. Note most apps (using orientation:sensor or user as opposed to fullSensor)
         // will not enter the reverse portrait orientation, so actually the orientation won't change
         // at all.
-        if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) {
-            return false;
-        }
-        // If the navigation bar can't change sides, then it will jump when we change orientations
-        // and we don't rotate seamlessly - unless that is allowed, eg. with gesture navigation
-        // where the navbar is low-profile enough that this isn't very noticeable.
-        return mAllowSeamlessRotationDespiteNavBarMoving || mDisplayPolicy.navigationBarCanMove();
+        return oldRotation != Surface.ROTATION_180 && newRotation != Surface.ROTATION_180;
     }
 
     void markForSeamlessRotation(WindowState w, boolean seamlesslyRotated) {
@@ -1224,16 +1224,8 @@
                 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
             // Otherwise, use sensor only if requested by the application or enabled
             // by default for USER or UNSPECIFIED modes.  Does not apply to NOSENSOR.
-            if (mAllowAllRotations == ALLOW_ALL_ROTATIONS_UNDEFINED) {
-                // Can't read this during init() because the context doesn't have display metrics at
-                // that time so we cannot determine tablet vs. phone then.
-                mAllowAllRotations = mContext.getResources().getBoolean(
-                        R.bool.config_allowAllRotations)
-                                ? ALLOW_ALL_ROTATIONS_ENABLED
-                                : ALLOW_ALL_ROTATIONS_DISABLED;
-            }
             if (sensorRotation != Surface.ROTATION_180
-                    || mAllowAllRotations == ALLOW_ALL_ROTATIONS_ENABLED
+                    || getAllowAllRotations() == ALLOW_ALL_ROTATIONS_ENABLED
                     || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
                     || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
                 preferredRotation = sensorRotation;
@@ -1322,6 +1314,19 @@
         }
     }
 
+    private int getAllowAllRotations() {
+        if (mAllowAllRotations == ALLOW_ALL_ROTATIONS_UNDEFINED) {
+            // Can't read this during init() because the context doesn't have display metrics at
+            // that time so we cannot determine tablet vs. phone then.
+            mAllowAllRotations = mContext.getResources().getBoolean(
+                    R.bool.config_allowAllRotations)
+                    ? ALLOW_ALL_ROTATIONS_ENABLED
+                    : ALLOW_ALL_ROTATIONS_DISABLED;
+        }
+
+        return mAllowAllRotations;
+    }
+
     private boolean isLandscapeOrSeascape(int rotation) {
         return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
     }
@@ -1349,6 +1354,11 @@
 
             case ActivityInfo.SCREEN_ORIENTATION_USER:
             case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
+                // When all rotations enabled it works with any of the 4 rotations
+                if (getAllowAllRotations() == ALLOW_ALL_ROTATIONS_ENABLED) {
+                    return preferredRotation >= 0;
+                }
+
                 // Works with any rotation except upside down.
                 return (preferredRotation >= 0) && (preferredRotation != Surface.ROTATION_180);
         }
@@ -1683,7 +1693,7 @@
                 mSensorRotation = (listener == null || !listener.mEnabled)
                         ? -2 /* disabled */ : dr.mLastSensorRotation;
                 final DisplayContent dc = dr.mDisplayContent;
-                mIgnoreOrientationRequest = dc.mIgnoreOrientationRequest;
+                mIgnoreOrientationRequest = dc.getIgnoreOrientationRequest();
                 final TaskDisplayArea requestingTda = dc.getOrientationRequestingTaskDisplayArea();
                 mNonDefaultRequestingTaskDisplayArea = requestingTda == null
                         ? "none" : requestingTda != dc.getDefaultTaskDisplayArea()
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 6162f12..5c8cfff 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -46,7 +46,6 @@
 import android.app.ActivityTaskManager;
 import android.app.StatusBarManager;
 import android.app.WindowConfiguration;
-import android.graphics.Insets;
 import android.graphics.Rect;
 import android.util.ArrayMap;
 import android.util.IntArray;
@@ -461,22 +460,10 @@
 
     private InsetsState adjustInsetsForRoundedCorners(WindowState w, InsetsState originalState,
             boolean copyState) {
-        final WindowState roundedCornerWindow = mPolicy.getRoundedCornerWindow();
         final Task task = w.getTask();
-        if (task != null && !task.getWindowConfiguration().tasksAreFloating()
-                && (roundedCornerWindow != null || task.inSplitScreen())) {
-            // Instead of using display frame to calculating rounded corner, for the fake rounded
-            // corners drawn by divider bar or task bar, we need to re-calculate rounded corners
-            // based on task bounds and if the task bounds is intersected with task bar, we should
-            // exclude the intersected part.
+        if (task != null && !task.getWindowConfiguration().tasksAreFloating()) {
+            // Use task bounds to calculating rounded corners if the task is not floating.
             final Rect roundedCornerFrame = new Rect(task.getBounds());
-            if (roundedCornerWindow != null
-                    && roundedCornerWindow.getControllableInsetProvider() != null) {
-                final InsetsSource source =
-                        roundedCornerWindow.getControllableInsetProvider().getSource();
-                final Insets insets = source.calculateInsets(roundedCornerFrame, false);
-                roundedCornerFrame.inset(insets);
-            }
             final InsetsState state = copyState ? new InsetsState(originalState) : originalState;
             state.setRoundedCornerFrame(roundedCornerFrame);
             return state;
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index e04644c..9853d13 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -123,7 +123,7 @@
         mDisplayContent = displayContent;
         mStateController = stateController;
         mFakeControl = new InsetsSourceControl(
-                source.getType(), null /* leash */, new Point(), Insets.NONE);
+                source.getType(), null /* leash */, new Point(), InsetsSourceControl.INVALID_HINTS);
         mControllable = InsetsPolicy.isInsetsTypeControllable(source.getType());
     }
 
@@ -170,6 +170,7 @@
         if (windowContainer == null) {
             setServerVisible(false);
             mSource.setVisibleFrame(null);
+            mSource.setInsetsRoundedCornerFrame(false);
             mSourceFrame.setEmpty();
         } else {
             mWindowContainer.getProvidedInsetsSources().put(mSource.getType(), mSource);
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index c162e8e..bb15d76 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -332,25 +332,29 @@
         if (windowSurface != null && windowSurface.isValid()) {
             Transaction transaction = mActivityRecord.getSyncTransaction();
 
+            final InsetsState insetsState = mainWindow.getInsetsState();
+            final InsetsSource taskbarInsetsSource =
+                    insetsState.peekSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
+
             if (!isLetterboxedNotForDisplayCutout(mainWindow)
-                    || !mLetterboxConfiguration.isLetterboxActivityCornersRounded()) {
+                    || !mLetterboxConfiguration.isLetterboxActivityCornersRounded()
+                    || taskbarInsetsSource == null) {
                 transaction
                         .setWindowCrop(windowSurface, null)
                         .setCornerRadius(windowSurface, 0);
                 return;
             }
 
-            final InsetsState insetsState = mainWindow.getInsetsState();
-            final InsetsSource taskbarInsetsSource =
-                    insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
-
             Rect cropBounds = null;
 
             // Rounded corners should be displayed above the taskbar. When taskbar is hidden,
             // an insets frame is equal to a navigation bar which shouldn't affect position of
             // rounded corners since apps are expected to handle navigation bar inset.
             // This condition checks whether the taskbar is visible.
-            if (taskbarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight) {
+            // Do not crop the taskbar inset if the window is in immersive mode - the user can
+            // swipe to show/hide the taskbar as an overlay.
+            if (taskbarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight
+                    && taskbarInsetsSource.isVisible()) {
                 cropBounds = new Rect(mActivityRecord.getBounds());
                 // Activity bounds are in screen coordinates while (0,0) for activity's surface
                 // control is at the top left corner of an app window so offsetting bounds
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 4fc31f8..0e7619c 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -643,9 +643,9 @@
         }
     }
 
-    void setSecureSurfaceState(int userId) {
+    void refreshSecureSurfaceState() {
         forAllWindows((w) -> {
-            if (w.mHasSurface && userId == w.mShowUserId) {
+            if (w.mHasSurface) {
                 w.mWinAnimator.setSecureLocked(w.isSecureLocked());
             }
         }, true /* traverseTopToBottom */);
@@ -2092,11 +2092,14 @@
             r.setWindowingMode(intermediateWindowingMode);
             r.mWaitForEnteringPinnedMode = true;
             rootTask.forAllTaskFragments(tf -> {
-                // When the Task is entering picture-in-picture, we should clear all override from
-                // the client organizer, so the PIP activity can get the correct config from the
-                // Task, and prevent conflict with the PipTaskOrganizer.
-                if (tf.isOrganizedTaskFragment()) {
-                    tf.resetAdjacentTaskFragment();
+                if (!tf.isOrganizedTaskFragment()) {
+                    return;
+                }
+                tf.resetAdjacentTaskFragment();
+                if (tf.getTopNonFinishingActivity() != null) {
+                    // When the Task is entering picture-in-picture, we should clear all override
+                    // from the client organizer, so the PIP activity can get the correct config
+                    // from the Task, and prevent conflict with the PipTaskOrganizer.
                     tf.updateRequestedOverrideConfiguration(EMPTY);
                 }
             });
@@ -2111,7 +2114,8 @@
             // to the root pinned task
             r.supportsEnterPipOnTaskSwitch = false;
 
-            if (organizedTf != null && organizedTf.mClearedTaskFragmentForPip) {
+            if (organizedTf != null && organizedTf.mClearedTaskFragmentForPip
+                    && organizedTf.isTaskVisibleRequested()) {
                 // Dispatch the pending info to TaskFragmentOrganizer before PIP animation.
                 // Otherwise, it will keep waiting for the empty TaskFragment to be non-empty.
                 mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent(
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index dc15cb7..17e1dd2 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1175,7 +1175,7 @@
         // Call this again after super onParentChanged in-case the surface wasn't created yet
         // (happens when the task is first inserted into the hierarchy). It's a no-op if it
         // already ran fully within super.onParentChanged
-        updateTaskOrganizerState(false /* forceUpdate */);
+        updateTaskOrganizerState();
 
         // TODO(b/168037178): The check for null display content and setting it to null doesn't
         //                    really make sense here...
@@ -1724,8 +1724,8 @@
     /** Returns {@code true} if this task is currently in split-screen. */
     boolean inSplitScreen() {
         return getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
-                && getRootTask() != null
-                && getRootTask().getAdjacentTaskFragment() != null;
+                && getCreatedByOrganizerTask() != null
+                && getCreatedByOrganizerTask().getAdjacentTaskFragment() != null;
     }
 
     private boolean supportsSplitScreenWindowingModeInner(@Nullable TaskDisplayArea tda) {
@@ -1951,7 +1951,7 @@
         }
 
         saveLaunchingStateIfNeeded();
-        final boolean taskOrgChanged = updateTaskOrganizerState(false /* forceUpdate */);
+        final boolean taskOrgChanged = updateTaskOrganizerState();
         if (taskOrgChanged) {
             updateSurfacePosition(getSyncTransaction());
             if (!isOrganized()) {
@@ -4269,21 +4269,18 @@
         return true;
     }
 
-    boolean updateTaskOrganizerState(boolean forceUpdate) {
-        return updateTaskOrganizerState(forceUpdate, false /* skipTaskAppeared */);
+    boolean updateTaskOrganizerState() {
+        return updateTaskOrganizerState(false /* skipTaskAppeared */);
     }
 
     /**
      * Called when the task state changes (ie. from windowing mode change) an the task organizer
      * state should also be updated.
      *
-     * @param forceUpdate Updates the task organizer to the one currently specified in the task
-     *                    org controller for the task's windowing mode, ignoring the cached
-     *                    windowing mode checks.
      * @param skipTaskAppeared Skips calling taskAppeared for the new organizer if it has changed
      * @return {@code true} if task organizer changed.
      */
-    boolean updateTaskOrganizerState(boolean forceUpdate, boolean skipTaskAppeared) {
+    boolean updateTaskOrganizerState(boolean skipTaskAppeared) {
         if (getSurfaceControl() == null) {
             // Can't call onTaskAppeared without a surfacecontrol, so defer this until next one
             // is created.
@@ -4295,7 +4292,10 @@
 
         final TaskOrganizerController controller = mWmService.mAtmService.mTaskOrganizerController;
         final ITaskOrganizer organizer = controller.getTaskOrganizer();
-        if (!forceUpdate && mTaskOrganizer == organizer) {
+        // Do not change to different organizer if the task is created by organizer because only
+        // the creator knows how to manage it.
+        if (mCreatedByOrganizer && mTaskOrganizer != null && organizer != null
+                && mTaskOrganizer != organizer) {
             return false;
         }
         return setTaskOrganizer(organizer, skipTaskAppeared);
@@ -5053,21 +5053,9 @@
             positionChildAtTop(rTask);
         }
         Task task = null;
-        if (!newTask && isOrhasTask) {
-            // Starting activity cannot be occluding activity, otherwise starting window could be
-            // remove immediately without transferring to starting activity.
-            final ActivityRecord occludingActivity = getOccludingActivityAbove(r);
-            if (occludingActivity != null) {
-                // Here it is!  Now, if this is not yet visible (occluded by another task) to the
-                // user, then just add it without starting; it will get started when the user
-                // navigates back to it.
-                ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Adding activity %s to task %s "
-                                + "callers: %s", r, task,
-                        new RuntimeException("here").fillInStackTrace());
-                rTask.positionChildAtTop(r);
-                ActivityOptions.abort(options);
-                return;
-            }
+        if (!newTask && isOrhasTask && !r.shouldBeVisible()) {
+            ActivityOptions.abort(options);
+            return;
         }
 
         // Place a new activity at top of root task, so it is next to interact with the user.
@@ -5697,9 +5685,7 @@
             return false;
         }
 
-        // See if there is an occluding activity on-top of this one.
-        final ActivityRecord occludingActivity = getOccludingActivityAbove(r);
-        if (occludingActivity != null) return false;
+        if (!r.shouldBeVisible()) return false;
 
         if (r.finishing) Slog.e(TAG, "willActivityBeVisible: Returning false,"
                 + " would have returned true for r=" + r);
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index d7691f6..fdb88312 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -642,7 +642,7 @@
     @Override
     int getOrientation(int candidate) {
         mLastOrientationSource = null;
-        if (mIgnoreOrientationRequest) {
+        if (getIgnoreOrientationRequest()) {
             return SCREEN_ORIENTATION_UNSET;
         }
         if (!canSpecifyOrientation()) {
@@ -965,7 +965,7 @@
         } else if (candidateTask != null) {
             final int position = onTop ? POSITION_TOP : POSITION_BOTTOM;
             final Task launchRootTask = getLaunchRootTask(resolvedWindowingMode, activityType,
-                    options, sourceTask, launchFlags);
+                    options, sourceTask, launchFlags, candidateTask);
             if (launchRootTask != null) {
                 if (candidateTask.getParent() == null) {
                     launchRootTask.addChild(candidateTask, position);
@@ -979,6 +979,11 @@
                     candidateTask.reparent(this, onTop);
                 }
             }
+            // Update windowing mode if necessary, e.g. launch into a different windowing mode.
+            if (windowingMode != WINDOWING_MODE_UNDEFINED && candidateTask.isRootTask()
+                    && candidateTask.getWindowingMode() != windowingMode) {
+                candidateTask.setWindowingMode(windowingMode);
+            }
             return candidateTask.getRootTask();
         }
         return new Task.Builder(mAtmService)
@@ -1114,6 +1119,13 @@
     @Nullable
     Task getLaunchRootTask(int windowingMode, int activityType, @Nullable ActivityOptions options,
             @Nullable Task sourceTask, int launchFlags) {
+        return getLaunchRootTask(windowingMode, activityType, options, sourceTask, launchFlags,
+                null /* candidateTask */);
+    }
+
+    @Nullable
+    Task getLaunchRootTask(int windowingMode, int activityType, @Nullable ActivityOptions options,
+            @Nullable Task sourceTask, int launchFlags, @Nullable Task candidateTask) {
         // Try to use the launch root task in options if available.
         if (options != null) {
             final Task launchRootTask = Task.fromWindowContainerToken(options.getLaunchRootTask());
@@ -1154,9 +1166,19 @@
         }
 
         // For a better split UX, If a task is launching from a created-by-organizer task, it should
-        // be launched into the same created-by-organizer task as well.
-        if (sourceTask != null) {
-            return sourceTask.getCreatedByOrganizerTask();
+        // be launched into the same created-by-organizer task as well. Unless, the candidate task
+        // is already positioned in the split.
+        Task preferredRootInSplit = sourceTask != null && sourceTask.inSplitScreen()
+                ? sourceTask.getCreatedByOrganizerTask() : null;
+        if (preferredRootInSplit != null) {
+            if (candidateTask != null) {
+                final Task candidateRoot = candidateTask.getCreatedByOrganizerTask();
+                if (candidateRoot != null && candidateRoot != preferredRootInSplit
+                        && preferredRootInSplit == candidateRoot.getAdjacentTaskFragment()) {
+                    preferredRootInSplit = candidateRoot;
+                }
+            }
+            return preferredRootInSplit;
         }
 
         return null;
@@ -1914,7 +1936,7 @@
         // Only allow to specify orientation if this TDA is not set to ignore orientation request,
         // and it is the last focused one on this logical display that can request orientation
         // request.
-        return !mIgnoreOrientationRequest
+        return !getIgnoreOrientationRequest()
                 && mDisplayContent.getOrientationRequestingTaskDisplayArea() == this;
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index e0346544..56e96fa 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -519,15 +519,20 @@
         return false;
     }
 
+    boolean isAllowedToEmbedActivity(@NonNull ActivityRecord a) {
+        return isAllowedToEmbedActivity(a, mTaskFragmentOrganizerUid);
+    }
+
     /**
      * Checks if the organized task fragment is allowed to have the specified activity, which is
      * allowed if an activity allows embedding in untrusted mode, or if the trusted mode can be
      * enabled.
      * @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord)
+     * @param uid   uid of the TaskFragment organizer.
      */
-    boolean isAllowedToEmbedActivity(@NonNull ActivityRecord a) {
+    boolean isAllowedToEmbedActivity(@NonNull ActivityRecord a, int uid) {
         return isAllowedToEmbedActivityInUntrustedMode(a)
-                || isAllowedToEmbedActivityInTrustedMode(a);
+                || isAllowedToEmbedActivityInTrustedMode(a, uid);
     }
 
     /**
@@ -544,20 +549,25 @@
                 == FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING;
     }
 
+    boolean isAllowedToEmbedActivityInTrustedMode(@NonNull ActivityRecord a) {
+        return isAllowedToEmbedActivityInTrustedMode(a, mTaskFragmentOrganizerUid);
+    }
+
     /**
      * Checks if the organized task fragment is allowed to embed activity in fully trusted mode,
      * which means that all transactions are allowed. This is supported in the following cases:
      * <li>the activity belongs to the same app as the organizer host;</li>
      * <li>the activity has declared the organizer host as trusted explicitly via known
      * certificate.</li>
+     * @param uid   uid of the TaskFragment organizer.
      */
-    boolean isAllowedToEmbedActivityInTrustedMode(@NonNull ActivityRecord a) {
-        if (UserHandle.getAppId(mTaskFragmentOrganizerUid) == SYSTEM_UID) {
+    boolean isAllowedToEmbedActivityInTrustedMode(@NonNull ActivityRecord a, int uid) {
+        if (UserHandle.getAppId(uid) == SYSTEM_UID) {
             // The system is trusted to embed other apps securely and for all users.
             return true;
         }
 
-        if (mTaskFragmentOrganizerUid == a.getUid()) {
+        if (uid == a.getUid()) {
             // Activities from the same UID can be embedded freely by the host.
             return true;
         }
@@ -570,7 +580,7 @@
         }
 
         AndroidPackage hostPackage = mAtmService.getPackageManagerInternalLocked()
-                .getPackage(mTaskFragmentOrganizerUid);
+                .getPackage(uid);
 
         return hostPackage != null && hostPackage.getSigningDetails().hasAncestorOrSelfWithDigest(
                 knownActivityEmbeddingCerts);
@@ -581,7 +591,9 @@
      * @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord)
      */
     boolean isAllowedToBeEmbeddedInTrustedMode() {
-        return forAllActivities(this::isAllowedToEmbedActivityInTrustedMode);
+        // Traverse all activities to see if any of them are not in the trusted mode.
+        final Predicate<ActivityRecord> callback = r -> !isAllowedToEmbedActivityInTrustedMode(r);
+        return !forAllActivities(callback);
     }
 
     /**
@@ -2144,7 +2156,8 @@
         if (applicationType != ACTIVITY_TYPE_UNDEFINED || !hasChild()) {
             return applicationType;
         }
-        return getTopChild().getActivityType();
+        final ActivityRecord activity = getTopNonFinishingActivity();
+        return activity != null ? activity.getActivityType() : getTopChild().getActivityType();
     }
 
     @Override
@@ -2302,11 +2315,32 @@
         return mTaskFragmentOrganizer != null;
     }
 
+    /** Whether the Task should be visible. */
+    boolean isTaskVisibleRequested() {
+        final Task task = getTask();
+        return task != null && task.isVisibleRequested();
+    }
+
     boolean isReadyToTransit() {
+        // We only wait when this is organized to give the organizer a chance to update.
+        if (!isOrganizedTaskFragment()) {
+            return true;
+        }
         // We don't want to start the transition if the organized TaskFragment is empty, unless
         // it is requested to be removed.
-        return !isOrganizedTaskFragment() || getTopNonFinishingActivity() != null
-                || mIsRemovalRequested;
+        if (getTopNonFinishingActivity() != null || mIsRemovalRequested) {
+            return true;
+        }
+        // Organizer shouldn't change embedded TaskFragment in PiP.
+        if (isEmbeddedTaskFragmentInPip()) {
+            return true;
+        }
+        // The TaskFragment becomes empty because the last running activity enters PiP when the Task
+        // is minimized.
+        if (mClearedTaskFragmentForPip && !isTaskVisibleRequested()) {
+            return true;
+        }
+        return false;
     }
 
     /** Clear {@link #mLastPausedActivity} for all {@link TaskFragment} children */
@@ -2424,8 +2458,19 @@
         mIsRemovalRequested = false;
         resetAdjacentTaskFragment();
         cleanUp();
+        final boolean shouldExecuteAppTransition =
+                mClearedTaskFragmentForPip && isTaskVisibleRequested();
         super.removeImmediately();
         sendTaskFragmentVanished();
+        if (shouldExecuteAppTransition && mDisplayContent != null) {
+            // When the Task is still visible, and the TaskFragment is removed because the last
+            // running activity is reparenting to PiP, it is possible that no activity is getting
+            // paused or resumed (having an embedded activity in split), thus we need to relayout
+            // and execute it explicitly.
+            mAtmService.addWindowLayoutReasons(
+                    ActivityTaskManagerService.LAYOUT_REASON_VISIBILITY_CHANGED);
+            mDisplayContent.executeAppTransition();
+        }
     }
 
     /** Called on remove to cleanup. */
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index bd351ac..eaf2526 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -51,6 +51,7 @@
  */
 public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerController.Stub {
     private static final String TAG = "TaskFragmentOrganizerController";
+    private static final long TEMPORARY_ACTIVITY_TOKEN_TIMEOUT_MS = 5000;
 
     private final ActivityTaskManagerService mAtmService;
     private final WindowManagerGlobalLock mGlobalLock;
@@ -78,10 +79,14 @@
     private class TaskFragmentOrganizerState implements IBinder.DeathRecipient {
         private final ArrayList<TaskFragment> mOrganizedTaskFragments = new ArrayList<>();
         private final ITaskFragmentOrganizer mOrganizer;
+        private final int mOrganizerPid;
+        private final int mOrganizerUid;
         private final Map<TaskFragment, TaskFragmentInfo> mLastSentTaskFragmentInfos =
                 new WeakHashMap<>();
         private final Map<TaskFragment, Configuration> mLastSentTaskFragmentParentConfigs =
                 new WeakHashMap<>();
+        private final Map<IBinder, ActivityRecord> mTemporaryActivityTokens =
+                new WeakHashMap<>();
 
         /**
          * Map from Task Id to {@link RemoteAnimationDefinition}.
@@ -91,8 +96,10 @@
         private final SparseArray<RemoteAnimationDefinition> mRemoteAnimationDefinitions =
                 new SparseArray<>();
 
-        TaskFragmentOrganizerState(ITaskFragmentOrganizer organizer) {
+        TaskFragmentOrganizerState(ITaskFragmentOrganizer organizer, int pid, int uid) {
             mOrganizer = organizer;
+            mOrganizerPid = pid;
+            mOrganizerUid = uid;
             try {
                 mOrganizer.asBinder().linkToDeath(this, 0 /*flags*/);
             } catch (RemoteException e) {
@@ -134,23 +141,23 @@
             mOrganizer.asBinder().unlinkToDeath(this, 0 /*flags*/);
         }
 
-        void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment tf) {
+        void onTaskFragmentAppeared(TaskFragment tf) {
             ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment appeared name=%s", tf.getName());
             final TaskFragmentInfo info = tf.getTaskFragmentInfo();
             try {
-                organizer.onTaskFragmentAppeared(info);
+                mOrganizer.onTaskFragmentAppeared(info);
                 mLastSentTaskFragmentInfos.put(tf, info);
                 tf.mTaskFragmentAppearedSent = true;
             } catch (RemoteException e) {
                 Slog.d(TAG, "Exception sending onTaskFragmentAppeared callback", e);
             }
-            onTaskFragmentParentInfoChanged(organizer, tf);
+            onTaskFragmentParentInfoChanged(tf);
         }
 
-        void onTaskFragmentVanished(ITaskFragmentOrganizer organizer, TaskFragment tf) {
+        void onTaskFragmentVanished(TaskFragment tf) {
             ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment vanished name=%s", tf.getName());
             try {
-                organizer.onTaskFragmentVanished(tf.getTaskFragmentInfo());
+                mOrganizer.onTaskFragmentVanished(tf.getTaskFragmentInfo());
             } catch (RemoteException e) {
                 Slog.d(TAG, "Exception sending onTaskFragmentVanished callback", e);
             }
@@ -159,10 +166,10 @@
             mLastSentTaskFragmentParentConfigs.remove(tf);
         }
 
-        void onTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) {
+        void onTaskFragmentInfoChanged(TaskFragment tf) {
             // Parent config may have changed. The controller will check if there is any important
             // config change for the organizer.
-            onTaskFragmentParentInfoChanged(organizer, tf);
+            onTaskFragmentParentInfoChanged(tf);
 
             // Check if the info is different from the last reported info.
             final TaskFragmentInfo info = tf.getTaskFragmentInfo();
@@ -174,14 +181,14 @@
             ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment info changed name=%s",
                     tf.getName());
             try {
-                organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo());
+                mOrganizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo());
                 mLastSentTaskFragmentInfos.put(tf, info);
             } catch (RemoteException e) {
                 Slog.d(TAG, "Exception sending onTaskFragmentInfoChanged callback", e);
             }
         }
 
-        void onTaskFragmentParentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) {
+        void onTaskFragmentParentInfoChanged(TaskFragment tf) {
             // Check if the parent info is different from the last reported parent info.
             if (tf.getParent() == null || tf.getParent().asTask() == null) {
                 mLastSentTaskFragmentParentConfigs.remove(tf);
@@ -197,30 +204,86 @@
                     "TaskFragment parent info changed name=%s parentTaskId=%d",
                     tf.getName(), parent.mTaskId);
             try {
-                organizer.onTaskFragmentParentInfoChanged(tf.getFragmentToken(), parentConfig);
+                mOrganizer.onTaskFragmentParentInfoChanged(tf.getFragmentToken(), parentConfig);
                 mLastSentTaskFragmentParentConfigs.put(tf, new Configuration(parentConfig));
             } catch (RemoteException e) {
                 Slog.d(TAG, "Exception sending onTaskFragmentParentInfoChanged callback", e);
             }
         }
 
-        void onTaskFragmentError(ITaskFragmentOrganizer organizer, IBinder errorCallbackToken,
-                Throwable exception) {
+        void onTaskFragmentError(IBinder errorCallbackToken, Throwable exception) {
             ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
                     "Sending TaskFragment error exception=%s", exception.toString());
             final Bundle exceptionBundle = putExceptionInBundle(exception);
             try {
-                organizer.onTaskFragmentError(errorCallbackToken, exceptionBundle);
+                mOrganizer.onTaskFragmentError(errorCallbackToken, exceptionBundle);
             } catch (RemoteException e) {
                 Slog.d(TAG, "Exception sending onTaskFragmentError callback", e);
             }
         }
+
+        void onActivityReparentToTask(ActivityRecord activity) {
+            if (activity.finishing) {
+                Slog.d(TAG, "Reparent activity=" + activity.token + " is finishing");
+                return;
+            }
+            final Task task = activity.getTask();
+            if (task == null || task.effectiveUid != mOrganizerUid) {
+                Slog.d(TAG, "Reparent activity=" + activity.token
+                        + " is not in a task belong to the organizer app.");
+                return;
+            }
+            if (!task.isAllowedToEmbedActivity(activity, mOrganizerUid)) {
+                Slog.d(TAG, "Reparent activity=" + activity.token
+                        + " is not allowed to be embedded.");
+                return;
+            }
+
+            final IBinder activityToken;
+            if (activity.getPid() == mOrganizerPid) {
+                // We only pass the actual token if the activity belongs to the organizer process.
+                activityToken = activity.token;
+            } else {
+                // For security, we can't pass the actual token if the activity belongs to a
+                // different process. In this case, we will pass a temporary token that organizer
+                // can use to reparent through WindowContainerTransaction.
+                activityToken = new Binder("TemporaryActivityToken");
+                mTemporaryActivityTokens.put(activityToken, activity);
+                final Runnable timeout = () -> {
+                    synchronized (mGlobalLock) {
+                        mTemporaryActivityTokens.remove(activityToken);
+                    }
+                };
+                mAtmService.mWindowManager.mH.postDelayed(timeout,
+                        TEMPORARY_ACTIVITY_TOKEN_TIMEOUT_MS);
+            }
+            ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Activity=%s reparent to taskId=%d",
+                    activity.token, task.mTaskId);
+            try {
+                mOrganizer.onActivityReparentToTask(task.mTaskId, activity.intent, activityToken);
+            } catch (RemoteException e) {
+                Slog.d(TAG, "Exception sending onActivityReparentToTask callback", e);
+            }
+        }
+    }
+
+    @Nullable
+    ActivityRecord getReparentActivityFromTemporaryToken(
+            @Nullable ITaskFragmentOrganizer organizer, @Nullable IBinder activityToken) {
+        if (organizer == null || activityToken == null) {
+            return null;
+        }
+        final TaskFragmentOrganizerState state = mTaskFragmentOrganizerState.get(
+                organizer.asBinder());
+        return state != null
+                ? state.mTemporaryActivityTokens.remove(activityToken)
+                : null;
     }
 
     @Override
     public void registerOrganizer(ITaskFragmentOrganizer organizer) {
         final int pid = Binder.getCallingPid();
-        final long uid = Binder.getCallingUid();
+        final int uid = Binder.getCallingUid();
         synchronized (mGlobalLock) {
             ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
                     "Register task fragment organizer=%s uid=%d pid=%d",
@@ -230,7 +293,7 @@
                         "Replacing existing organizer currently unsupported");
             }
             mTaskFragmentOrganizerState.put(organizer.asBinder(),
-                    new TaskFragmentOrganizerState(organizer));
+                    new TaskFragmentOrganizerState(organizer, pid, uid));
         }
     }
 
@@ -321,8 +384,10 @@
         PendingTaskFragmentEvent pendingEvent = getPendingTaskFragmentEvent(taskFragment,
                 PendingTaskFragmentEvent.EVENT_APPEARED);
         if (pendingEvent == null) {
-            pendingEvent = new PendingTaskFragmentEvent(taskFragment, organizer,
-                    PendingTaskFragmentEvent.EVENT_APPEARED);
+            pendingEvent = new PendingTaskFragmentEvent.Builder(
+                    PendingTaskFragmentEvent.EVENT_APPEARED, organizer)
+                    .setTaskFragment(taskFragment)
+                    .build();
             mPendingTaskFragmentEvents.add(pendingEvent);
         }
     }
@@ -347,7 +412,9 @@
         }
         PendingTaskFragmentEvent pendingEvent = getLastPendingLifecycleEvent(taskFragment);
         if (pendingEvent == null) {
-            pendingEvent = new PendingTaskFragmentEvent(taskFragment, organizer, eventType);
+            pendingEvent = new PendingTaskFragmentEvent.Builder(eventType, organizer)
+                            .setTaskFragment(taskFragment)
+                            .build();
         } else {
             if (pendingEvent.mEventType == PendingTaskFragmentEvent.EVENT_VANISHED) {
                 // Skipped the info changed event if vanished event is pending.
@@ -374,8 +441,10 @@
         if (!taskFragment.mTaskFragmentAppearedSent) {
             return;
         }
-        PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent(taskFragment,
-                organizer, PendingTaskFragmentEvent.EVENT_VANISHED);
+        final PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent.Builder(
+                PendingTaskFragmentEvent.EVENT_VANISHED, organizer)
+                .setTaskFragment(taskFragment)
+                .build();
         mPendingTaskFragmentEvents.add(pendingEvent);
         state.removeTaskFragment(taskFragment);
     }
@@ -384,8 +453,43 @@
             Throwable exception) {
         validateAndGetState(organizer);
         Slog.w(TAG, "onTaskFragmentError ", exception);
-        PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent(organizer,
-                errorCallbackToken, exception, PendingTaskFragmentEvent.EVENT_ERROR);
+        final PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent.Builder(
+                PendingTaskFragmentEvent.EVENT_ERROR, organizer)
+                .setErrorCallbackToken(errorCallbackToken)
+                .setException(exception)
+                .build();
+        mPendingTaskFragmentEvents.add(pendingEvent);
+    }
+
+    void onActivityReparentToTask(ActivityRecord activity) {
+        final ITaskFragmentOrganizer organizer;
+        if (activity.mLastTaskFragmentOrganizerBeforePip != null) {
+            // If the activity is previously embedded in an organized TaskFragment.
+            organizer = activity.mLastTaskFragmentOrganizerBeforePip;
+        } else {
+            // Find the topmost TaskFragmentOrganizer.
+            final Task task = activity.getTask();
+            final TaskFragment[] organizedTf = new TaskFragment[1];
+            task.forAllLeafTaskFragments(tf -> {
+                if (tf.isOrganizedTaskFragment()) {
+                    organizedTf[0] = tf;
+                    return true;
+                }
+                return false;
+            });
+            if (organizedTf[0] == null) {
+                return;
+            }
+            organizer = organizedTf[0].getTaskFragmentOrganizer();
+        }
+        if (!mTaskFragmentOrganizerState.containsKey(organizer.asBinder())) {
+            Slog.w(TAG, "The last TaskFragmentOrganizer no longer exists");
+            return;
+        }
+        final PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent.Builder(
+                PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENT_TO_TASK, organizer)
+                .setActivity(activity)
+                .build();
         mPendingTaskFragmentEvents.add(pendingEvent);
     }
 
@@ -422,13 +526,15 @@
         static final int EVENT_INFO_CHANGED = 2;
         static final int EVENT_PARENT_INFO_CHANGED = 3;
         static final int EVENT_ERROR = 4;
+        static final int EVENT_ACTIVITY_REPARENT_TO_TASK = 5;
 
         @IntDef(prefix = "EVENT_", value = {
                 EVENT_APPEARED,
                 EVENT_VANISHED,
                 EVENT_INFO_CHANGED,
                 EVENT_PARENT_INFO_CHANGED,
-                EVENT_ERROR
+                EVENT_ERROR,
+                EVENT_ACTIVITY_REPARENT_TO_TASK
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface EventType {}
@@ -436,34 +542,30 @@
         @EventType
         private final int mEventType;
         private final ITaskFragmentOrganizer mTaskFragmentOrg;
+        @Nullable
         private final TaskFragment mTaskFragment;
-        private final IBinder mErrorCallback;
+        @Nullable
+        private final IBinder mErrorCallbackToken;
+        @Nullable
         private final Throwable mException;
+        @Nullable
+        private final ActivityRecord mActivity;
         // Set when the event is deferred due to the host task is invisible. The defer time will
         // be the last active time of the host task.
         private long mDeferTime;
 
-        private PendingTaskFragmentEvent(TaskFragment taskFragment,
-                ITaskFragmentOrganizer taskFragmentOrg, @EventType int eventType) {
-            this(taskFragment, taskFragmentOrg, null /* errorCallback */,
-                    null /* exception */, eventType);
-
-        }
-
-        private PendingTaskFragmentEvent(ITaskFragmentOrganizer taskFragmentOrg,
-                IBinder errorCallback, Throwable exception, @EventType int eventType) {
-            this(null /* taskFragment */, taskFragmentOrg, errorCallback, exception,
-                    eventType);
-        }
-
-        private PendingTaskFragmentEvent(TaskFragment taskFragment,
-                ITaskFragmentOrganizer taskFragmentOrg, IBinder errorCallback, Throwable exception,
-                @EventType int eventType) {
-            mTaskFragment = taskFragment;
-            mTaskFragmentOrg = taskFragmentOrg;
-            mErrorCallback = errorCallback;
-            mException = exception;
+        private PendingTaskFragmentEvent(@EventType int eventType,
+                ITaskFragmentOrganizer taskFragmentOrg,
+                @Nullable TaskFragment taskFragment,
+                @Nullable IBinder errorCallbackToken,
+                @Nullable Throwable exception,
+                @Nullable ActivityRecord activity) {
             mEventType = eventType;
+            mTaskFragmentOrg = taskFragmentOrg;
+            mTaskFragment = taskFragment;
+            mErrorCallbackToken = errorCallbackToken;
+            mException = exception;
+            mActivity = activity;
         }
 
         /**
@@ -481,6 +583,50 @@
                     return false;
             }
         }
+
+        private static class Builder {
+            @EventType
+            private final int mEventType;
+            private final ITaskFragmentOrganizer mTaskFragmentOrg;
+            @Nullable
+            private TaskFragment mTaskFragment;
+            @Nullable
+            private IBinder mErrorCallbackToken;
+            @Nullable
+            private Throwable mException;
+            @Nullable
+            private ActivityRecord mActivity;
+
+            Builder(@EventType int eventType, ITaskFragmentOrganizer taskFragmentOrg) {
+                mEventType = eventType;
+                mTaskFragmentOrg = taskFragmentOrg;
+            }
+
+            Builder setTaskFragment(@Nullable TaskFragment taskFragment) {
+                mTaskFragment = taskFragment;
+                return this;
+            }
+
+            Builder setErrorCallbackToken(@Nullable IBinder errorCallbackToken) {
+                mErrorCallbackToken = errorCallbackToken;
+                return this;
+            }
+
+            Builder setException(@Nullable Throwable exception) {
+                mException = exception;
+                return this;
+            }
+
+            Builder setActivity(@Nullable ActivityRecord activity) {
+                mActivity = activity;
+                return this;
+            }
+
+            PendingTaskFragmentEvent build() {
+                return new PendingTaskFragmentEvent(mEventType, mTaskFragmentOrg, mTaskFragment,
+                        mErrorCallbackToken, mException, mActivity);
+            }
+        }
     }
 
     @Nullable
@@ -518,8 +664,13 @@
         // longer has activities. As a result, the organizer will never get this info changed event
         // and will not delete the TaskFragment because the organizer thinks the TaskFragment still
         // has running activities.
+        // Another case is when an organized TaskFragment became empty because the last running
+        // activity is reparented to a new Task due to enter PiP. We also want to notify the
+        // organizer, so it can remove the empty TaskFragment and update the paired TaskFragment
+        // without causing the extra delay.
         return event.mEventType == PendingTaskFragmentEvent.EVENT_INFO_CHANGED
-                && task.topRunningActivity() == null && lastInfo != null
+                && (task.topRunningActivity() == null || info.isTaskFragmentClearedForPip())
+                && lastInfo != null
                 && lastInfo.getRunningActivityCount() > 0 && info.getRunningActivityCount() == 0;
     }
 
@@ -591,20 +742,22 @@
         }
         switch (event.mEventType) {
             case PendingTaskFragmentEvent.EVENT_APPEARED:
-                state.onTaskFragmentAppeared(taskFragmentOrg, taskFragment);
+                state.onTaskFragmentAppeared(taskFragment);
                 break;
             case PendingTaskFragmentEvent.EVENT_VANISHED:
-                state.onTaskFragmentVanished(taskFragmentOrg, taskFragment);
+                state.onTaskFragmentVanished(taskFragment);
                 break;
             case PendingTaskFragmentEvent.EVENT_INFO_CHANGED:
-                state.onTaskFragmentInfoChanged(taskFragmentOrg, taskFragment);
+                state.onTaskFragmentInfoChanged(taskFragment);
                 break;
             case PendingTaskFragmentEvent.EVENT_PARENT_INFO_CHANGED:
-                state.onTaskFragmentParentInfoChanged(taskFragmentOrg, taskFragment);
+                state.onTaskFragmentParentInfoChanged(taskFragment);
                 break;
             case PendingTaskFragmentEvent.EVENT_ERROR:
-                state.onTaskFragmentError(taskFragmentOrg, event.mErrorCallback,
-                        event.mException);
+                state.onTaskFragmentError(event.mErrorCallbackToken, event.mException);
+                break;
+            case PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENT_TO_TASK:
+                state.onActivityReparentToTask(event.mActivity);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 9bf988f..6e84681 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -257,7 +257,7 @@
                     // organizer is disposed off to avoid inconsistent behavior.
                     t.removeImmediately();
                 } else {
-                    t.updateTaskOrganizerState(true /* forceUpdate */);
+                    t.updateTaskOrganizerState();
                 }
                 if (mOrganizedTasks.contains(t)) {
                     // updateTaskOrganizerState should remove the task from the list, but still
@@ -381,8 +381,7 @@
                 final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
                 mService.mRootWindowContainer.forAllTasks((task) -> {
                     boolean returnTask = !task.mCreatedByOrganizer;
-                    task.updateTaskOrganizerState(true /* forceUpdate */,
-                            returnTask /* skipTaskAppeared */);
+                    task.updateTaskOrganizerState(returnTask /* skipTaskAppeared */);
                     if (returnTask) {
                         SurfaceControl outSurfaceControl = state.addTaskWithoutCallback(task,
                                 "TaskOrganizerController.registerTaskOrganizer");
@@ -1001,6 +1000,19 @@
         }
     }
 
+    @Override
+    public void setIsIgnoreOrientationRequestDisabled(boolean isDisabled) {
+        enforceTaskPermission("setIsIgnoreOrientationRequestDisabled()");
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                mService.mWindowManager.setIsIgnoreOrientationRequestDisabled(isDisabled);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
     public boolean handleInterceptBackPressedOnTaskRoot(Task task) {
         if (task == null || !task.isOrganized()
                 || !mInterceptBackPressedOnRootTasks.contains(task.mTaskId)) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 454424c..dfbeb55 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -490,7 +490,6 @@
         }
 
         // Commit all going-invisible containers
-        boolean activitiesWentInvisible = false;
         for (int i = 0; i < mParticipants.size(); ++i) {
             final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
             if (ar != null) {
@@ -541,7 +540,6 @@
                         }
                         ar.commitVisibility(false /* visible */, false /* performLayout */,
                                 true /* fromTransition */);
-                        activitiesWentInvisible = true;
                     }
                 }
                 if (mChanges.get(ar).mVisible != visibleAtTransitionEnd) {
@@ -568,12 +566,10 @@
                 mController.dispatchLegacyAppTransitionFinished(ar);
             }
         }
-        if (activitiesWentInvisible) {
-            // Always schedule stop processing when transition finishes because activities don't
-            // stop while they are in a transition thus their stop could still be pending.
-            mController.mAtm.mTaskSupervisor
-                    .scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
-        }
+        // Always schedule stop processing when transition finishes because activities don't
+        // stop while they are in a transition thus their stop could still be pending.
+        mController.mAtm.mTaskSupervisor
+                .scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
 
         sendRemoteCallback(mClientAnimationFinishCallback);
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6334fc9..38eaaa0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -423,7 +423,7 @@
             "persist.wm.enable_remote_keyguard_animation";
 
     private static final int sEnableRemoteKeyguardAnimation =
-            SystemProperties.getInt(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, 1);
+            SystemProperties.getInt(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, 2);
 
     /**
      * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY
@@ -989,6 +989,8 @@
 
     final LetterboxConfiguration mLetterboxConfiguration;
 
+    private boolean mIsIgnoreOrientationRequestDisabled;
+
     final InputManagerService mInputManager;
     final DisplayManagerInternal mDisplayManagerInternal;
     final DisplayManager mDisplayManager;
@@ -2005,15 +2007,15 @@
      * the device policy cache.
      */
     @Override
-    public void refreshScreenCaptureDisabled(int userId) {
+    public void refreshScreenCaptureDisabled() {
         int callingUid = Binder.getCallingUid();
         if (callingUid != SYSTEM_UID) {
             throw new SecurityException("Only system can call refreshScreenCaptureDisabled.");
         }
 
         synchronized (mGlobalLock) {
-            // Update secure surface for all windows belonging to this user.
-            mRoot.setSecureSurfaceState(userId);
+            // Refresh secure surface for all windows.
+            mRoot.refreshSecureSurfaceState();
         }
     }
 
@@ -4083,6 +4085,36 @@
         }
     }
 
+    /**
+     * Controls whether ignore orientation request logic in {@link DisplayArea} is disabled
+     * at runtime.
+     *
+     * <p>Note: this assumes that {@link #mGlobalLock} is held by the caller.
+     *
+     * @param isDisabled when {@code true}, the system always ignores the value of {@link
+     *                   DisplayArea#getIgnoreOrientationRequest} and app requested orientation is
+     *                   respected.
+     */
+    void setIsIgnoreOrientationRequestDisabled(boolean isDisabled) {
+        if (isDisabled == mIsIgnoreOrientationRequestDisabled) {
+            return;
+        }
+        mIsIgnoreOrientationRequestDisabled = isDisabled;
+        for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
+            mRoot.getChildAt(i).onIsIgnoreOrientationRequestDisabledChanged();
+        }
+    }
+
+    /**
+     * Whether the system ignores the value of {@link DisplayArea#getIgnoreOrientationRequest} and
+     * app requested orientation is respected.
+     *
+     * <p>Note: this assumes that {@link #mGlobalLock} is held by the caller.
+     */
+    boolean isIgnoreOrientationRequestDisabled() {
+        return mIsIgnoreOrientationRequestDisabled;
+    }
+
     @Override
     public void freezeRotation(int rotation) {
         freezeDisplayRotation(Display.DEFAULT_DISPLAY, rotation);
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 27d6041..afeede7 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -30,6 +30,7 @@
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
@@ -707,7 +708,14 @@
             }
             case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT: {
                 final IBinder fragmentToken = hop.getNewParent();
-                final ActivityRecord activity = ActivityRecord.forTokenLocked(hop.getContainer());
+                final IBinder activityToken = hop.getContainer();
+                ActivityRecord activity = ActivityRecord.forTokenLocked(activityToken);
+                if (activity == null) {
+                    // The token may be a temporary token if the activity doesn't belong to
+                    // the organizer process.
+                    activity = mTaskFragmentOrganizerController
+                            .getReparentActivityFromTemporaryToken(organizer, activityToken);
+                }
                 final TaskFragment parent = mLaunchTaskFragments.get(fragmentToken);
                 if (parent == null || activity == null) {
                     final Throwable exception = new IllegalArgumentException(
@@ -770,6 +778,29 @@
                 }
                 break;
             }
+            case HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT: {
+                final TaskFragment tf = mLaunchTaskFragments.get(hop.getContainer());
+                if (tf == null || !tf.isAttached()) {
+                    Slog.e(TAG, "Attempt to operate on detached container: " + tf);
+                    break;
+                }
+                final ActivityRecord curFocus = tf.getDisplayContent().mFocusedApp;
+                if (curFocus != null && curFocus.getTaskFragment() == tf) {
+                    Slog.d(TAG, "The requested TaskFragment already has the focus.");
+                    break;
+                }
+                if (curFocus != null && curFocus.getTask() != tf.getTask()) {
+                    Slog.d(TAG, "The Task of the requested TaskFragment doesn't have focus.");
+                    break;
+                }
+                final ActivityRecord targetFocus = tf.getTopResumedActivity();
+                if (targetFocus == null) {
+                    Slog.d(TAG, "There is no resumed activity in the requested TaskFragment.");
+                    break;
+                }
+                tf.getDisplayContent().setFocusedApp(targetFocus);
+                break;
+            }
             default: {
                 // The other operations may change task order so they are skipped while in lock
                 // task mode. The above operations are still allowed because they don't move
@@ -1313,6 +1344,7 @@
                 case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
                 case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT:
                 case HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS:
+                case HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT:
                     // We are allowing organizer to start/reparent activity to a TaskFragment it
                     // created, or set two TaskFragments adjacent to each other. Nothing to check
                     // here because the TaskFragment may not be created yet, but will be created in
@@ -1408,7 +1440,8 @@
         }
         final WindowConfiguration requestedWindowConfig = requestedConfig.windowConfiguration;
         final WindowConfiguration parentWindowConfig = parentConfig.windowConfiguration;
-        if (!parentWindowConfig.getBounds().contains(requestedWindowConfig.getBounds())) {
+        if (!requestedWindowConfig.getBounds().isEmpty()
+                && !parentWindowConfig.getBounds().contains(requestedWindowConfig.getBounds())) {
             String msg = "Permission Denial: " + func + " from pid="
                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
                     + " trying to apply bounds outside of parent for non-trusted host,"
@@ -1417,6 +1450,7 @@
             throw new SecurityException(msg);
         }
         if (requestedWindowConfig.getAppBounds() != null
+                && !requestedWindowConfig.getAppBounds().isEmpty()
                 && parentWindowConfig.getAppBounds() != null
                 && !parentWindowConfig.getAppBounds().contains(
                         requestedWindowConfig.getAppBounds())) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index a9e66a1..faf54c8 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2033,8 +2033,7 @@
         if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SECURE) != 0) {
             return true;
         }
-        return !DevicePolicyCache.getInstance().isScreenCaptureAllowed(mShowUserId,
-                mOwnerCanAddInternalSystemWindow);
+        return !DevicePolicyCache.getInstance().isScreenCaptureAllowed(mShowUserId);
     }
 
     /**
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
index aca1389..3912991 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
@@ -21,6 +21,7 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
 import static android.app.admin.WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST;
 import static android.app.admin.WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
 
 import static com.android.server.devicepolicy.DevicePolicyManagerService.LOG_TAG;
 
@@ -159,6 +160,10 @@
     private static final String ATTR_VALUE = "value";
     private static final String ATTR_LAST_NETWORK_LOGGING_NOTIFICATION = "last-notification";
     private static final String ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS = "num-notifications";
+    private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIGS =
+            "preferential_network_service_configs";
+    private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG =
+            "preferential_network_service_config";
 
     DeviceAdminInfo info;
 
@@ -587,8 +592,6 @@
         }
         writeAttributeValueToXml(out, TAG_ADMIN_CAN_GRANT_SENSORS_PERMISSIONS,
                 mAdminCanGrantSensorsPermissions);
-        writeAttributeValueToXml(out, TAG_PREFERENTIAL_NETWORK_SERVICE_ENABLED,
-                mPreferentialNetworkServiceEnabled);
         if (mUsbDataSignalingEnabled != USB_DATA_SIGNALING_ENABLED_DEFAULT) {
             writeAttributeValueToXml(out, TAG_USB_DATA_SIGNALING, mUsbDataSignalingEnabled);
         }
@@ -603,6 +606,13 @@
                 writeAttributeValuesToXml(out, TAG_SSID_DENYLIST, TAG_SSID, ssids);
             }
         }
+        if (!mPreferentialNetworkServiceConfigs.isEmpty()) {
+            out.startTag(null, TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIGS);
+            for (PreferentialNetworkServiceConfig config : mPreferentialNetworkServiceConfigs) {
+                config.writeToXml(out);
+            }
+            out.endTag(null, TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIGS);
+        }
     }
 
     private List<String> ssidsToStrings(Set<WifiSsid> ssids) {
@@ -833,6 +843,14 @@
             } else if (TAG_PREFERENTIAL_NETWORK_SERVICE_ENABLED.equals(tag)) {
                 mPreferentialNetworkServiceEnabled = parser.getAttributeBoolean(null, ATTR_VALUE,
                         DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT);
+                if (mPreferentialNetworkServiceEnabled) {
+                    PreferentialNetworkServiceConfig.Builder configBuilder =
+                            new PreferentialNetworkServiceConfig.Builder();
+                    configBuilder.setEnabled(mPreferentialNetworkServiceEnabled);
+                    configBuilder.setNetworkId(NET_ENTERPRISE_ID_1);
+                    mPreferentialNetworkServiceConfigs = List.of(configBuilder.build());
+                    mPreferentialNetworkServiceEnabled = false;
+                }
             } else if (TAG_COMMON_CRITERIA_MODE.equals(tag)) {
                 mCommonCriteriaMode = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_PASSWORD_COMPLEXITY.equals(tag)) {
@@ -871,6 +889,12 @@
                 List<WifiSsid> ssids = readWifiSsids(parser, TAG_SSID);
                 mWifiSsidPolicy = new WifiSsidPolicy(
                         WIFI_SSID_POLICY_TYPE_DENYLIST, new ArraySet<>(ssids));
+            } else if (TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIGS.equals(tag)) {
+                List<PreferentialNetworkServiceConfig> configs =
+                        getPreferentialNetworkServiceConfigs(parser, tag);
+                if (!configs.isEmpty()) {
+                    mPreferentialNetworkServiceConfigs = configs;
+                }
             } else {
                 Slogf.w(LOG_TAG, "Unknown admin tag: %s", tag);
                 XmlUtils.skipCurrentTag(parser);
@@ -956,19 +980,43 @@
         return result;
     }
 
-    private TrustAgentInfo getTrustAgentInfo(TypedXmlPullParser parser, String tag)
+    private TrustAgentInfo getTrustAgentInfo(TypedXmlPullParser parser, String outerTag)
             throws XmlPullParserException, IOException  {
-        int outerDepthDAM = parser.getDepth();
-        int typeDAM;
+        int outerDepth = parser.getDepth();
+        int type;
         TrustAgentInfo result = new TrustAgentInfo(null);
+        while ((type = parser.next()) != END_DOCUMENT
+                && (type != END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == END_TAG || type == TEXT) {
+                continue;
+            }
+            String tag = parser.getName();
+            if (TAG_TRUST_AGENT_COMPONENT_OPTIONS.equals(tag)) {
+                result.options = PersistableBundle.restoreFromXml(parser);
+            } else {
+                Slogf.w(LOG_TAG, "Unknown tag under %s: %s", outerTag, tag);
+            }
+        }
+        return result;
+    }
+
+    @NonNull
+    private List<PreferentialNetworkServiceConfig> getPreferentialNetworkServiceConfigs(
+            TypedXmlPullParser parser, String tag) throws XmlPullParserException, IOException {
+        int outerDepth = parser.getDepth();
+        int typeDAM;
+        final List<PreferentialNetworkServiceConfig> result = new ArrayList<>();
         while ((typeDAM = parser.next()) != END_DOCUMENT
-                && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
+            && (typeDAM != END_TAG || parser.getDepth() > outerDepth)) {
             if (typeDAM == END_TAG || typeDAM == TEXT) {
                 continue;
             }
             String tagDAM = parser.getName();
-            if (TAG_TRUST_AGENT_COMPONENT_OPTIONS.equals(tagDAM)) {
-                result.options = PersistableBundle.restoreFromXml(parser);
+            if (TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG.equals(tagDAM)) {
+                final PreferentialNetworkServiceConfig preferentialNetworkServiceConfig =
+                        PreferentialNetworkServiceConfig.getPreferentialNetworkServiceConfig(
+                                parser, tag);
+                result.add(preferentialNetworkServiceConfig);
             } else {
                 Slogf.w(LOG_TAG, "Unknown tag under %s: %s", tag, tagDAM);
             }
@@ -1258,5 +1306,14 @@
             mFactoryResetProtectionPolicy.dump(pw);
             pw.decreaseIndent();
         }
+
+        if (mPreferentialNetworkServiceConfigs != null) {
+            pw.println("mPreferentialNetworkServiceConfigs:");
+            pw.increaseIndent();
+            for (PreferentialNetworkServiceConfig config : mPreferentialNetworkServiceConfigs) {
+                config.dump(pw);
+            }
+            pw.decreaseIndent();
+        }
     }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
index a301799..304d148 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
@@ -18,6 +18,7 @@
 import android.annotation.UserIdInt;
 import android.app.admin.DevicePolicyCache;
 import android.app.admin.DevicePolicyManager;
+import android.os.UserHandle;
 import android.util.IndentingPrintWriter;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
@@ -37,8 +38,12 @@
      */
     private final Object mLock = new Object();
 
+    /**
+     * Indicates which user is screen capture disallowed on. Can be {@link UserHandle#USER_NULL},
+     * {@link UserHandle#USER_ALL} or a concrete user ID.
+     */
     @GuardedBy("mLock")
-    private final SparseBooleanArray mScreenCaptureDisabled = new SparseBooleanArray();
+    private int mScreenCaptureDisallowedUser = UserHandle.USER_NULL;
 
     @GuardedBy("mLock")
     private final SparseIntArray mPasswordQuality = new SparseIntArray();
@@ -57,7 +62,6 @@
 
     public void onUserRemoved(int userHandle) {
         synchronized (mLock) {
-            mScreenCaptureDisabled.delete(userHandle);
             mPasswordQuality.delete(userHandle);
             mPermissionPolicy.delete(userHandle);
             mCanGrantSensorsPermissions.delete(userHandle);
@@ -65,15 +69,22 @@
     }
 
     @Override
-    public boolean isScreenCaptureAllowed(int userHandle, boolean ownerCanAddInternalSystemWindow) {
+    public boolean isScreenCaptureAllowed(int userHandle) {
         synchronized (mLock) {
-            return !mScreenCaptureDisabled.get(userHandle) || ownerCanAddInternalSystemWindow;
+            return mScreenCaptureDisallowedUser != UserHandle.USER_ALL
+                    && mScreenCaptureDisallowedUser != userHandle;
         }
     }
 
-    public void setScreenCaptureAllowed(int userHandle, boolean allowed) {
+    public int getScreenCaptureDisallowedUser() {
         synchronized (mLock) {
-            mScreenCaptureDisabled.put(userHandle, !allowed);
+            return mScreenCaptureDisallowedUser;
+        }
+    }
+
+    public void setScreenCaptureDisallowedUser(int userHandle) {
+        synchronized (mLock) {
+            mScreenCaptureDisallowedUser = userHandle;
         }
     }
 
@@ -125,7 +136,7 @@
     public void dump(IndentingPrintWriter pw) {
         pw.println("Device policy cache:");
         pw.increaseIndent();
-        pw.println("Screen capture disabled: " + mScreenCaptureDisabled.toString());
+        pw.println("Screen capture disallowed user: " + mScreenCaptureDisallowedUser);
         pw.println("Password quality: " + mPasswordQuality.toString());
         pw.println("Permission policy: " + mPermissionPolicy.toString());
         pw.println("Admin can grant sensors permission: "
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java
index 9a0b5c7..48a436f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java
@@ -69,6 +69,7 @@
     private static final String TAG_PASSWORD_VALIDITY = "password-validity";
     private static final String TAG_PASSWORD_TOKEN_HANDLE = "password-token";
     private static final String TAG_PROTECTED_PACKAGES = "protected-packages";
+    private static final String TAG_BYPASS_ROLE_QUALIFICATIONS = "bypass-role-qualifications";
     private static final String ATTR_VALUE = "value";
     private static final String ATTR_ALIAS = "alias";
     private static final String ATTR_ID = "id";
@@ -107,6 +108,8 @@
     int mPasswordOwner = -1;
     long mLastMaximumTimeToLock = -1;
     boolean mUserSetupComplete = false;
+    boolean mBypassDevicePolicyManagementRoleQualifications = false;
+    String mCurrentRoleHolder;
     boolean mPaired = false;
     int mUserProvisioningState;
     int mPermissionPolicy;
@@ -374,6 +377,12 @@
                 out.endTag(null, TAG_APPS_SUSPENDED);
             }
 
+            if (policyData.mBypassDevicePolicyManagementRoleQualifications) {
+                out.startTag(null, TAG_BYPASS_ROLE_QUALIFICATIONS);
+                out.attribute(null, ATTR_VALUE, policyData.mCurrentRoleHolder);
+                out.endTag(null, TAG_BYPASS_ROLE_QUALIFICATIONS);
+            }
+
             out.endTag(null, "policies");
 
             out.endDocument();
@@ -558,6 +567,9 @@
                 } else if (TAG_APPS_SUSPENDED.equals(tag)) {
                     policy.mAppsSuspended =
                             parser.getAttributeBoolean(null, ATTR_VALUE, false);
+                } else if (TAG_BYPASS_ROLE_QUALIFICATIONS.equals(tag)) {
+                    policy.mBypassDevicePolicyManagementRoleQualifications = true;
+                    policy.mCurrentRoleHolder =  parser.getAttributeValue(null, ATTR_VALUE);
                 } else {
                     Slogf.w(TAG, "Unknown tag: %s", tag);
                     XmlUtils.skipCurrentTag(parser);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 18bffeb..d1fac87 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -138,7 +138,6 @@
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
-import static android.provider.Settings.Global.BYPASS_DEVICE_POLICY_MANAGEMENT_ROLE_QUALIFICATIONS;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
 import static android.provider.Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED;
 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
@@ -222,6 +221,7 @@
 import android.app.admin.WifiSsidPolicy;
 import android.app.backup.IBackupManager;
 import android.app.compat.CompatChanges;
+import android.app.role.OnRoleHoldersChangedListener;
 import android.app.role.RoleManager;
 import android.app.trust.TrustManager;
 import android.app.usage.UsageStatsManagerInternal;
@@ -255,6 +255,7 @@
 import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.Signature;
 import android.content.pm.StringParceledListSlice;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
@@ -409,6 +410,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -756,6 +758,7 @@
     private @UserIdInt int mNetworkLoggingNotificationUserId = UserHandle.USER_NULL;
 
     private final DeviceManagementResourcesProvider mDeviceManagementResourcesProvider;
+    private final DevicePolicyManagementRoleObserver mDevicePolicyManagementRoleObserver;
 
     private static final boolean ENABLE_LOCK_GUARD = true;
 
@@ -1823,6 +1826,8 @@
         mBugreportCollectionManager = new RemoteBugreportManager(this, mInjector);
 
         mDeviceManagementResourcesProvider = mInjector.getDeviceManagementResourcesProvider();
+        mDevicePolicyManagementRoleObserver = new DevicePolicyManagementRoleObserver(mContext);
+        mDevicePolicyManagementRoleObserver.register();
 
         // "Lite" interface is available even when the device doesn't have the feature
         LocalServices.addService(DevicePolicyManagerLiteInternal.class, mLocalService);
@@ -1963,6 +1968,7 @@
 
             mOwners.removeProfileOwner(userHandle);
             mOwners.writeProfileOwner(userHandle);
+            pushScreenCapturePolicy(userHandle);
 
             DevicePolicyData policy = mUserData.get(userHandle);
             if (policy != null) {
@@ -3183,8 +3189,9 @@
 
     @Override
     void handleStartUser(int userId) {
-        updateScreenCaptureDisabled(userId,
-                getScreenCaptureDisabled(null, userId, false));
+        synchronized (getLockObject()) {
+            pushScreenCapturePolicy(userId);
+        }
         pushUserRestrictions(userId);
         // When system user is started (device boot), load cache for all users.
         // This is to mitigate the potential race between loading the cache and keyguard
@@ -6919,7 +6926,6 @@
             notifyResetProtectionPolicyChanged(frpAgentUid);
         }
         mLockSettingsInternal.refreshStrongAuthTimeout(parentId);
-        updateScreenCaptureDisabled(parentId, getScreenCaptureDisabled(null, parentId, false));
 
         Slogf.i(LOG_TAG, "Cleaning up device-wide policies done.");
     }
@@ -7686,10 +7692,7 @@
             if (ap.disableScreenCapture != disabled) {
                 ap.disableScreenCapture = disabled;
                 saveSettingsLocked(caller.getUserId());
-                final int affectedUserId = parent
-                        ? getProfileParentId(caller.getUserId())
-                        : caller.getUserId();
-                updateScreenCaptureDisabled(affectedUserId, disabled);
+                pushScreenCapturePolicy(caller.getUserId());
             }
         }
         DevicePolicyEventLogger
@@ -7699,6 +7702,38 @@
                 .write();
     }
 
+    // Push the screen capture policy for a given userId. If screen capture is disabled by the
+    // DO or COPE PO on the parent profile, then this takes precedence as screen capture will
+    // be disabled device-wide.
+    private void pushScreenCapturePolicy(int adminUserId) {
+        // Update screen capture device-wide if disabled by the DO or COPE PO on the parent profile.
+        ActiveAdmin admin =
+                getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceParentLocked(
+                        UserHandle.USER_SYSTEM);
+        if (admin != null && admin.disableScreenCapture) {
+            setScreenCaptureDisabled(UserHandle.USER_ALL);
+        } else {
+            // Otherwise, update screen capture only for the calling user.
+            admin = getProfileOwnerAdminLocked(adminUserId);
+            if (admin != null && admin.disableScreenCapture) {
+                setScreenCaptureDisabled(adminUserId);
+            } else {
+                setScreenCaptureDisabled(UserHandle.USER_NULL);
+            }
+        }
+    }
+
+    // Set the latest screen capture policy, overriding any existing ones.
+    // userHandle can be one of USER_ALL, USER_NULL or a concrete userId.
+    private void setScreenCaptureDisabled(int userHandle) {
+        int current = mPolicyCache.getScreenCaptureDisallowedUser();
+        if (userHandle == current) {
+            return;
+        }
+        mPolicyCache.setScreenCaptureDisallowedUser(userHandle);
+        updateScreenCaptureDisabled();
+    }
+
     /**
      * Returns whether or not screen capture is disabled for a given admin, or disabled for any
      * active admin (if given admin is null).
@@ -7708,7 +7743,6 @@
         if (!mHasFeature) {
             return false;
         }
-
         final CallerIdentity caller = getCallerIdentity(who);
         Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle));
 
@@ -7716,29 +7750,13 @@
             Preconditions.checkCallAuthorization(
                     isProfileOwnerOfOrganizationOwnedDevice(getCallerIdentity().getUserId()));
         }
-
-        synchronized (getLockObject()) {
-            if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
-                return (admin != null) && admin.disableScreenCapture;
-            }
-
-            final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
-            List<ActiveAdmin> admins = getActiveAdminsForAffectedUserLocked(affectedUserId);
-            for (ActiveAdmin admin: admins) {
-                if (admin.disableScreenCapture) {
-                    return true;
-                }
-            }
-            return false;
-        }
+        return !mPolicyCache.isScreenCaptureAllowed(userHandle);
     }
 
-    private void updateScreenCaptureDisabled(int userHandle, boolean disabled) {
-        mPolicyCache.setScreenCaptureAllowed(userHandle, !disabled);
+    private void updateScreenCaptureDisabled() {
         mHandler.post(() -> {
             try {
-                mInjector.getIWindowManager().refreshScreenCaptureDisabled(userHandle);
+                mInjector.getIWindowManager().refreshScreenCaptureDisabled();
             } catch (RemoteException e) {
                 Slogf.w(LOG_TAG, "Unable to notify WindowManager.", e);
             }
@@ -8690,6 +8708,7 @@
     }
 
     ActiveAdmin getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(int userId) {
+        ensureLocked();
         ActiveAdmin admin = getDeviceOwnerAdminLocked();
         if (admin == null) {
             admin = getProfileOwnerOfOrganizationOwnedDeviceLocked(userId);
@@ -8697,6 +8716,16 @@
         return admin;
     }
 
+    ActiveAdmin getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceParentLocked(int userId) {
+        ensureLocked();
+        ActiveAdmin admin = getDeviceOwnerAdminLocked();
+        if (admin != null) {
+            return admin;
+        }
+        admin = getProfileOwnerOfOrganizationOwnedDeviceLocked(userId);
+        return admin != null ? admin.getParentActiveAdmin() : null;
+    }
+
     @Override
     public void clearDeviceOwner(String packageName) {
         Objects.requireNonNull(packageName, "packageName is null");
@@ -14625,6 +14654,13 @@
             throw new SecurityException(
                     "Only the system can mark a profile owner of organization-owned device.");
         }
+        // Only a test admin can be unmarked as a profile owner on an organization-owned device.
+        synchronized (getLockObject()) {
+            if (!isProfileOwnerOnOrganizationOwnedDevice && !isAdminTestOnlyLocked(who, userId)) {
+                throw new SecurityException("Only a test admin can be unmarked as a "
+                        + "profile owner of organization-owned device.");
+            }
+        }
 
         if (isAdb(caller)) {
             if (hasIncompatibleAccountsOrNonAdbNoLock(caller, userId, who)) {
@@ -15151,6 +15187,7 @@
             saveSettingsLocked(userHandle);
             updateMaximumTimeToLockLocked(userHandle);
             policy.mRemovingAdmins.remove(adminReceiver);
+            pushScreenCapturePolicy(userHandle);
 
             Slogf.i(LOG_TAG, "Device admin " + adminReceiver + " removed from user " + userHandle);
         }
@@ -18251,16 +18288,20 @@
                     preferenceBuilder.setPreference(
                             PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
                 }
+                preferenceBuilder.setIncludedUids(
+                        preferentialNetworkServiceConfig.getIncludedUids());
+                preferenceBuilder.setExcludedUids(
+                        preferentialNetworkServiceConfig.getExcludedUids());
+                preferenceBuilder.setPreferenceEnterpriseId(
+                        preferentialNetworkServiceConfig.getNetworkId());
             } else {
                 preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT);
             }
-            preferenceBuilder.setIncludedUids(preferentialNetworkServiceConfig.getIncludedUids());
-            preferenceBuilder.setExcludedUids(preferentialNetworkServiceConfig.getExcludedUids());
-            preferenceBuilder.setPreferenceEnterpriseId(
-                    preferentialNetworkServiceConfig.getNetworkId());
+
 
             preferences.add(preferenceBuilder.build());
         }
+        Slogf.d(LOG_TAG, "updateNetworkPreferenceForUser to " + preferences);
         mInjector.binderWithCleanCallingIdentity(() ->
                 mInjector.getConnectivityManager().setProfileNetworkPreferences(
                         UserHandle.of(userId), preferences,
@@ -18627,16 +18668,11 @@
         Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
                 android.Manifest.permission.MANAGE_ROLE_HOLDERS));
         return mInjector.binderWithCleanCallingIdentity(() -> {
-            if (mInjector.settingsGlobalGetInt(
-                    BYPASS_DEVICE_POLICY_MANAGEMENT_ROLE_QUALIFICATIONS, /* def= */ 0) == 1) {
+            if (getUserData(
+                    UserHandle.USER_SYSTEM).mBypassDevicePolicyManagementRoleQualifications) {
                 return true;
             }
-            if (shouldAllowBypassingDevicePolicyManagementRoleQualificationInternal()) {
-                mInjector.settingsGlobalPutInt(
-                        BYPASS_DEVICE_POLICY_MANAGEMENT_ROLE_QUALIFICATIONS, /* value= */ 1);
-                return true;
-            }
-            return false;
+            return shouldAllowBypassingDevicePolicyManagementRoleQualificationInternal();
         });
     }
 
@@ -18649,6 +18685,142 @@
         return accounts.length == 0;
     }
 
+    private void setBypassDevicePolicyManagementRoleQualificationStateInternal(
+            String currentRoleHolder, boolean allowBypass) {
+        boolean stateChanged = false;
+        DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM);
+        if (policy.mBypassDevicePolicyManagementRoleQualifications != allowBypass) {
+            policy.mBypassDevicePolicyManagementRoleQualifications = allowBypass;
+            stateChanged = true;
+        }
+        if (!Objects.equals(currentRoleHolder, policy.mCurrentRoleHolder)) {
+            policy.mCurrentRoleHolder = currentRoleHolder;
+            stateChanged = true;
+        }
+        if (stateChanged) {
+            synchronized (getLockObject()) {
+                saveSettingsLocked(UserHandle.USER_SYSTEM);
+            }
+        }
+    }
+
+    private final class DevicePolicyManagementRoleObserver implements OnRoleHoldersChangedListener {
+        private RoleManager mRm;
+        private final Executor mExecutor;
+        private final Context mContext;
+
+        DevicePolicyManagementRoleObserver(@NonNull Context context) {
+            mContext = context;
+            mExecutor = mContext.getMainExecutor();
+            mRm = mContext.getSystemService(RoleManager.class);
+        }
+
+        public void register() {
+            mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.SYSTEM);
+        }
+
+        @Override
+        public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
+            if (!RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT.equals(roleName)) {
+                return;
+            }
+            String newRoleHolder = getRoleHolder();
+            if (isDefaultRoleHolder(newRoleHolder)) {
+                Slogf.i(LOG_TAG,
+                        "onRoleHoldersChanged: Default role holder is set, returning early");
+                return;
+            }
+            if (newRoleHolder == null) {
+                Slogf.i(LOG_TAG,
+                        "onRoleHoldersChanged: New role holder is null, returning early");
+                return;
+            }
+            if (shouldAllowBypassingDevicePolicyManagementRoleQualificationInternal()) {
+                Slogf.w(LOG_TAG,
+                        "onRoleHoldersChanged: Updating current role holder to " + newRoleHolder);
+                setBypassDevicePolicyManagementRoleQualificationStateInternal(
+                        newRoleHolder, /* allowBypass= */ true);
+                return;
+            }
+            DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM);
+            if (!newRoleHolder.equals(policy.mCurrentRoleHolder)) {
+                Slogf.w(LOG_TAG,
+                        "onRoleHoldersChanged: You can't set a different role holder, role "
+                                + "is getting revoked from " + newRoleHolder);
+                setBypassDevicePolicyManagementRoleQualificationStateInternal(
+                        /* currentRoleHolder= */ null, /* allowBypass= */ false);
+                mRm.removeRoleHolderAsUser(
+                        RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT,
+                        newRoleHolder,
+                        /* flags= */ 0,
+                        user,
+                        mExecutor,
+                        successful -> {});
+            }
+        }
+
+        private String getRoleHolder() {
+            return DevicePolicyManagerService.this.getDevicePolicyManagementRoleHolderPackageName(
+                    mContext);
+        }
+
+        private boolean isDefaultRoleHolder(String packageName) {
+            String defaultRoleHolder = getDefaultRoleHolderPackageName();
+            if (packageName == null || defaultRoleHolder == null) {
+                return false;
+            }
+            if (!defaultRoleHolder.equals(packageName)) {
+                return false;
+            }
+            return hasSigningCertificate(
+                    packageName, getDefaultRoleHolderPackageSignature());
+        }
+
+        private boolean hasSigningCertificate(String packageName, String  certificateString) {
+            if (packageName == null || certificateString == null) {
+                return false;
+            }
+            byte[] certificate;
+            try {
+                certificate = new Signature(certificateString).toByteArray();
+            } catch (IllegalArgumentException e) {
+                Slogf.w(LOG_TAG, "Cannot parse signing certificate: " + certificateString, e);
+                return false;
+            }
+            PackageManager pm = mInjector.getPackageManager();
+            return pm.hasSigningCertificate(
+                    packageName, certificate, PackageManager.CERT_INPUT_SHA256);
+        }
+
+        private String getDefaultRoleHolderPackageName() {
+            String[] info = getDefaultRoleHolderPackageNameAndSignature();
+            if (info == null) {
+                return null;
+            }
+            return info[0];
+        }
+
+        private String getDefaultRoleHolderPackageSignature() {
+            String[] info = getDefaultRoleHolderPackageNameAndSignature();
+            if (info == null || info.length < 2) {
+                return null;
+            }
+            return info[1];
+        }
+
+        private String[] getDefaultRoleHolderPackageNameAndSignature() {
+            String packageNameAndSignature = mContext.getString(
+                    com.android.internal.R.string.config_devicePolicyManagement);
+            if (TextUtils.isEmpty(packageNameAndSignature)) {
+                return null;
+            }
+            if (packageNameAndSignature.contains(":")) {
+                return packageNameAndSignature.split(":");
+            }
+            return new String[]{packageNameAndSignature};
+        }
+    }
+
     @Override
     public List<UserHandle> getPolicyManagedProfiles(@NonNull UserHandle user) {
         Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
diff --git a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
index 7b15224..9c0f713 100644
--- a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
+++ b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
@@ -30,6 +30,7 @@
 import com.android.server.pm.parsing.pkg.PackageImpl
 import com.android.server.pm.parsing.pkg.ParsedPackage
 import com.android.server.pm.resolution.ComponentResolver
+import com.android.server.pm.snapshot.PackageDataSnapshot
 import com.android.server.pm.test.override.PackageManagerComponentLabelIconOverrideTest.Companion.Params.AppType
 import com.android.server.testutils.TestHandler
 import com.android.server.testutils.mock
@@ -361,8 +362,8 @@
             whenever(this.isCallerRecents(anyInt())) { false }
         }
         val mockAppsFilter: AppsFilterImpl = mockThrowOnUnmocked {
-            whenever(this.shouldFilterApplication(anyInt(), any<PackageSetting>(),
-                    any<PackageSetting>(), anyInt())) { false }
+            whenever(this.shouldFilterApplication(any<PackageDataSnapshot>(), anyInt(), 
+                    any<PackageSetting>(), any<PackageSetting>(), anyInt())) { false }
             whenever(this.snapshot()) { this@mockThrowOnUnmocked }
             whenever(registerObserver(any())).thenCallRealMethod()
         }
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp
index 670c159..08c68b9 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -42,6 +42,8 @@
     static_libs: [
         "androidx.test.core",
         "androidx.test.runner",
+        "androidx.test.espresso.core",
+        "androidx.test.espresso.contrib",
         "androidx.test.ext.truth",
         "frameworks-base-testutils",
         "hamcrest-library",
diff --git a/services/tests/mockingservicestests/AndroidManifest.xml b/services/tests/mockingservicestests/AndroidManifest.xml
index 7714cf0..07b763d 100644
--- a/services/tests/mockingservicestests/AndroidManifest.xml
+++ b/services/tests/mockingservicestests/AndroidManifest.xml
@@ -32,6 +32,8 @@
     <uses-permission
         android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/>
     <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
+    <uses-permission android:name="android.permission.MANAGE_GAME_ACTIVITY" />
+    <uses-permission android:name="android.permission.SET_ALWAYS_FINISH" />
 
     <!-- needed by MasterClearReceiverTest to display a system dialog -->
     <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/>
@@ -39,6 +41,8 @@
     <application android:testOnly="true"
                  android:debuggable="true">
         <uses-library android:name="android.test.runner" />
+        <activity
+            android:name="android.service.games.GameSessionTrampolineActivityTest$TestActivity" />
     </application>
 
     <instrumentation
diff --git a/services/tests/mockingservicestests/src/android/service/games/GameSessionTrampolineActivityTest.java b/services/tests/mockingservicestests/src/android/service/games/GameSessionTrampolineActivityTest.java
new file mode 100644
index 0000000..d68b517
--- /dev/null
+++ b/services/tests/mockingservicestests/src/android/service/games/GameSessionTrampolineActivityTest.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.games;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isClickable;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.ext.truth.content.IntentSubject.assertThat;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.hamcrest.Matchers.allOf;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.testing.AndroidTestingRunner;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.test.espresso.NoActivityResumedException;
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.infra.AndroidFuture;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Unit tests for the {@link GameSessionTrampolineActivity}.
+ */
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+@Presubmit
+public class GameSessionTrampolineActivityTest {
+
+    @Before
+    public void setUp() {
+        setAlwaysFinishActivities(false);
+    }
+
+    @After
+    public void tearDown() {
+        setAlwaysFinishActivities(false);
+    }
+
+    @Test
+    public void launch_launchesTargetActivity() {
+        AndroidFuture<GameSessionActivityResult> unusedResultFuture =
+                startTestActivityViaGameSessionTrampolineActivity();
+
+        TestActivityPage.assertPageIsLaunched();
+    }
+
+    @Test
+    public void launch_targetActivityFinishesSuccessfully_futureCompletedWithSameResults() {
+        AndroidFuture<GameSessionActivityResult> resultFuture =
+                startTestActivityViaGameSessionTrampolineActivity();
+
+        TestActivityPage.assertPageIsLaunched();
+        TestActivityPage.clickFinish();
+
+        GameSessionActivityResult expectedResult =
+                new GameSessionActivityResult(Activity.RESULT_OK, TestActivity.RESULT_INTENT);
+
+        assertEquals(resultFuture, expectedResult);
+
+        TestActivityPage.assertPageIsNotLaunched();
+    }
+
+    @Test
+    public void launch_trampolineActivityProcessDeath_futureCompletedWithSameResults() {
+        setAlwaysFinishActivities(true);
+
+        AndroidFuture<GameSessionActivityResult> resultFuture =
+                startTestActivityViaGameSessionTrampolineActivity();
+
+        TestActivityPage.assertPageIsLaunched();
+        TestActivityPage.clickFinish();
+
+        GameSessionActivityResult expectedResult =
+                new GameSessionActivityResult(Activity.RESULT_OK, TestActivity.RESULT_INTENT);
+
+        assertEquals(resultFuture, expectedResult);
+
+        TestActivityPage.assertPageIsNotLaunched();
+    }
+
+    private static void assertEquals(
+            AndroidFuture<GameSessionActivityResult> actualFuture,
+            GameSessionActivityResult expected) {
+        try {
+            assertEquals(actualFuture.get(20, TimeUnit.SECONDS), expected);
+        } catch (Exception ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    private static void assertEquals(
+            GameSessionActivityResult actual,
+            GameSessionActivityResult expected) {
+        assertThat(actual.getResultCode()).isEqualTo(expected.getResultCode());
+        assertThat(actual.getData()).filtersEquallyTo(actual.getData());
+    }
+
+    private static void setAlwaysFinishActivities(boolean isEnabled) {
+        try {
+            ActivityManager.getService().setAlwaysFinish(isEnabled);
+        } catch (RemoteException ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    private static AndroidFuture<GameSessionActivityResult>
+            startTestActivityViaGameSessionTrampolineActivity() {
+        Intent testActivityIntent = new Intent();
+        testActivityIntent.setClass(getInstrumentation().getTargetContext(), TestActivity.class);
+
+        return startGameSessionTrampolineActivity(testActivityIntent);
+    }
+
+    private static AndroidFuture<GameSessionActivityResult> startGameSessionTrampolineActivity(
+            Intent targetIntent) {
+        AndroidFuture<GameSessionActivityResult> resultFuture = new AndroidFuture<>();
+        Intent trampolineActivityIntent = GameSessionTrampolineActivity.createIntent(targetIntent,
+                null, resultFuture);
+        trampolineActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        getInstrumentation().getTargetContext().startActivity(trampolineActivityIntent);
+        getInstrumentation().waitForIdleSync();
+
+        return resultFuture;
+    }
+
+
+    private static class TestActivityPage {
+        private TestActivityPage() {}
+
+        public static void assertPageIsLaunched() {
+            onView(withText(TestActivity.PAGE_TITLE_TEXT)).check(matches(isDisplayed()));
+        }
+
+        public static void assertPageIsNotLaunched() {
+            try {
+                onView(withText(TestActivity.PAGE_TITLE_TEXT)).check(doesNotExist());
+            } catch (NoActivityResumedException ex) {
+                // Do nothing
+            }
+        }
+
+        public static void clickFinish() {
+            onView(allOf(withText(TestActivity.FINISH_BUTTON_TEXT), isClickable())).perform(
+                    click());
+            getInstrumentation().waitForIdleSync();
+        }
+    }
+
+    public static class TestActivity extends Activity {
+        private static final String PAGE_TITLE_TEXT = "GameSessionTestActivity";
+        private static final String FINISH_BUTTON_TEXT = "Finish Test Activity";
+        private static final Intent RESULT_INTENT = new Intent("com.test.action.VIEW");
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            LinearLayout contentLayout = new LinearLayout(this);
+            contentLayout.setOrientation(LinearLayout.VERTICAL);
+
+            TextView titleTextView = new TextView(this);
+            titleTextView.setText(PAGE_TITLE_TEXT);
+            contentLayout.addView(titleTextView);
+
+            Button finishActivityButton = new Button(this);
+            finishActivityButton.setText(FINISH_BUTTON_TEXT);
+            finishActivityButton.setOnClickListener((unused) -> {
+                setResult(Activity.RESULT_OK, RESULT_INTENT);
+                finish();
+            });
+
+
+            contentLayout.addView(finishActivityButton);
+            setContentView(contentLayout);
+        }
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
index 319a769..5b551b1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
@@ -216,11 +216,12 @@
                 mRunningTaskInfos);
 
 
+        final UserHandle userHandle = new UserHandle(USER_ID);
         mGameServiceProviderInstance = new GameServiceProviderInstanceImpl(
-                new UserHandle(USER_ID),
+                userHandle,
                 ConcurrentUtils.DIRECT_EXECUTOR,
                 mMockContext,
-                mFakeGameClassifier,
+                new GameTaskInfoProvider(userHandle, mMockActivityTaskManager, mFakeGameClassifier),
                 mMockActivityManager,
                 mMockActivityManagerInternal,
                 mMockActivityTaskManager,
@@ -788,6 +789,36 @@
     }
 
     @Test
+    public void gameTaskFocusedWithCreateAfterRemoved_gameSessionRecreated() throws Exception {
+        mGameServiceProviderInstance.start();
+
+        startTask(10, GAME_A_MAIN_ACTIVITY);
+        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
+        mFakeGameService.requestCreateGameSession(10);
+
+        FakeGameSession gameSession10 = new FakeGameSession();
+        SurfacePackage mockSurfacePackage10 = Mockito.mock(SurfacePackage.class);
+        mFakeGameSessionService.removePendingFutureForTaskId(10)
+                .complete(new CreateGameSessionResult(gameSession10, mockSurfacePackage10));
+
+        stopTask(10);
+
+        assertThat(gameSession10.mIsDestroyed).isTrue();
+
+        // If the game task is restored via the Recents UI, the task will be running again but
+        // we would not expect any call to TaskStackListener#onTaskCreated.
+        addRunningTaskInfo(10, GAME_A_MAIN_ACTIVITY);
+
+        // We now receive a task focused event for the task. This will occur if the game task is
+        // restored via the Recents UI.
+        dispatchTaskFocused(10, /*focused=*/ true);
+        mFakeGameService.requestCreateGameSession(10);
+
+        // Verify that a new pending game session is created for the game's taskId.
+        assertNotNull(mFakeGameSessionService.removePendingFutureForTaskId(10));
+    }
+
+    @Test
     public void gameTaskRemoved_removesTaskOverlay() throws Exception {
         mGameServiceProviderInstance.start();
 
@@ -1144,13 +1175,18 @@
     }
 
     private void startTask(int taskId, ComponentName componentName) {
+        addRunningTaskInfo(taskId, componentName);
+
+        dispatchTaskCreated(taskId, componentName);
+    }
+
+    private void addRunningTaskInfo(int taskId, ComponentName componentName) {
         RunningTaskInfo runningTaskInfo = new RunningTaskInfo();
         runningTaskInfo.taskId = taskId;
+        runningTaskInfo.baseActivity = componentName;
         runningTaskInfo.displayId = 1;
         runningTaskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 0, 500, 800));
         mRunningTaskInfos.add(runningTaskInfo);
-
-        dispatchTaskCreated(taskId, componentName);
     }
 
     private void stopTask(int taskId) {
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 353c8e2..55745cd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -69,6 +69,7 @@
 import com.android.server.pm.pkg.parsing.ParsingPackage
 import com.android.server.pm.pkg.parsing.ParsingPackageUtils
 import com.android.server.pm.resolution.ComponentResolver
+import com.android.server.pm.snapshot.PackageDataSnapshot
 import com.android.server.pm.verify.domain.DomainVerificationManagerInternal
 import com.android.server.sdksandbox.SdkSandboxManagerLocal
 import com.android.server.testutils.TestHandler
@@ -329,7 +330,7 @@
         }
         whenever(mocks.injector.sharedLibrariesImpl) { mSharedLibraries }
         // everything visible by default
-        whenever(mocks.appsFilter.shouldFilterApplication(
+        whenever(mocks.appsFilter.shouldFilterApplication(any(PackageDataSnapshot::class.java),
                 anyInt(), nullable(), nullable(), anyInt())) { false }
 
         val displayManager: DisplayManager = mock()
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
index 3ba9ca5..b9d6b2c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
@@ -23,6 +23,7 @@
 import android.util.ArrayMap
 import android.util.SparseArray
 import com.android.server.pm.pkg.PackageStateInternal
+import com.android.server.pm.snapshot.PackageDataSnapshot
 import com.android.server.testutils.any
 import com.android.server.testutils.eq
 import com.android.server.testutils.nullable
@@ -389,6 +390,7 @@
 
     private fun mockAllowList(pkgSetting: PackageStateInternal, list: SparseArray<IntArray>?) {
         whenever(rule.mocks().appsFilter.getVisibilityAllowList(
+                any(PackageDataSnapshot::class.java),
             argThat { it?.packageName == pkgSetting.packageName }, any(IntArray::class.java),
             any() as ArrayMap<String, out PackageStateInternal>
         ))
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 449177e..0afb182 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -102,6 +102,7 @@
     <uses-permission android:name="android.permission.READ_NEARBY_STREAMING_POLICY" />
     <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING" />
     <uses-permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT" />
+    <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" />
 
     <queries>
         <package android:name="com.android.servicestests.apps.suspendtestapp" />
diff --git a/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java b/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
index 0e84e04..42c4129 100644
--- a/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
@@ -16,6 +16,10 @@
 
 package com.android.server;
 
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.app.job.JobScheduler;
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -43,13 +47,15 @@
 
     @Before
     public void setUp() {
-        mContext = ApplicationProvider.getApplicationContext();
+        mContext = spy(ApplicationProvider.getApplicationContext());
         mBinaryTransparencyService = new BinaryTransparencyService(mContext);
         mTestInterface = mBinaryTransparencyService.new BinaryTransparencyServiceImpl();
     }
 
     private void prepSignedInfo() {
         // simulate what happens on boot completed phase
+        // but we avoid calling JobScheduler.schedule by returning a null.
+        doReturn(null).when(mContext).getSystemService(JobScheduler.class);
         mBinaryTransparencyService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
index 00f4c39..5c91b8b 100644
--- a/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -43,34 +44,52 @@
     @Test
     public void testMultipleProcesses() {
         // The first 5 entries should not be rate limited.
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
         // Different processes and tags should not get rate limited either.
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process2"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag2", "process"));
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process2").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag2", "process").shouldRateLimit());
         // The 6th entry of the same process should be rate limited.
-        assertTrue(mRateLimiter.shouldRateLimit("tag", "process"));
+        assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
     }
 
     @Test
     public void testBufferClearing() throws Exception {
         // The first 5 entries should not be rate limited.
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
         // The 6th entry of the same process should be rate limited.
-        assertTrue(mRateLimiter.shouldRateLimit("tag", "process"));
+        assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
 
         // After 11 seconds there should be nothing left in the buffer and the same type of entry
         // should not get rate limited anymore.
         mClock.setOffsetMillis(11000);
 
-        assertFalse(mRateLimiter.shouldRateLimit("tag", "process"));
+        assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+    }
+
+    @Test
+    public void testRecentlyDroppedCount() throws Exception {
+        assertEquals(0,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(0,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(0,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(0,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(0,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(1,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+        assertEquals(2,
+                mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
     }
 
     private static class TestClock implements DropboxRateLimiter.Clock {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
index f40b31a..abf992b 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
@@ -415,7 +415,7 @@
         // Auth was attempted
         when(mUdfpsClient.getState())
                 .thenReturn(AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED);
-        verify(mCallback, never()).sendHapticFeedback();
+        verify(mCallback).sendHapticFeedback();
         verify(mCallback).handleLifecycleAfterAuth();
 
         // Then face rejected. Note that scheduler leaves UDFPS in the CoexCoordinator since
@@ -425,7 +425,7 @@
                 LockoutTracker.LOCKOUT_NONE, faceCallback);
         verify(faceCallback).sendHapticFeedback();
         verify(faceCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
-        verify(mCallback, never()).sendHapticFeedback();
+        verify(mCallback).sendHapticFeedback();
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
index aba93b0..f08d0ef6 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
@@ -18,6 +18,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.inOrder;
@@ -26,8 +27,13 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.content.ComponentName;
+import android.hardware.biometrics.common.ICancellationSignal;
 import android.hardware.biometrics.common.OperationContext;
 import android.hardware.biometrics.face.ISession;
+import android.hardware.face.Face;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
@@ -53,6 +59,9 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @Presubmit
 @SmallTest
 public class FaceAuthenticationClientTest {
@@ -82,6 +91,10 @@
     private ClientMonitorCallback mCallback;
     @Mock
     private Sensor.HalSessionCallback mHalSessionCallback;
+    @Mock
+    private ActivityTaskManager mActivityTaskManager;
+    @Mock
+    private ICancellationSignal mCancellationSignal;
     @Captor
     private ArgumentCaptor<OperationContext> mOperationContextCaptor;
 
@@ -116,6 +129,25 @@
         verify(mHal, never()).authenticate(anyLong());
     }
 
+    @Test
+    public void cancelsAuthWhenNotInForeground() throws Exception {
+        final ActivityManager.RunningTaskInfo topTask = new ActivityManager.RunningTaskInfo();
+        topTask.topActivity = new ComponentName("other", "thing");
+        when(mActivityTaskManager.getTasks(anyInt())).thenReturn(List.of(topTask));
+        when(mHal.authenticateWithContext(anyLong(), any())).thenReturn(mCancellationSignal);
+
+        final FaceAuthenticationClient client = createClient();
+        client.start(mCallback);
+        client.onAuthenticated(new Face("friendly", 1 /* faceId */, 2 /* deviceId */),
+                true /* authenticated */, new ArrayList<>());
+
+        verify(mCancellationSignal).cancel();
+    }
+
+    private FaceAuthenticationClient createClient() throws RemoteException {
+        return createClient(2 /* version */);
+    }
+
     private FaceAuthenticationClient createClient(int version) throws RemoteException {
         when(mHal.getInterfaceVersion()).thenReturn(version);
 
@@ -126,6 +158,11 @@
                 false /* requireConfirmation */, 9 /* sensorId */,
                 mBiometricLogger, mBiometricContext, true /* isStrongBiometric */,
                 mUsageStats, mLockoutCache, false /* allowBackgroundAuthentication */,
-                false /* isKeyguardBypassEnabled */, null /* sensorPrivacyManager */);
+                false /* isKeyguardBypassEnabled */, null /* sensorPrivacyManager */) {
+            @Override
+            protected ActivityTaskManager getActivityTaskManager() {
+                return mActivityTaskManager;
+            }
+        };
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
index 7463022..1a49f8a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
@@ -31,7 +31,11 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.content.ComponentName;
 import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.common.ICancellationSignal;
 import android.hardware.biometrics.common.OperationContext;
 import android.hardware.biometrics.fingerprint.ISession;
 import android.hardware.biometrics.fingerprint.PointerContext;
@@ -66,6 +70,7 @@
 import org.mockito.junit.MockitoRule;
 
 import java.util.ArrayList;
+import java.util.List;
 import java.util.function.Consumer;
 
 @Presubmit
@@ -111,6 +116,10 @@
     @Mock
     private Sensor.HalSessionCallback mHalSessionCallback;
     @Mock
+    private ActivityTaskManager mActivityTaskManager;
+    @Mock
+    private ICancellationSignal mCancellationSignal;
+    @Mock
     private Probe mLuxProbe;
     @Captor
     private ArgumentCaptor<OperationContext> mOperationContextCaptor;
@@ -288,11 +297,36 @@
         verify(mSideFpsController).hide(anyInt());
     }
 
+    @Test
+    public void cancelsAuthWhenNotInForeground() throws Exception {
+        final ActivityManager.RunningTaskInfo topTask = new ActivityManager.RunningTaskInfo();
+        topTask.topActivity = new ComponentName("other", "thing");
+        when(mActivityTaskManager.getTasks(anyInt())).thenReturn(List.of(topTask));
+        when(mHal.authenticateWithContext(anyLong(), any())).thenReturn(mCancellationSignal);
+
+        final FingerprintAuthenticationClient client = createClientWithoutBackgroundAuth();
+        client.start(mCallback);
+        client.onAuthenticated(new Fingerprint("friendly", 1 /* fingerId */, 2 /* deviceId */),
+                true /* authenticated */, new ArrayList<>());
+
+        verify(mCancellationSignal).cancel();
+    }
+
     private FingerprintAuthenticationClient createClient() throws RemoteException {
-        return createClient(100);
+        return createClient(100 /* version */, true /* allowBackgroundAuthentication */);
+    }
+
+    private FingerprintAuthenticationClient createClientWithoutBackgroundAuth()
+            throws RemoteException {
+        return createClient(100 /* version */, false /* allowBackgroundAuthentication */);
     }
 
     private FingerprintAuthenticationClient createClient(int version) throws RemoteException {
+        return createClient(version, true /* allowBackgroundAuthentication */);
+    }
+
+    private FingerprintAuthenticationClient createClient(int version,
+            boolean allowBackgroundAuthentication) throws RemoteException {
         when(mHal.getInterfaceVersion()).thenReturn(version);
 
         final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
@@ -302,7 +336,11 @@
         9 /* sensorId */, mBiometricLogger, mBiometricContext,
         true /* isStrongBiometric */,
         null /* taskStackListener */, mLockoutCache,
-        mUdfpsOverlayController, mSideFpsController,
-        true /* allowBackgroundAuthentication */, mSensorProps);
+        mUdfpsOverlayController, mSideFpsController, allowBackgroundAuthentication, mSensorProps) {
+            @Override
+            protected ActivityTaskManager getActivityTaskManager() {
+                return mActivityTaskManager;
+            }
+        };
     }
 }
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 45d101a..545361c 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -4992,8 +4992,8 @@
                 .thenReturn(12345 /* some UID in user 0 */);
         // Make personal apps look suspended
         dpms.getUserData(UserHandle.USER_SYSTEM).mAppsSuspended = true;
-
-        clearInvocations(getServices().iwindowManager);
+        // Screen capture
+        dpm.setScreenCaptureDisabled(admin1, true);
 
         dpm.wipeData(0);
         verify(getServices().userManagerInternal).removeUserEvenWhenDisallowed(CALLER_USER_HANDLE);
@@ -5004,6 +5004,8 @@
         verify(getServices().userManager).setUserRestriction(
                 UserManager.DISALLOW_ADD_USER, false, UserHandle.SYSTEM);
 
+        clearInvocations(getServices().iwindowManager);
+
         // Some device-wide policies are getting cleaned-up after the user is removed.
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
         sendBroadcastWithUser(dpms, Intent.ACTION_USER_REMOVED, CALLER_USER_HANDLE);
@@ -5020,9 +5022,10 @@
                 MockUtils.checkIntentAction(
                         DevicePolicyManager.ACTION_RESET_PROTECTION_POLICY_CHANGED),
                 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
-        // Refresh strong auth timeout and screen capture
+        // Refresh strong auth timeout
         verify(getServices().lockSettingsInternal).refreshStrongAuthTimeout(UserHandle.USER_SYSTEM);
-        verify(getServices().iwindowManager).refreshScreenCaptureDisabled(UserHandle.USER_SYSTEM);
+        // Refresh screen capture
+        verify(getServices().iwindowManager).refreshScreenCaptureDisabled();
         // Unsuspend personal apps
         verify(getServices().packageManagerInternal)
                 .unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, UserHandle.USER_SYSTEM);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index 2cf67f8..e991ec6 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -237,6 +237,8 @@
                 return mMockSystemServices.devicePolicyManager;
             case Context.LOCATION_SERVICE:
                 return mMockSystemServices.locationManager;
+            case Context.ROLE_SERVICE:
+                return mMockSystemServices.roleManager;
         }
         throw new UnsupportedOperationException();
     }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index 34c9f7c..884ffce 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -33,6 +33,7 @@
 import android.app.NotificationManager;
 import android.app.admin.DevicePolicyManager;
 import android.app.backup.IBackupManager;
+import android.app.role.RoleManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -131,6 +132,7 @@
     public final VpnManager vpnManager;
     public final DevicePolicyManager devicePolicyManager;
     public final LocationManager locationManager;
+    public final RoleManager roleManager;
     /** Note this is a partial mock, not a real mock. */
     public final PackageManager packageManager;
     public final BuildMock buildMock = new BuildMock();
@@ -181,6 +183,7 @@
         vpnManager = mock(VpnManager.class);
         devicePolicyManager = mock(DevicePolicyManager.class);
         locationManager = mock(LocationManager.class);
+        roleManager = realContext.getSystemService(RoleManager.class);
 
         // Package manager is huge, so we use a partial mock instead.
         packageManager = spy(realContext.getPackageManager());
diff --git a/services/tests/servicestests/src/com/android/server/display/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/display/TEST_MAPPING
new file mode 100644
index 0000000..9f1a209
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/TEST_MAPPING
@@ -0,0 +1,21 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.display."
+        },
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ]
+    }
+  ]
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
index 3be2aac..c43e6ab 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
@@ -30,6 +30,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
 import android.content.pm.SigningDetails;
 import android.content.pm.UserInfo;
@@ -53,6 +54,7 @@
 import com.android.server.pm.pkg.component.ParsedIntentInfoImpl;
 import com.android.server.pm.pkg.component.ParsedProviderImpl;
 import com.android.server.pm.pkg.parsing.ParsingPackage;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
 import com.android.server.utils.WatchableTester;
 
 import org.junit.Before;
@@ -99,9 +101,11 @@
     @Mock
     AppsFilterImpl.FeatureConfig mFeatureConfigMock;
     @Mock
-    AppsFilterImpl.StateProvider mStateProvider;
+    PackageDataSnapshot mSnapshot;
     @Mock
     Executor mMockExecutor;
+    @Mock
+    PackageManagerInternal mPmInternal;
 
     private ArrayMap<String, PackageSetting> mExisting = new ArrayMap<>();
     private Collection<SharedUserSetting> mSharedUserSettings = new ArraySet<>();
@@ -201,12 +205,10 @@
         mExisting = new ArrayMap<>();
 
         MockitoAnnotations.initMocks(this);
-        doAnswer(invocation -> {
-            ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0))
-                    .currentState(mExisting, mSharedUserSettings, USER_INFO_LIST);
-            return new Object();
-        }).when(mStateProvider)
-                .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class));
+        when(mSnapshot.getPackageStates()).thenAnswer(x -> mExisting);
+        when(mSnapshot.getAllSharedUsers()).thenReturn(mSharedUserSettings);
+        when(mSnapshot.getUserInfos()).thenReturn(USER_INFO_LIST);
+        when(mPmInternal.snapshot()).thenReturn(mSnapshot);
 
         doAnswer(invocation -> {
             ((Runnable) invocation.getArgument(0)).run();
@@ -223,11 +225,11 @@
     @Test
     public void testSystemReadyPropogates() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
         watcher.verifyChangeReported("systemReady");
         verify(mFeatureConfigMock).onSystemReady();
     }
@@ -235,13 +237,13 @@
     @Test
     public void testQueriesAction_FilterMatches() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
         watcher.verifyChangeReported("addBasicAndroid");
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
         watcher.verifyChangeReported("systemReady");
 
         PackageSetting target = simulateAddPackage(appsFilter,
@@ -251,14 +253,16 @@
                 pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
         watcher.verifyChangeReported("add package");
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
         watcher.verifyNoChangeReported("shouldFilterAplication");
     }
+
     @Test
     public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
@@ -271,7 +275,7 @@
         simulateAddPackage(appsFilter, android, 1000,
                 b -> b.setSigningDetails(frameworkSigningDetails));
         watcher.verifyChangeReported("addPackage");
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
         watcher.verifyChangeReported("systemReady");
 
         final int activityUid = DUMMY_TARGET_APPID;
@@ -292,14 +296,14 @@
                 pkg("com.calling.wildcard", new Intent("*")), wildcardUid);
         watcher.verifyChangeReported("addPackage");
 
-        assertFalse(appsFilter.shouldFilterApplication(callingUid, calling, targetActivity,
-                SYSTEM_USER));
-        assertTrue(appsFilter.shouldFilterApplication(callingUid, calling, targetReceiver,
-                SYSTEM_USER));
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot, callingUid, calling,
+                targetActivity, SYSTEM_USER));
+        assertTrue(appsFilter.shouldFilterApplication(mSnapshot, callingUid, calling,
+                targetReceiver, SYSTEM_USER));
 
-        assertFalse(appsFilter.shouldFilterApplication(
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot,
                 wildcardUid, callingWildCard, targetActivity, SYSTEM_USER));
-        assertTrue(appsFilter.shouldFilterApplication(
+        assertTrue(appsFilter.shouldFilterApplication(mSnapshot,
                 wildcardUid, callingWildCard, targetReceiver, SYSTEM_USER));
         watcher.verifyNoChangeReported("shouldFilterApplication");
     }
@@ -307,13 +311,13 @@
     @Test
     public void testQueriesProvider_FilterMatches() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
         watcher.verifyChangeReported("addPackage");
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
         watcher.verifyChangeReported("systemReady");
 
         PackageSetting target = simulateAddPackage(appsFilter,
@@ -324,19 +328,19 @@
                 DUMMY_CALLING_APPID);
         watcher.verifyChangeReported("addPackage");
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling,
+                target, SYSTEM_USER));
         watcher.verifyNoChangeReported("shouldFilterApplication");
     }
 
     @Test
     public void testOnUserUpdated_FilterMatches() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
 
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_APPID);
@@ -346,41 +350,31 @@
 
         for (int subjectUserId : USER_ARRAY) {
             for (int otherUserId : USER_ARRAY) {
-                assertFalse(appsFilter.shouldFilterApplication(
+                assertFalse(appsFilter.shouldFilterApplication(mSnapshot,
                         UserHandle.getUid(DUMMY_CALLING_APPID, subjectUserId), calling, target,
                         otherUserId));
             }
         }
 
         // adds new user
-        doAnswer(invocation -> {
-            ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0))
-                    .currentState(mExisting, mSharedUserSettings, USER_INFO_LIST_WITH_ADDED);
-            return new Object();
-        }).when(mStateProvider)
-                .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class));
-        appsFilter.onUserCreated(ADDED_USER);
+        when(mSnapshot.getUserInfos()).thenReturn(USER_INFO_LIST_WITH_ADDED);
+        appsFilter.onUserCreated(mSnapshot, ADDED_USER);
 
         for (int subjectUserId : USER_ARRAY_WITH_ADDED) {
             for (int otherUserId : USER_ARRAY_WITH_ADDED) {
-                assertFalse(appsFilter.shouldFilterApplication(
+                assertFalse(appsFilter.shouldFilterApplication(mSnapshot,
                         UserHandle.getUid(DUMMY_CALLING_APPID, subjectUserId), calling, target,
                         otherUserId));
             }
         }
 
         // delete user
-        doAnswer(invocation -> {
-            ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0))
-                    .currentState(mExisting, mSharedUserSettings, USER_INFO_LIST);
-            return new Object();
-        }).when(mStateProvider)
-                .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class));
+        when(mSnapshot.getUserInfos()).thenReturn(USER_INFO_LIST);
         appsFilter.onUserDeleted(ADDED_USER);
 
         for (int subjectUserId : USER_ARRAY) {
             for (int otherUserId : USER_ARRAY) {
-                assertFalse(appsFilter.shouldFilterApplication(
+                assertFalse(appsFilter.shouldFilterApplication(mSnapshot,
                         UserHandle.getUid(DUMMY_CALLING_APPID, subjectUserId), calling, target,
                         otherUserId));
             }
@@ -390,13 +384,13 @@
     @Test
     public void testQueriesDifferentProvider_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
         watcher.verifyChangeReported("addPackage");
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
         watcher.verifyChangeReported("systemReady");
 
         PackageSetting target = simulateAddPackage(appsFilter,
@@ -407,18 +401,18 @@
                 DUMMY_CALLING_APPID);
         watcher.verifyChangeReported("addPackage");
 
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling,
+                target, SYSTEM_USER));
         watcher.verifyNoChangeReported("shouldFilterApplication");
     }
 
     @Test
     public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkgWithProvider("com.some.package", "com.some.authority;com.some.other.authority"),
@@ -427,34 +421,34 @@
                 pkgQueriesProvider("com.some.other.package", "com.some.authority"),
                 DUMMY_CALLING_APPID);
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling,
+                target, SYSTEM_USER));
     }
 
     @Test
     public void testQueriesAction_NoMatchingAction_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package"), DUMMY_TARGET_APPID);
         PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
 
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling,
+                target, SYSTEM_USER));
     }
 
     @Test
     public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package"), DUMMY_TARGET_APPID);
@@ -465,35 +459,37 @@
                 DUMMY_CALLING_APPID);
 
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testNoQueries_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package"), DUMMY_TARGET_APPID);
         PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package"), DUMMY_CALLING_APPID);
 
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertTrue(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testNoUsesLibrary_Filters() throws Exception {
-        final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
+        final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
                 new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
                 mMockExecutor);
 
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         final Signature mockSignature = Mockito.mock(Signature.class);
         final SigningDetails mockSigningDetails = new SigningDetails(
@@ -508,18 +504,19 @@
         final PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package"), DUMMY_CALLING_APPID);
 
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertTrue(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testUsesLibrary_DoesntFilter() throws Exception {
-        final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
+        final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
                 new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
                 mMockExecutor);
 
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         final Signature mockSignature = Mockito.mock(Signature.class);
         final SigningDetails mockSigningDetails = new SigningDetails(
@@ -535,18 +532,19 @@
                 pkg("com.some.other.package").addUsesLibrary("com.some.shared_library"),
                 DUMMY_CALLING_APPID);
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testUsesOptionalLibrary_DoesntFilter() throws Exception {
-        final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
+        final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
                 new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
                 mMockExecutor);
 
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         final Signature mockSignature = Mockito.mock(Signature.class);
         final SigningDetails mockSigningDetails = new SigningDetails(
@@ -562,18 +560,19 @@
                 pkg("com.some.other.package").addUsesOptionalLibrary("com.some.shared_library"),
                 DUMMY_CALLING_APPID);
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testUsesLibrary_ShareUid_DoesntFilter() throws Exception {
-        final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
+        final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
                 new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
                 mMockExecutor);
 
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         final Signature mockSignature = Mockito.mock(Signature.class);
         final SigningDetails mockSigningDetails = new SigningDetails(
@@ -589,22 +588,23 @@
                 pkg("com.some.other.package_a").setSharedUserId("com.some.uid"),
                 DUMMY_CALLING_APPID);
         simulateAddPackage(appsFilter, pkg("com.some.other.package_b")
-                .setSharedUserId("com.some.uid").addUsesLibrary("com.some.shared_library"),
+                        .setSharedUserId("com.some.uid").addUsesLibrary("com.some.shared_library"),
                 DUMMY_CALLING_APPID);
 
         // Although package_a doesn't use library, it should be granted visibility. It's because
         // package_a shares userId with package_b, and package_b uses that shared library.
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testForceQueryable_SystemDoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID,
@@ -612,36 +612,38 @@
         PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package"), DUMMY_CALLING_APPID);
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
 
     @Test
     public void testForceQueryable_NonSystemFilters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID);
         PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package"), DUMMY_CALLING_APPID);
 
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertTrue(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
+                new AppsFilterImpl(mFeatureConfigMock,
                         new String[]{"com.some.package"}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package"), DUMMY_TARGET_APPID,
@@ -649,17 +651,18 @@
         PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package"), DUMMY_CALLING_APPID);
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
 
     @Test
     public void testSystemSignedTarget_DoesntFilter() throws CertificateException {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         final Signature frameworkSignature = Mockito.mock(Signature.class);
         final SigningDetails frameworkSigningDetails =
@@ -679,36 +682,38 @@
                 pkg("com.some.other.package"), DUMMY_CALLING_APPID,
                 b -> b.setSigningDetails(otherSigningDetails));
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock,
+                new AppsFilterImpl(mFeatureConfigMock,
                         new String[]{"com.some.package"}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package"), DUMMY_TARGET_APPID);
         PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package"), DUMMY_CALLING_APPID);
 
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertTrue(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
 
     @Test
     public void testSystemQueryable_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{},
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{},
                         true /* system force queryable */, null, mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package"), DUMMY_TARGET_APPID,
@@ -716,25 +721,27 @@
         PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package"), DUMMY_CALLING_APPID);
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testQueriesPackage_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package"), DUMMY_TARGET_APPID);
         PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package", "com.some.package"), DUMMY_CALLING_APPID);
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
@@ -742,49 +749,52 @@
         when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
                 .thenReturn(false);
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(
                 appsFilter, pkg("com.some.package"), DUMMY_TARGET_APPID);
         PackageSetting calling = simulateAddPackage(
                 appsFilter, pkg("com.some.other.package"), DUMMY_CALLING_APPID);
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testSystemUid_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package"), DUMMY_TARGET_APPID);
 
-        assertFalse(appsFilter.shouldFilterApplication(SYSTEM_USER, null, target, SYSTEM_USER));
-        assertFalse(appsFilter.shouldFilterApplication(Process.FIRST_APPLICATION_UID - 1,
-                null, target, SYSTEM_USER));
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot, SYSTEM_USER, null, target,
+                SYSTEM_USER));
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot,
+                Process.FIRST_APPLICATION_UID - 1, null, target, SYSTEM_USER));
     }
 
     @Test
     public void testSystemUidSecondaryUser_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package"), DUMMY_TARGET_APPID);
 
-        assertFalse(appsFilter.shouldFilterApplication(0, null, target, SECONDARY_USER));
-        assertFalse(appsFilter.shouldFilterApplication(
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot, 0, null, target,
+                SECONDARY_USER));
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot,
                 UserHandle.getUid(SECONDARY_USER, Process.FIRST_APPLICATION_UID - 1),
                 null, target, SECONDARY_USER));
     }
@@ -792,25 +802,25 @@
     @Test
     public void testNonSystemUid_NoCallingSetting_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter,
                 pkg("com.some.package"), DUMMY_TARGET_APPID);
 
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, null, target,
+        assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, null, target,
                 SYSTEM_USER));
     }
 
     @Test
     public void testNoTargetPackage_filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = new PackageSettingBuilder()
                 .setAppId(DUMMY_TARGET_APPID)
@@ -821,8 +831,9 @@
         PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
 
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertTrue(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
@@ -838,7 +849,6 @@
         ParsingPackage actor = pkg("com.some.package.actor");
 
         final AppsFilterImpl appsFilter = new AppsFilterImpl(
-                mStateProvider,
                 mFeatureConfigMock,
                 new String[]{},
                 false,
@@ -868,7 +878,7 @@
                 },
                 mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         // Packages must be added in actor -> overlay -> target order so that the implicit
         // visibility of the actor into the overlay can be tested
@@ -878,33 +888,33 @@
                 simulateAddPackage(appsFilter, overlay, DUMMY_OVERLAY_APPID);
 
         // Actor can not see overlay (yet)
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting,
+        assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_ACTOR_APPID, actorSetting,
                 overlaySetting, SYSTEM_USER));
 
         PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_APPID);
 
         // Actor can see both target and overlay
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting,
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_ACTOR_APPID, actorSetting,
                 targetSetting, SYSTEM_USER));
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting,
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_ACTOR_APPID, actorSetting,
                 overlaySetting, SYSTEM_USER));
 
         // But target/overlay can't see each other
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, targetSetting,
+        assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_TARGET_APPID, targetSetting,
                 overlaySetting, SYSTEM_USER));
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_APPID, overlaySetting,
-                targetSetting, SYSTEM_USER));
+        assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_OVERLAY_APPID,
+                overlaySetting, targetSetting, SYSTEM_USER));
 
         // And can't see the actor
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, targetSetting,
+        assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_TARGET_APPID, targetSetting,
                 actorSetting, SYSTEM_USER));
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_APPID, overlaySetting,
-                actorSetting, SYSTEM_USER));
+        assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_OVERLAY_APPID,
+                overlaySetting, actorSetting, SYSTEM_USER));
 
-        appsFilter.removePackage(targetSetting, false /* isReplace */);
+        appsFilter.removePackage(mSnapshot, targetSetting, false /* isReplace */);
 
         // Actor loses visibility to the overlay via removal of the target
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting,
+        assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_ACTOR_APPID, actorSetting,
                 overlaySetting, SYSTEM_USER));
     }
 
@@ -928,7 +938,6 @@
                 null /*settingBuilder*/);
 
         final AppsFilterImpl appsFilter = new AppsFilterImpl(
-                mStateProvider,
                 mFeatureConfigMock,
                 new String[]{},
                 false,
@@ -959,7 +968,7 @@
                 },
                 mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_APPID);
         SharedUserSetting actorSharedSetting = new SharedUserSetting("actorSharedUser",
@@ -971,19 +980,19 @@
         simulateAddPackage(ps2, appsFilter, actorSharedSetting);
 
         // actorTwo can see both target and overlay
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSharedSetting,
-                targetSetting, SYSTEM_USER));
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSharedSetting,
-                overlaySetting, SYSTEM_USER));
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_ACTOR_APPID,
+                actorSharedSetting, targetSetting, SYSTEM_USER));
+        assertFalse(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_ACTOR_APPID,
+                actorSharedSetting, overlaySetting, SYSTEM_USER));
     }
 
     @Test
     public void testInitiatingApp_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
                 DUMMY_TARGET_APPID);
@@ -991,17 +1000,18 @@
                 DUMMY_CALLING_APPID,
                 withInstallSource(target.getPackageName(), null, null, null, false));
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testUninstalledInitiatingApp_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
                 DUMMY_TARGET_APPID);
@@ -1009,20 +1019,21 @@
                 DUMMY_CALLING_APPID,
                 withInstallSource(target.getPackageName(), null, null, null, true));
 
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertTrue(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
     }
 
     @Test
     public void testOriginatingApp_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
         watcher.verifyChangeReported("addBasicAndroid");
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
         watcher.verifyChangeReported("systemReady");
 
         PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
@@ -1033,21 +1044,22 @@
                         false));
         watcher.verifyChangeReported("add package");
 
-        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertTrue(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
         watcher.verifyNoChangeReported("shouldFilterAplication");
     }
 
     @Test
     public void testInstallingApp_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
         watcher.verifyChangeReported("addBasicAndroid");
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
         watcher.verifyChangeReported("systemReady");
 
         PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
@@ -1058,21 +1070,22 @@
                         false));
         watcher.verifyChangeReported("add package");
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
-                SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
         watcher.verifyNoChangeReported("shouldFilterAplication");
     }
 
     @Test
     public void testInstrumentation_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
         watcher.verifyChangeReported("addBasicAndroid");
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
         watcher.verifyChangeReported("systemReady");
 
         PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
@@ -1084,24 +1097,24 @@
         watcher.verifyChangeReported("add package");
 
         assertFalse(
-                appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target,
-                        SYSTEM_USER));
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, instrumentation,
+                        target, SYSTEM_USER));
         assertFalse(
-                appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, target, instrumentation,
-                        SYSTEM_USER));
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_TARGET_APPID, target,
+                        instrumentation, SYSTEM_USER));
         watcher.verifyNoChangeReported("shouldFilterAplication");
     }
 
     @Test
     public void testWhoCanSee() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
         watcher.verifyChangeReported("addBasicAndroid");
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
         watcher.verifyChangeReported("systemReady");
 
         final int systemAppId = Process.FIRST_APPLICATION_UID - 1;
@@ -1123,14 +1136,14 @@
         watcher.verifyChangeReported("add package");
 
         final SparseArray<int[]> systemFilter =
-                appsFilter.getVisibilityAllowList(system, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(mSnapshot, system, USER_ARRAY, mExisting);
         watcher.verifyNoChangeReported("getVisibility");
         assertThat(toList(systemFilter.get(SYSTEM_USER)),
                 contains(seesNothingAppId, hasProviderAppId, queriesProviderAppId));
         watcher.verifyNoChangeReported("getVisibility");
 
         final SparseArray<int[]> seesNothingFilter =
-                appsFilter.getVisibilityAllowList(seesNothing, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(mSnapshot, seesNothing, USER_ARRAY, mExisting);
         watcher.verifyNoChangeReported("getVisibility");
         assertThat(toList(seesNothingFilter.get(SYSTEM_USER)),
                 contains(seesNothingAppId));
@@ -1140,12 +1153,13 @@
         watcher.verifyNoChangeReported("getVisibility");
 
         final SparseArray<int[]> hasProviderFilter =
-                appsFilter.getVisibilityAllowList(hasProvider, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(mSnapshot, hasProvider, USER_ARRAY, mExisting);
         assertThat(toList(hasProviderFilter.get(SYSTEM_USER)),
                 contains(hasProviderAppId, queriesProviderAppId));
 
         SparseArray<int[]> queriesProviderFilter =
-                appsFilter.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(mSnapshot, queriesProvider, USER_ARRAY,
+                        mExisting);
         watcher.verifyNoChangeReported("getVisibility");
         assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
                 contains(queriesProviderAppId));
@@ -1158,7 +1172,8 @@
 
         // ensure implicit access is included in the filter
         queriesProviderFilter =
-                appsFilter.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(mSnapshot, queriesProvider, USER_ARRAY,
+                        mExisting);
         watcher.verifyNoChangeReported("getVisibility");
         assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
                 contains(hasProviderAppId, queriesProviderAppId));
@@ -1168,13 +1183,13 @@
     @Test
     public void testOnChangeReport() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
         watcher.verifyChangeReported("addBasic");
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
         watcher.verifyChangeReported("systemReady");
 
         final int systemAppId = Process.FIRST_APPLICATION_UID - 1;
@@ -1196,13 +1211,13 @@
         watcher.verifyChangeReported("addPackage");
 
         final SparseArray<int[]> systemFilter =
-                appsFilter.getVisibilityAllowList(system, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(mSnapshot, system, USER_ARRAY, mExisting);
         assertThat(toList(systemFilter.get(SYSTEM_USER)),
                 contains(seesNothingAppId, hasProviderAppId, queriesProviderAppId));
         watcher.verifyNoChangeReported("get");
 
         final SparseArray<int[]> seesNothingFilter =
-                appsFilter.getVisibilityAllowList(seesNothing, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(mSnapshot, seesNothing, USER_ARRAY, mExisting);
         assertThat(toList(seesNothingFilter.get(SYSTEM_USER)),
                 contains(seesNothingAppId));
         assertThat(toList(seesNothingFilter.get(SECONDARY_USER)),
@@ -1210,13 +1225,14 @@
         watcher.verifyNoChangeReported("get");
 
         final SparseArray<int[]> hasProviderFilter =
-                appsFilter.getVisibilityAllowList(hasProvider, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(mSnapshot, hasProvider, USER_ARRAY, mExisting);
         assertThat(toList(hasProviderFilter.get(SYSTEM_USER)),
                 contains(hasProviderAppId, queriesProviderAppId));
         watcher.verifyNoChangeReported("get");
 
         SparseArray<int[]> queriesProviderFilter =
-                appsFilter.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(mSnapshot, queriesProvider, USER_ARRAY,
+                        mExisting);
         assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
                 contains(queriesProviderAppId));
         watcher.verifyNoChangeReported("get");
@@ -1228,23 +1244,24 @@
 
         // ensure implicit access is included in the filter
         queriesProviderFilter =
-                appsFilter.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting);
+                appsFilter.getVisibilityAllowList(mSnapshot, queriesProvider, USER_ARRAY,
+                        mExisting);
         assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
                 contains(hasProviderAppId, queriesProviderAppId));
         watcher.verifyNoChangeReported("get");
 
         // remove a package
-        appsFilter.removePackage(seesNothing, false /* isReplace */);
+        appsFilter.removePackage(mSnapshot, seesNothing, false /* isReplace */);
         watcher.verifyChangeReported("removePackage");
     }
 
     @Test
     public void testOnChangeReportedFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange filter");
         watcher.register();
 
@@ -1256,21 +1273,21 @@
         watcher.verifyChangeReported("addPackage");
 
         assertFalse(
-                appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target,
-                        SYSTEM_USER));
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, instrumentation,
+                        target, SYSTEM_USER));
         assertFalse(
-                appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, target, instrumentation,
-                        SYSTEM_USER));
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_TARGET_APPID, target,
+                        instrumentation, SYSTEM_USER));
         watcher.verifyNoChangeReported("shouldFilterApplication");
     }
 
     @Test
     public void testAppsFilterRead() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
                         mMockExecutor);
         simulateAddBasicAndroid(appsFilter);
-        appsFilter.onSystemReady();
+        appsFilter.onSystemReady(mPmInternal);
 
         PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
                 DUMMY_TARGET_APPID);
@@ -1288,25 +1305,29 @@
 
         AppsFilterSnapshot snapshot = appsFilter.snapshot();
         assertFalse(
-                snapshot.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target,
+                snapshot.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, instrumentation,
+                        target,
                         SYSTEM_USER));
         assertFalse(
-                snapshot.shouldFilterApplication(DUMMY_TARGET_APPID, target, instrumentation,
+                snapshot.shouldFilterApplication(mSnapshot, DUMMY_TARGET_APPID, target,
+                        instrumentation,
                         SYSTEM_USER));
 
         SparseArray<int[]> queriesProviderFilter =
-                snapshot.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting);
+                snapshot.getVisibilityAllowList(mSnapshot, queriesProvider, USER_ARRAY, mExisting);
         assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)), contains(queriesProviderAppId));
         assertTrue(snapshot.canQueryPackage(instrumentation.getPkg(),
                 target.getPackageName()));
 
         // New changes don't affect the snapshot
-        appsFilter.removePackage(target, false);
+        appsFilter.removePackage(mSnapshot, target, false);
         assertTrue(
-                appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target,
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, instrumentation,
+                        target,
                         SYSTEM_USER));
         assertFalse(
-                snapshot.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target,
+                snapshot.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, instrumentation,
+                        target,
                         SYSTEM_USER));
 
     }
@@ -1343,7 +1364,7 @@
     }
 
     private PackageSetting simulateAddPackage(AppsFilterImpl filter,
-                ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action,
+            ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action,
             @Nullable SharedUserSetting sharedUserSetting) {
         final PackageSetting setting =
                 getPackageSettingFromParsingPackage(newPkgBuilder, appId, action);
@@ -1373,7 +1394,7 @@
             setting.setSharedUserAppId(sharedUserSetting.mAppId);
             mSharedUserSettings.add(sharedUserSetting);
         }
-        filter.addPackage(setting);
+        filter.addPackage(mSnapshot, setting);
     }
 
     private WithSettingBuilder withInstallSource(String initiatingPackageName,
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 e4ee4d06..fdf9354 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -266,6 +266,11 @@
         public void sendIntentSender(IntentSender intent) {
             // Placeholder for spying.
         }
+
+        @Override
+        public String getPackageName() {
+            return SYSTEM_PACKAGE_NAME;
+        }
     }
 
     /** ShortcutService with injection override methods. */
@@ -704,6 +709,7 @@
 
     protected UriPermissionOwner mUriPermissionOwner;
 
+    protected static final String SYSTEM_PACKAGE_NAME = "android";
 
     protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
     protected static final int CALLING_UID_1 = 10001;
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index f4ab3db..39220a4 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -1516,7 +1516,7 @@
     private Settings makeSettings() {
         return new Settings(InstrumentationRegistry.getContext().getFilesDir(),
                 mRuntimePermissionsPersistence, mPermissionDataProvider,
-                mDomainVerificationManager, new PackageManagerTracedLock());
+                mDomainVerificationManager, null, new PackageManagerTracedLock());
     }
 
     private void verifyKeySetMetaData(Settings settings)
diff --git a/services/tests/uiservicestests/AndroidManifest.xml b/services/tests/uiservicestests/AndroidManifest.xml
index 767857b..e8e3a8f 100644
--- a/services/tests/uiservicestests/AndroidManifest.xml
+++ b/services/tests/uiservicestests/AndroidManifest.xml
@@ -33,6 +33,7 @@
     <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" />
     <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT"/>
     <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
+    <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
 
     <application android:debuggable="true">
         <uses-library android:name="android.test.runner" />
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 4a13050..c5131c8 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
@@ -31,8 +31,11 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -42,18 +45,16 @@
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.content.pm.VersionedPackage;
 import android.os.Bundle;
-import android.os.IBinder;
-import android.os.IInterface;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerFilter;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationRankingUpdate;
+import android.service.notification.NotificationStats;
 import android.service.notification.StatusBarNotification;
 import android.testing.TestableContext;
 import android.util.ArraySet;
@@ -70,6 +71,7 @@
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.internal.util.reflection.FieldSetter;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
@@ -430,4 +432,66 @@
         verify(mPmi).grantImplicitAccess(sbn.getUserId(), null, UserHandle.getAppId(33),
                 sbn.getUid(), false, false);
     }
+
+    @Test
+    public void testNotifyPostedLockedInLockdownMode() {
+        NotificationRecord r = mock(NotificationRecord.class);
+        NotificationRecord old = mock(NotificationRecord.class);
+
+        // before the lockdown mode
+        when(mNm.isInLockDownMode()).thenReturn(false);
+        mListeners.notifyPostedLocked(r, old, true);
+        mListeners.notifyPostedLocked(r, old, false);
+        verify(r, atLeast(2)).getSbn();
+
+        // in the lockdown mode
+        reset(r);
+        reset(old);
+        when(mNm.isInLockDownMode()).thenReturn(true);
+        mListeners.notifyPostedLocked(r, old, true);
+        mListeners.notifyPostedLocked(r, old, false);
+        verify(r, never()).getSbn();
+    }
+
+    @Test
+    public void testnotifyRankingUpdateLockedInLockdownMode() {
+        List chn = mock(List.class);
+
+        // before the lockdown mode
+        when(mNm.isInLockDownMode()).thenReturn(false);
+        mListeners.notifyRankingUpdateLocked(chn);
+        verify(chn, atLeast(1)).size();
+
+        // in the lockdown mode
+        reset(chn);
+        when(mNm.isInLockDownMode()).thenReturn(true);
+        mListeners.notifyRankingUpdateLocked(chn);
+        verify(chn, never()).size();
+    }
+
+    @Test
+    public void testNotifyRemovedLockedInLockdownMode() throws NoSuchFieldException {
+        NotificationRecord r = mock(NotificationRecord.class);
+        NotificationStats rs = mock(NotificationStats.class);
+        StatusBarNotification sbn = mock(StatusBarNotification.class);
+        FieldSetter.setField(mNm,
+                NotificationManagerService.class.getDeclaredField("mHandler"),
+                mock(NotificationManagerService.WorkerHandler.class));
+
+        // before the lockdown mode
+        when(mNm.isInLockDownMode()).thenReturn(false);
+        when(r.getSbn()).thenReturn(sbn);
+        mListeners.notifyRemovedLocked(r, 0, rs);
+        mListeners.notifyRemovedLocked(r, 0, rs);
+        verify(r, atLeast(2)).getSbn();
+
+        // in the lockdown mode
+        reset(r);
+        reset(rs);
+        when(mNm.isInLockDownMode()).thenReturn(true);
+        when(r.getSbn()).thenReturn(sbn);
+        mListeners.notifyRemovedLocked(r, 0, rs);
+        mListeners.notifyRemovedLocked(r, 0, rs);
+        verify(r, never()).getSbn();
+    }
 }
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 b987c69..348e015 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -63,10 +63,13 @@
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
+import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static junit.framework.Assert.assertEquals;
@@ -352,6 +355,7 @@
     MultiRateLimiter mToastRateLimiter;
     BroadcastReceiver mPackageIntentReceiver;
     NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
+    TestableNotificationManagerService.StrongAuthTrackerFake mStrongAuthTracker;
     private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
             1 << 30);
     @Mock
@@ -508,6 +512,9 @@
 
         mService.setAudioManager(mAudioManager);
 
+        mStrongAuthTracker = mService.new StrongAuthTrackerFake(mContext);
+        mService.setStrongAuthTracker(mStrongAuthTracker);
+
         mShortcutHelper = mService.getShortcutHelper();
         mShortcutHelper.setLauncherApps(mLauncherApps);
         mShortcutHelper.setShortcutServiceInternal(mShortcutServiceInternal);
@@ -9247,4 +9254,44 @@
         // make sure the summary was removed and not re-posted
         assertThat(mService.getNotificationRecordCount()).isEqualTo(0);
     }
+
+    @Test
+    public void testStrongAuthTracker_isInLockDownMode() {
+        mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
+                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+        mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
+        assertTrue(mStrongAuthTracker.isInLockDownMode());
+        mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0);
+        mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
+        assertFalse(mStrongAuthTracker.isInLockDownMode());
+    }
+
+    @Test
+    public void testCancelAndPostNotificationsWhenEnterAndExitLockDownMode() {
+        // post 2 notifications from 2 packages
+        NotificationRecord pkgA = new NotificationRecord(mContext,
+                generateSbn("a", 1000, 9, 0), mTestNotificationChannel);
+        mService.addNotification(pkgA);
+        NotificationRecord pkgB = new NotificationRecord(mContext,
+                generateSbn("b", 1001, 9, 0), mTestNotificationChannel);
+        mService.addNotification(pkgB);
+
+        // when entering the lockdown mode, cancel the 2 notifications.
+        mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
+                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+        mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
+        assertTrue(mStrongAuthTracker.isInLockDownMode());
+
+        // the notifyRemovedLocked function is called twice due to REASON_CANCEL_ALL.
+        ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class);
+        verify(mListeners, times(2)).notifyRemovedLocked(any(), captor.capture(), any());
+        assertEquals(REASON_CANCEL_ALL, captor.getValue().intValue());
+
+        // exit lockdown mode.
+        mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0);
+        mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
+
+        // the notifyPostedLocked function is called twice.
+        verify(mListeners, times(2)).notifyPostedLocked(any(), any());
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
index bde0485..4ed7d35 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
@@ -113,4 +113,20 @@
     protected void doChannelWarningToast(int uid, CharSequence toastText) {
         mChannelToastsSent.add(uid);
     }
+
+    public class StrongAuthTrackerFake extends NotificationManagerService.StrongAuthTracker {
+        private int mGetStrongAuthForUserReturnValue = 0;
+        StrongAuthTrackerFake(Context context) {
+            super(context);
+        }
+
+        public void setGetStrongAuthForUserReturnValue(int val) {
+            mGetStrongAuthForUserReturnValue = val;
+        }
+
+        @Override
+        public int getStrongAuthForUser(int userId) {
+            return mGetStrongAuthForUserReturnValue;
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 55147f3..533540e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -757,6 +757,8 @@
         final ActivityRecord activity = createActivityWithTask();
         ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(activity.getTask()).build();
         topActivity.setOccludesParent(false);
+        // The requested occluding state doesn't affect whether it fills parent.
+        assertTrue(topActivity.fillsParent());
         activity.setState(STOPPED, "Testing");
         activity.setVisibility(true);
         activity.makeActiveIfNeeded(null /* activeActivity */);
@@ -1218,7 +1220,7 @@
         task.setPausingActivity(currentTop);
         currentTop.finishing = true;
         currentTop.setState(PAUSED, "test");
-        currentTop.completeFinishing("completePauseLocked");
+        currentTop.completeFinishing(false /* updateVisibility */, "completePause");
 
         // Current top becomes stopping because it is visible and the next is invisible.
         assertEquals(STOPPING, currentTop.getState());
@@ -1896,10 +1898,13 @@
         final ActivityRecord activity = createActivityWithTask();
         final Task task = activity.getTask();
         final Rect taskBounds = task.getBounds();
+        final int currentRotation = mDisplayContent.getRotation();
+        final int w = taskBounds.width();
+        final int h = taskBounds.height();
         final TaskSnapshot snapshot = new TaskSnapshotPersisterTestBase.TaskSnapshotBuilder()
                 .setTopActivityComponent(activity.mActivityComponent)
-                .setRotation(activity.getWindowConfiguration().getRotation())
-                .setTaskSize(taskBounds.width(), taskBounds.height())
+                .setRotation(currentRotation)
+                .setTaskSize(w, h)
                 .build();
 
         assertTrue(activity.isSnapshotCompatible(snapshot));
@@ -1909,6 +1914,18 @@
         activity.getWindowConfiguration().setBounds(taskBounds);
 
         assertFalse(activity.isSnapshotCompatible(snapshot));
+
+        // Flipped size should be accepted if the activity will show with 90 degree rotation.
+        final int targetRotation = currentRotation + 1;
+        doReturn(targetRotation).when(mDisplayContent)
+                .rotationForActivityInDifferentOrientation(any());
+        final TaskSnapshot rotatedSnapshot = new TaskSnapshotPersisterTestBase.TaskSnapshotBuilder()
+                .setTopActivityComponent(activity.mActivityComponent)
+                .setRotation(targetRotation)
+                .setTaskSize(h, w)
+                .build();
+        task.getWindowConfiguration().getBounds().set(0, 0, w, h);
+        assertTrue(activity.isSnapshotCompatible(rotatedSnapshot));
     }
 
     @Test
@@ -3124,7 +3141,7 @@
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
 
         InsetsSource imeSource = new InsetsSource(ITYPE_IME);
-        app.getInsetsState().addSource(imeSource);
+        app.mAboveInsetsState.addSource(imeSource);
         mDisplayContent.setImeLayeringTarget(app);
         mDisplayContent.updateImeInputAndControlTarget(app);
 
@@ -3141,10 +3158,12 @@
         // Simulate app re-start input or turning screen off/on then unlocked by un-secure
         // keyguard to back to the app, expect IME insets is not frozen
         mDisplayContent.updateImeInputAndControlTarget(app);
+        app.mActivityRecord.commitVisibility(true, false);
         assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
+
+        imeSource.setVisible(true);
         imeSource.setFrame(new Rect(100, 400, 500, 500));
-        app.getInsetsState().addSource(imeSource);
-        app.getInsetsState().setSourceVisible(ITYPE_IME, true);
+        app.mAboveInsetsState.addSource(imeSource);
 
         // Verify when IME is visible and the app can receive the right IME insets from policy.
         makeWindowVisibleAndDrawn(app, mImeWindow);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 33b7024..67f02c7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -46,7 +46,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.doCallRealMethod;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -89,14 +88,6 @@
         mAppTransitionController = new AppTransitionController(mWm, mDisplayContent);
     }
 
-    @Override
-    ActivityRecord createActivityRecord(DisplayContent dc, int windowingMode, int activityType) {
-        final ActivityRecord r = super.createActivityRecord(dc, windowingMode, activityType);
-        // Ensure that ActivityRecord#setOccludesParent takes effect.
-        doCallRealMethod().when(r).fillsParent();
-        return r;
-    }
-
     @Test
     public void testSkipOccludedActivityCloseTransition() {
         final ActivityRecord behind = createActivityRecord(mDisplayContent,
@@ -135,7 +126,7 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         final ActivityRecord translucentOpening = createActivityRecord(mDisplayContent,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
-        translucentOpening.setOccludesParent(false);
+        doReturn(false).when(translucentOpening).fillsParent();
         translucentOpening.setVisible(false);
         mDisplayContent.prepareAppTransition(TRANSIT_OPEN);
         mDisplayContent.mOpeningApps.add(behind);
@@ -153,7 +144,7 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         final ActivityRecord translucentClosing = createActivityRecord(mDisplayContent,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
-        translucentClosing.setOccludesParent(false);
+        doReturn(false).when(translucentClosing).fillsParent();
         mDisplayContent.prepareAppTransition(TRANSIT_CLOSE);
         mDisplayContent.mClosingApps.add(translucentClosing);
         assertEquals(WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE,
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index ccafbb2..8b00039 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -2193,7 +2193,7 @@
         assertEquals(windowingMode, windowConfig.getWindowingMode());
 
         // test misc display overrides
-        assertEquals(ignoreOrientationRequests, testDisplayContent.mIgnoreOrientationRequest);
+        assertEquals(ignoreOrientationRequests, testDisplayContent.mSetIgnoreOrientationRequest);
         assertEquals(fixedOrientationLetterboxRatio,
                 mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(),
                 0 /* delta */);
@@ -2234,7 +2234,7 @@
         assertEquals(windowingMode, windowConfig.getWindowingMode());
 
         // test misc display overrides
-        assertEquals(ignoreOrientationRequests, testDisplayContent.mIgnoreOrientationRequest);
+        assertEquals(ignoreOrientationRequests, testDisplayContent.mSetIgnoreOrientationRequest);
         assertEquals(fixedOrientationLetterboxRatio,
                 mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(),
                 0 /* delta */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index 25cff61c..e4eb98e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -40,7 +40,9 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.clearInvocations;
 
+import android.app.WindowConfiguration;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -515,6 +517,69 @@
     }
 
     @Test
+    public void testAllowAllRotations_allowsUpsideDownSuggestion()
+            throws Exception {
+        mBuilder.build();
+        mTarget.updateOrientation(SCREEN_ORIENTATION_UNSPECIFIED, true);
+        configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false, false);
+        when(mMockRes.getBoolean(com.android.internal.R.bool.config_allowAllRotations))
+                .thenReturn(true);
+        freezeRotation(Surface.ROTATION_0);
+        enableOrientationSensor();
+
+        mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_180));
+        assertTrue(waitForUiHandler());
+
+        verify(mMockStatusBarManagerInternal)
+                .onProposedRotationChanged(Surface.ROTATION_180, true);
+    }
+
+    @Test
+    public void testDoNotAllowAllRotations_doesNotAllowUpsideDownSuggestion()
+            throws Exception {
+        mBuilder.build();
+        mTarget.updateOrientation(SCREEN_ORIENTATION_UNSPECIFIED, true);
+        configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false, false);
+        when(mMockRes.getBoolean(com.android.internal.R.bool.config_allowAllRotations))
+                .thenReturn(false);
+        freezeRotation(Surface.ROTATION_0);
+        enableOrientationSensor();
+
+        mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_180));
+        assertTrue(waitForUiHandler());
+
+        verify(mMockStatusBarManagerInternal)
+                .onProposedRotationChanged(Surface.ROTATION_180, false);
+    }
+
+    @Test
+    public void testAllowAllRotations_allowAllRotationsBecomesDisabled_forbidsUpsideDownSuggestion()
+            throws Exception {
+        mBuilder.build();
+        mTarget.updateOrientation(SCREEN_ORIENTATION_UNSPECIFIED, true);
+        configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false, false);
+        when(mMockRes.getBoolean(com.android.internal.R.bool.config_allowAllRotations))
+                .thenReturn(true);
+        freezeRotation(Surface.ROTATION_0);
+        enableOrientationSensor();
+        mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_0));
+        assertTrue(waitForUiHandler());
+
+        // Change resource to disallow all rotations.
+        // Reset "allowAllRotations".
+        mTarget.applyCurrentRotation(Surface.ROTATION_0);
+        clearInvocations(mMockStatusBarManagerInternal);
+        when(mMockRes.getBoolean(com.android.internal.R.bool.config_allowAllRotations))
+                .thenReturn(false);
+        mTarget.resetAllowAllRotations();
+        mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_180));
+        assertTrue(waitForUiHandler());
+
+        verify(mMockStatusBarManagerInternal)
+                .onProposedRotationChanged(Surface.ROTATION_180, false);
+    }
+
+    @Test
     public void testReturnsCompatibleRotation_SensorEnabled_RotationThawed() throws Exception {
         mBuilder.build();
         configureDisplayRotation(SCREEN_ORIENTATION_PORTRAIT, false, false);
@@ -721,14 +786,20 @@
         doReturn(true).when(mMockDisplayPolicy).navigationBarCanMove();
         doReturn(win).when(mMockDisplayPolicy).getTopFullscreenOpaqueWindow();
         mMockDisplayContent.mCurrentFocus = win;
-        mTarget.mUpsideDownRotation = Surface.ROTATION_180;
+        // This should not affect the condition of shouldRotateSeamlessly.
+        mTarget.mUpsideDownRotation = Surface.ROTATION_90;
 
         doReturn(true).when(win.mActivityRecord).matchParentBounds();
         // The focused fullscreen opaque window without override bounds should be able to be
         // rotated seamlessly.
         assertTrue(mTarget.shouldRotateSeamlessly(
                 Surface.ROTATION_0, Surface.ROTATION_90, false /* forceUpdate */));
+        // Reject any 180 degree because non-movable navbar will be placed in a different position.
+        doReturn(false).when(mMockDisplayPolicy).navigationBarCanMove();
+        assertFalse(mTarget.shouldRotateSeamlessly(
+                Surface.ROTATION_90, Surface.ROTATION_180, false /* forceUpdate */));
 
+        doReturn(true).when(mMockDisplayPolicy).navigationBarCanMove();
         doReturn(false).when(win.mActivityRecord).matchParentBounds();
         // No seamless rotation if the window may be positioned with offset after rotation.
         assertFalse(mTarget.shouldRotateSeamlessly(
@@ -935,6 +1006,8 @@
                     .thenReturn(WmDisplayCutout.NO_CUTOUT);
             when(mMockDisplayContent.getDefaultTaskDisplayArea())
                     .thenReturn(mock(TaskDisplayArea.class));
+            when(mMockDisplayContent.getWindowConfiguration())
+                    .thenReturn(new WindowConfiguration());
 
             mMockDisplayPolicy = mock(DisplayPolicy.class);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index 80f6bce..e5e0145 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -741,4 +741,35 @@
         assertEquals(isAssistantOnTop ? topPosition : topPosition - 4,
                 getTaskIndexOf(taskDisplayArea, assistRootTask));
     }
+
+    /**
+     * This test verifies proper launch root based on source and candidate task for split screen.
+     * If a task is launching from a created-by-organizer task, it should be launched into the
+     * same created-by-organizer task as well. Unless, the candidate task is already positioned in
+     * the split.
+     */
+    @Test
+    public void getLaunchRootTaskInSplit() {
+        final Task rootTask = createTask(
+                mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
+        rootTask.mCreatedByOrganizer = true;
+        final Task adjacentRootTask = createTask(
+                mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
+        adjacentRootTask.mCreatedByOrganizer = true;
+        final Task candidateTask = createTaskInRootTask(rootTask, 0 /* userId*/);
+        final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea();
+        adjacentRootTask.setAdjacentTaskFragment(rootTask, false /* moveTogether */);
+
+        // Verify the launch root with candidate task
+        Task actualRootTask = taskDisplayArea.getLaunchRootTask(WINDOWING_MODE_UNDEFINED,
+                ACTIVITY_TYPE_STANDARD, null /* options */, adjacentRootTask /* sourceTask */,
+                0 /* launchFlags */, candidateTask);
+        assertSame(rootTask, actualRootTask.getRootTask());
+
+        // Verify the launch root task without candidate task
+        actualRootTask = taskDisplayArea.getLaunchRootTask(WINDOWING_MODE_UNDEFINED,
+                ACTIVITY_TYPE_STANDARD, null /* options */, adjacentRootTask /* sourceTask */,
+                0 /* launchFlags */);
+        assertSame(adjacentRootTask, actualRootTask.getRootTask());
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index a297608..7a70474 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -26,6 +26,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -38,6 +39,7 @@
 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 android.content.Intent;
@@ -63,6 +65,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 
 /**
  * Build/Install/Run:
@@ -223,6 +226,85 @@
     }
 
     @Test
+    public void testOnActivityReparentToTask_activityInOrganizerProcess_useActivityToken() {
+        // Make sure the activity pid/uid is the same as the organizer caller.
+        final int pid = Binder.getCallingPid();
+        final int uid = Binder.getCallingUid();
+        mController.registerOrganizer(mIOrganizer);
+        final ActivityRecord activity = createActivityRecord(mDisplayContent);
+        final Task task = activity.getTask();
+        activity.info.applicationInfo.uid = uid;
+        doReturn(pid).when(activity).getPid();
+        task.effectiveUid = uid;
+
+        // No need to notify organizer if it is not embedded.
+        mController.onActivityReparentToTask(activity);
+        mController.dispatchPendingEvents();
+
+        verify(mOrganizer, never()).onActivityReparentToTask(anyInt(), any(), any());
+
+        // Notify organizer if it was embedded before entered Pip.
+        activity.mLastTaskFragmentOrganizerBeforePip = mIOrganizer;
+        mController.onActivityReparentToTask(activity);
+        mController.dispatchPendingEvents();
+
+        verify(mOrganizer).onActivityReparentToTask(task.mTaskId, activity.intent, activity.token);
+
+        // Notify organizer if there is any embedded in the Task.
+        final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .setOrganizer(mOrganizer)
+                .build();
+        taskFragment.setTaskFragmentOrganizer(mOrganizer.getOrganizerToken(), uid,
+                DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME);
+        activity.reparent(taskFragment, POSITION_TOP);
+        activity.mLastTaskFragmentOrganizerBeforePip = null;
+        mController.onActivityReparentToTask(activity);
+        mController.dispatchPendingEvents();
+
+        verify(mOrganizer, times(2))
+                .onActivityReparentToTask(task.mTaskId, activity.intent, activity.token);
+    }
+
+    @Test
+    public void testOnActivityReparentToTask_activityNotInOrganizerProcess_useTemporaryToken() {
+        final int pid = Binder.getCallingPid();
+        final int uid = Binder.getCallingUid();
+        mTaskFragment.setTaskFragmentOrganizer(mOrganizer.getOrganizerToken(), uid,
+                DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME);
+        mAtm.mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
+        mController.registerOrganizer(mIOrganizer);
+        mOrganizer.applyTransaction(mTransaction);
+        final Task task = createTask(mDisplayContent);
+        task.addChild(mTaskFragment, POSITION_TOP);
+        final ActivityRecord activity = createActivityRecord(task);
+
+        // Make sure the activity belongs to the same app, but it is in a different pid.
+        activity.info.applicationInfo.uid = uid;
+        doReturn(pid + 1).when(activity).getPid();
+        task.effectiveUid = uid;
+        final ArgumentCaptor<IBinder> token = ArgumentCaptor.forClass(IBinder.class);
+
+        // Notify organizer if it was embedded before entered Pip.
+        // Create a temporary token since the activity doesn't belong to the same process.
+        activity.mLastTaskFragmentOrganizerBeforePip = mIOrganizer;
+        mController.onActivityReparentToTask(activity);
+        mController.dispatchPendingEvents();
+
+        // Allow organizer to reparent activity in other process using the temporary token.
+        verify(mOrganizer).onActivityReparentToTask(eq(task.mTaskId), eq(activity.intent),
+                token.capture());
+        final IBinder temporaryToken = token.getValue();
+        assertNotEquals(activity.token, temporaryToken);
+        mTransaction.reparentActivityToTaskFragment(mFragmentToken, temporaryToken);
+        mAtm.mWindowOrganizerController.applyTransaction(mTransaction);
+
+        assertEquals(mTaskFragment, activity.getTaskFragment());
+        // The temporary token can only be used once.
+        assertNull(mController.getReparentActivityFromTemporaryToken(mIOrganizer, temporaryToken));
+    }
+
+    @Test
     public void testRegisterRemoteAnimations() {
         mController.registerOrganizer(mIOrganizer);
         mController.registerRemoteAnimations(mIOrganizer, TASK_ID, mDefinition);
@@ -440,6 +522,55 @@
     }
 
     @Test
+    public void testApplyTransaction_requestFocusOnTaskFragment() {
+        mOrganizer.applyTransaction(mTransaction);
+        mController.registerOrganizer(mIOrganizer);
+        final Task task = createTask(mDisplayContent);
+        final IBinder token0 = new Binder();
+        final TaskFragment tf0 = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .setFragmentToken(token0)
+                .setOrganizer(mOrganizer)
+                .createActivityCount(1)
+                .build();
+        final IBinder token1 = new Binder();
+        final TaskFragment tf1 = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .setFragmentToken(token1)
+                .setOrganizer(mOrganizer)
+                .createActivityCount(1)
+                .build();
+        mAtm.mWindowOrganizerController.mLaunchTaskFragments.put(token0, tf0);
+        mAtm.mWindowOrganizerController.mLaunchTaskFragments.put(token1, tf1);
+        final ActivityRecord activity0 = tf0.getTopMostActivity();
+        final ActivityRecord activity1 = tf1.getTopMostActivity();
+
+        // No effect if the current focus is in a different Task.
+        final ActivityRecord activityInOtherTask = createActivityRecord(mDefaultDisplay);
+        mDisplayContent.setFocusedApp(activityInOtherTask);
+        mTransaction.requestFocusOnTaskFragment(token0);
+        mAtm.mWindowOrganizerController.applyTransaction(mTransaction);
+
+        assertEquals(activityInOtherTask, mDisplayContent.mFocusedApp);
+
+        // No effect if there is no resumed activity in the request TaskFragment.
+        activity0.setState(ActivityRecord.State.PAUSED, "test");
+        activity1.setState(ActivityRecord.State.RESUMED, "test");
+        mDisplayContent.setFocusedApp(activity1);
+        mAtm.mWindowOrganizerController.applyTransaction(mTransaction);
+
+        assertEquals(activity1, mDisplayContent.mFocusedApp);
+
+        // Set focus to the request TaskFragment when the current focus is in the same Task, and it
+        // has a resumed activity.
+        activity0.setState(ActivityRecord.State.RESUMED, "test");
+        mDisplayContent.setFocusedApp(activity1);
+        mAtm.mWindowOrganizerController.applyTransaction(mTransaction);
+
+        assertEquals(activity0, mDisplayContent.mFocusedApp);
+    }
+
+    @Test
     public void testTaskFragmentInPip_startActivityInTaskFragment() {
         setupTaskFragmentInPip();
         final ActivityRecord activity = mTaskFragment.getTopMostActivity();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 54fa4e4..b2043c3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -19,17 +19,22 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 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 com.android.dx.mockito.inline.extended.ExtendedMockito.any;
+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;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.wm.ActivityRecord.State.RESUMED;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.clearInvocations;
 
 import android.content.res.Configuration;
@@ -61,6 +66,7 @@
 public class TaskFragmentTest extends WindowTestsBase {
 
     private TaskFragmentOrganizer mOrganizer;
+    private ITaskFragmentOrganizer mIOrganizer;
     private TaskFragment mTaskFragment;
     private SurfaceControl mLeash;
     @Mock
@@ -70,10 +76,10 @@
     public void setup() {
         MockitoAnnotations.initMocks(this);
         mOrganizer = new TaskFragmentOrganizer(Runnable::run);
-        final ITaskFragmentOrganizer iOrganizer =
-                ITaskFragmentOrganizer.Stub.asInterface(mOrganizer.getOrganizerToken().asBinder());
+        mIOrganizer = ITaskFragmentOrganizer.Stub.asInterface(mOrganizer.getOrganizerToken()
+                .asBinder());
         mAtm.mWindowOrganizerController.mTaskFragmentOrganizerController
-                .registerOrganizer(iOrganizer);
+                .registerOrganizer(mIOrganizer);
         mTaskFragment = new TaskFragmentBuilder(mAtm)
                 .setCreateParentTask()
                 .setOrganizer(mOrganizer)
@@ -239,6 +245,8 @@
         assertEquals(taskBounds, taskFragment.getBounds());
         assertEquals(taskBounds, activity.getBounds());
         assertEquals(Configuration.EMPTY, taskFragment.getRequestedOverrideConfiguration());
+        // Because the whole Task is entering PiP, no need to record for future reparent.
+        assertNull(activity.mLastTaskFragmentOrganizerBeforePip);
     }
 
     @Test
@@ -257,6 +265,9 @@
                 .createActivityCount(1)
                 .build();
         final ActivityRecord activity0 = taskFragment0.getTopMostActivity();
+        final ActivityRecord activity1 = taskFragment1.getTopMostActivity();
+        activity0.setVisibility(true /* visible */, false /* deferHidingClient */);
+        activity1.setVisibility(true /* visible */, false /* deferHidingClient */);
         spyOn(mAtm.mTaskFragmentOrganizerController);
 
         // Move activity to pinned.
@@ -269,8 +280,76 @@
         final TaskFragmentInfo info = taskFragment0.getTaskFragmentInfo();
         assertTrue(info.isTaskFragmentClearedForPip());
         assertTrue(info.isEmpty());
+
+        // Notify organizer because the Task is still visible.
+        assertTrue(task.isVisibleRequested());
         verify(mAtm.mTaskFragmentOrganizerController)
                 .dispatchPendingInfoChangedEvent(taskFragment0);
+        // Make sure the organizer is recorded so that it can be reused when the activity is
+        // reparented back on exiting PiP.
+        assertEquals(mIOrganizer, activity0.mLastTaskFragmentOrganizerBeforePip);
+    }
+
+    @Test
+    public void testEmbeddedActivityExitPip_notifyOrganizer() {
+        final Task task = createTask(mDisplayContent);
+        final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .setOrganizer(mOrganizer)
+                .setFragmentToken(new Binder())
+                .createActivityCount(1)
+                .build();
+        new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .setOrganizer(mOrganizer)
+                .setFragmentToken(new Binder())
+                .createActivityCount(1)
+                .build();
+        final ActivityRecord activity = taskFragment.getTopMostActivity();
+        mRootWindowContainer.moveActivityToPinnedRootTask(activity,
+                null /* launchIntoPipHostActivity */, "test");
+        spyOn(mAtm.mTaskFragmentOrganizerController);
+        assertEquals(mIOrganizer, activity.mLastTaskFragmentOrganizerBeforePip);
+
+        // Move the activity back to its original Task.
+        activity.reparent(task, POSITION_TOP);
+
+        // Notify the organizer about the reparent.
+        verify(mAtm.mTaskFragmentOrganizerController).onActivityReparentToTask(activity);
+        assertNull(activity.mLastTaskFragmentOrganizerBeforePip);
+    }
+
+    @Test
+    public void testIsReadyToTransit() {
+        final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
+                .setCreateParentTask()
+                .setOrganizer(mOrganizer)
+                .setFragmentToken(new Binder())
+                .build();
+        final Task task = taskFragment.getTask();
+
+        // Not ready when it is empty.
+        assertFalse(taskFragment.isReadyToTransit());
+
+        // Ready when it is not empty.
+        final ActivityRecord activity = createActivityRecord(mDisplayContent);
+        doNothing().when(activity).setDropInputMode(anyInt());
+        activity.reparent(taskFragment, WindowContainer.POSITION_TOP);
+        assertTrue(taskFragment.isReadyToTransit());
+
+        // Ready when the Task is in PiP.
+        taskFragment.removeChild(activity);
+        task.setWindowingMode(WINDOWING_MODE_PINNED);
+        assertTrue(taskFragment.isReadyToTransit());
+
+        // Ready when the TaskFragment is empty because of PiP, and the Task is invisible.
+        task.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        taskFragment.mClearedTaskFragmentForPip = true;
+        assertTrue(taskFragment.isReadyToTransit());
+
+        // Not ready if the task is still visible when the TaskFragment becomes empty.
+        doReturn(true).when(task).isVisibleRequested();
+        assertFalse(taskFragment.isReadyToTransit());
     }
 
     @Test
@@ -324,4 +403,29 @@
         assertFalse(activity0.hasOverlayOverUntrustedModeEmbedded());
         assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded());
     }
+
+    @Test
+    public void testIsAllowedToBeEmbeddedInTrustedMode() {
+        final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
+                .setCreateParentTask()
+                .createActivityCount(2)
+                .build();
+        final ActivityRecord activity0 = taskFragment.getBottomMostActivity();
+        final ActivityRecord activity1 = taskFragment.getTopMostActivity();
+
+        // Allowed if all children activities are allowed.
+        doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity0);
+        doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity1);
+
+        assertTrue(taskFragment.isAllowedToBeEmbeddedInTrustedMode());
+
+        // Disallowed if any child activity is not allowed.
+        doReturn(false).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity0);
+
+        assertFalse(taskFragment.isAllowedToBeEmbeddedInTrustedMode());
+
+        doReturn(false).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity1);
+
+        assertFalse(taskFragment.isAllowedToBeEmbeddedInTrustedMode());
+    }
 }
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 832bd2d..40ca250 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -370,13 +370,16 @@
         // Ensure events dispatch to organizer.
         mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
         assertContainsTasks(existingTasks2, rootTask);
-        verify(organizer2, times(1)).onTaskAppeared(any(RunningTaskInfo.class),
+        verify(organizer2, never()).onTaskAppeared(any(RunningTaskInfo.class),
                 any(SurfaceControl.class));
         verify(organizer2, times(0)).onTaskVanished(any());
-        // Removed tasks from the original organizer
-        assertTaskVanished(organizer, true /* expectVanished */, rootTask, rootTask2);
-        assertTrue(rootTask2.isOrganized());
+        // The non-CreatedByOrganizer task is removed from the original organizer.
+        assertTaskVanished(organizer, true /* expectVanished */, rootTask);
+        assertEquals(organizer2, rootTask.mTaskOrganizer);
+        // The CreatedByOrganizer task should be still organized by the original organizer.
+        assertEquals(organizer, rootTask2.mTaskOrganizer);
 
+        clearInvocations(organizer);
         // Now we unregister the second one, the first one should automatically be reregistered
         // so we verify that it's now seeing changes.
         mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer2);
@@ -385,9 +388,13 @@
 
         verify(organizer, times(2))
                 .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
-        assertFalse(rootTask2.isOrganized());
-        assertTaskVanished(organizer2, true /* expectVanished */, rootTask,
-                rootTask2);
+
+        // Unregister the first one. The CreatedByOrganizer task created by it must be removed.
+        mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer);
+        assertFalse(rootTask2.isAttached());
+        assertFalse(task2.isAttached());
+        // Normal task should keep.
+        assertTrue(task.isAttached());
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index c672b91..7507df6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -1156,10 +1156,6 @@
 
             spyOn(activity);
             if (mTask != null) {
-                // fullscreen value is normally read from resources in ctor, so for testing we need
-                // to set it somewhere else since we can't mock resources.
-                doReturn(true).when(activity).occludesParent();
-                doReturn(true).when(activity).fillsParent();
                 mTask.addChild(activity);
                 if (mOnTop) {
                     // Move the task to front after activity is added.
diff --git a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
index 97d5215..eafcef2 100644
--- a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
+++ b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
@@ -41,10 +41,10 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.service.translation.TranslationServiceInfo;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Slog;
-import android.util.SparseArray;
 import android.view.autofill.AutofillId;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.translation.ITranslationServiceCallback;
@@ -71,7 +71,8 @@
 import java.util.List;
 
 final class TranslationManagerServiceImpl extends
-        AbstractPerUserSystemService<TranslationManagerServiceImpl, TranslationManagerService> {
+        AbstractPerUserSystemService<TranslationManagerServiceImpl, TranslationManagerService>
+        implements IBinder.DeathRecipient {
 
     private static final String TAG = "TranslationManagerServiceImpl";
     @SuppressLint("IsLoggableTagLength")
@@ -100,10 +101,10 @@
     private final ArraySet<IBinder> mWaitingFinishedCallbackActivities = new ArraySet<>();
 
     /**
-     * Key is translated activity uid, value is the specification and state for the translation.
+     * Key is translated activity token, value is the specification and state for the translation.
      */
     @GuardedBy("mLock")
-    private final SparseArray<ActiveTranslation> mActiveTranslations = new SparseArray<>();
+    private final ArrayMap<IBinder, ActiveTranslation> mActiveTranslations = new ArrayMap<>();
 
     protected TranslationManagerServiceImpl(
             @NonNull TranslationManagerService master,
@@ -190,25 +191,24 @@
         }
     }
 
-    private int getActivityUidByComponentName(Context context, ComponentName componentName,
-            int userId) {
-        int translationActivityUid = -1;
+    private int getAppUidByComponentName(Context context, ComponentName componentName, int userId) {
+        int translatedAppUid = -1;
         try {
             if (componentName != null) {
-                translationActivityUid = context.getPackageManager().getApplicationInfoAsUser(
+                translatedAppUid = context.getPackageManager().getApplicationInfoAsUser(
                         componentName.getPackageName(), 0, userId).uid;
             }
         } catch (PackageManager.NameNotFoundException e) {
             Slog.d(TAG, "Cannot find packageManager for" + componentName);
         }
-        return translationActivityUid;
+        return translatedAppUid;
     }
 
     @GuardedBy("mLock")
     public void onTranslationFinishedLocked(boolean activityDestroyed, IBinder token,
             ComponentName componentName) {
-        final int translationActivityUid =
-                getActivityUidByComponentName(getContext(), componentName, getUserId());
+        final int translatedAppUid =
+                getAppUidByComponentName(getContext(), componentName, getUserId());
         final String packageName = componentName.getPackageName();
         if (activityDestroyed) {
             // In the Activity destroy case, we only calls onTranslationFinished() in
@@ -216,13 +216,13 @@
             // should remove the waiting callback to avoid callback twice.
             invokeCallbacks(STATE_UI_TRANSLATION_FINISHED,
                     /* sourceSpec= */ null, /* targetSpec= */ null,
-                    packageName, translationActivityUid);
+                    packageName, translatedAppUid);
             mWaitingFinishedCallbackActivities.remove(token);
         } else {
             if (mWaitingFinishedCallbackActivities.contains(token)) {
                 invokeCallbacks(STATE_UI_TRANSLATION_FINISHED,
                         /* sourceSpec= */ null, /* targetSpec= */ null,
-                        packageName, translationActivityUid);
+                        packageName, translatedAppUid);
                 mWaitingFinishedCallbackActivities.remove(token);
             }
         }
@@ -259,49 +259,162 @@
         }
 
         ComponentName componentName = mActivityTaskManagerInternal.getActivityName(activityToken);
-        int translationActivityUid =
-                getActivityUidByComponentName(getContext(), componentName, getUserId());
+        int translatedAppUid =
+                getAppUidByComponentName(getContext(), componentName, getUserId());
         String packageName = componentName.getPackageName();
-        if (state != STATE_UI_TRANSLATION_FINISHED) {
-            invokeCallbacks(state, sourceSpec, targetSpec, packageName, translationActivityUid);
-            updateActiveTranslations(state, sourceSpec, targetSpec, packageName,
-                    translationActivityUid);
-        } else {
-            if (mActiveTranslations.contains(translationActivityUid)) {
-                mActiveTranslations.delete(translationActivityUid);
-            } else {
-                Slog.w(TAG, "Finishing translation for activity with uid=" + translationActivityUid
-                        + " but no active translation was found for it");
+
+        invokeCallbacksIfNecessaryLocked(state, sourceSpec, targetSpec, packageName, activityToken,
+                translatedAppUid);
+        updateActiveTranslationsLocked(state, sourceSpec, targetSpec, packageName, activityToken,
+                translatedAppUid);
+    }
+
+    @GuardedBy("mLock")
+    private void updateActiveTranslationsLocked(int state, TranslationSpec sourceSpec,
+            TranslationSpec targetSpec, String packageName, IBinder activityToken,
+            int translatedAppUid) {
+        // We keep track of active translations and their state so that we can:
+        // 1. Trigger callbacks that are registered after translation has started.
+        //    See registerUiTranslationStateCallbackLocked().
+        // 2. NOT trigger callbacks when the state didn't change.
+        //    See invokeCallbacksIfNecessaryLocked().
+        ActiveTranslation activeTranslation = mActiveTranslations.get(activityToken);
+        switch (state) {
+            case STATE_UI_TRANSLATION_STARTED: {
+                if (activeTranslation == null) {
+                    try {
+                        activityToken.linkToDeath(this, /* flags= */ 0);
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, "Failed to call linkToDeath for translated app with uid="
+                                + translatedAppUid + "; activity is already dead", e);
+
+                        // Apps with registered callbacks were just notified that translation
+                        // started. We should let them know translation is finished too.
+                        invokeCallbacks(STATE_UI_TRANSLATION_FINISHED, sourceSpec, targetSpec,
+                                packageName, translatedAppUid);
+                        return;
+                    }
+                    mActiveTranslations.put(activityToken,
+                            new ActiveTranslation(sourceSpec, targetSpec, translatedAppUid,
+                                    packageName));
+                }
+                break;
             }
+
+            case STATE_UI_TRANSLATION_PAUSED: {
+                if (activeTranslation != null) {
+                    activeTranslation.isPaused = true;
+                }
+                break;
+            }
+
+            case STATE_UI_TRANSLATION_RESUMED: {
+                if (activeTranslation != null) {
+                    activeTranslation.isPaused = false;
+                }
+                break;
+            }
+
+            case STATE_UI_TRANSLATION_FINISHED: {
+                if (activeTranslation != null) {
+                    mActiveTranslations.remove(activityToken);
+                }
+                break;
+            }
+        }
+
+        if (DEBUG) {
+            Slog.d(TAG,
+                    "Updating to translation state=" + state + " for app with uid="
+                            + translatedAppUid + " packageName=" + packageName);
         }
     }
 
     @GuardedBy("mLock")
-    private void updateActiveTranslations(int state, TranslationSpec sourceSpec,
-            TranslationSpec targetSpec, String packageName, int translationActivityUid) {
-        // Keep track of active translations so that we can trigger callbacks that are
-        // registered after translation has started.
-        switch (state) {
-            case STATE_UI_TRANSLATION_STARTED: {
-                ActiveTranslation activeTranslation = new ActiveTranslation(sourceSpec,
-                        targetSpec, packageName);
-                mActiveTranslations.put(translationActivityUid, activeTranslation);
-                break;
+    private void invokeCallbacksIfNecessaryLocked(int state, TranslationSpec sourceSpec,
+            TranslationSpec targetSpec, String packageName, IBinder activityToken,
+            int translatedAppUid) {
+        boolean shouldInvokeCallbacks = true;
+        int stateForCallbackInvocation = state;
+
+        ActiveTranslation activeTranslation = mActiveTranslations.get(activityToken);
+        if (activeTranslation == null) {
+            if (state != STATE_UI_TRANSLATION_STARTED) {
+                shouldInvokeCallbacks = false;
+                Slog.w(TAG,
+                        "Updating to translation state=" + state + " for app with uid="
+                                + translatedAppUid + " packageName=" + packageName
+                                + " but no active translation was found for it");
             }
-            case STATE_UI_TRANSLATION_PAUSED:
-            case STATE_UI_TRANSLATION_RESUMED: {
-                ActiveTranslation activeTranslation = mActiveTranslations.get(
-                        translationActivityUid);
-                if (activeTranslation != null) {
-                    activeTranslation.isPaused = (state == STATE_UI_TRANSLATION_PAUSED);
-                } else {
-                    Slog.w(TAG, "Pausing or resuming translation for activity with uid="
-                            + translationActivityUid
-                            + " but no active translation was found for it");
+        } else {
+            switch (state) {
+                case STATE_UI_TRANSLATION_STARTED: {
+                    boolean specsAreIdentical = activeTranslation.sourceSpec.getLocale().equals(
+                            sourceSpec.getLocale())
+                            && activeTranslation.targetSpec.getLocale().equals(
+                            targetSpec.getLocale());
+                    if (specsAreIdentical) {
+                        if (activeTranslation.isPaused) {
+                            // Ideally UiTranslationManager.resumeTranslation() should be first
+                            // used to resume translation, but for the purposes of invoking the
+                            // callback, we want to call onResumed() instead of onStarted(). This
+                            // way there can only be one call to onStarted() for the lifetime of
+                            // a translated activity and this will simplify the number of states
+                            // apps have to handle.
+                            stateForCallbackInvocation = STATE_UI_TRANSLATION_RESUMED;
+                        } else {
+                            // Don't invoke callbacks if the state or specs didn't change. For a
+                            // given activity, startTranslation() will be called every time there
+                            // are new views to be translated, but we don't need to repeatedly
+                            // notify apps about it.
+                            shouldInvokeCallbacks = false;
+                        }
+                    }
+                    break;
                 }
-                break;
+
+                case STATE_UI_TRANSLATION_PAUSED: {
+                    if (activeTranslation.isPaused) {
+                        // Don't invoke callbacks if the state didn't change.
+                        shouldInvokeCallbacks = false;
+                    }
+                    break;
+                }
+
+                case STATE_UI_TRANSLATION_RESUMED: {
+                    if (!activeTranslation.isPaused) {
+                        // Don't invoke callbacks if the state didn't change. Either
+                        // resumeTranslation() was called consecutive times, or right after
+                        // startTranslation(). The latter case shouldn't happen normally, so we
+                        // don't want apps to have to handle that particular transition.
+                        shouldInvokeCallbacks = false;
+                    }
+                    break;
+                }
+
+                case STATE_UI_TRANSLATION_FINISHED: {
+                    // Note: Here finishTranslation() was called but we don't want to invoke
+                    // onFinished() on the callbacks. They will be invoked when
+                    // UiTranslationManager.onTranslationFinished() is called (see
+                    // onTranslationFinishedLocked()).
+                    shouldInvokeCallbacks = false;
+                    break;
+                }
             }
         }
+
+        if (DEBUG) {
+            Slog.d(TAG,
+                    (shouldInvokeCallbacks ? "" : "NOT ")
+                            + "Invoking callbacks for translation state="
+                            + stateForCallbackInvocation + " for app with uid=" + translatedAppUid
+                            + " packageName=" + packageName);
+        }
+
+        if (shouldInvokeCallbacks) {
+            invokeCallbacks(stateForCallbackInvocation, sourceSpec, targetSpec, packageName,
+                    translatedAppUid);
+        }
     }
 
     @GuardedBy("mLock")
@@ -343,15 +456,14 @@
 
     private void invokeCallbacks(
             int state, TranslationSpec sourceSpec, TranslationSpec targetSpec, String packageName,
-            int translationActivityUid) {
+            int translatedAppUid) {
         Bundle result = createResultForCallback(state, sourceSpec, targetSpec, packageName);
         if (mCallbacks.getRegisteredCallbackCount() == 0) {
             return;
         }
         List<InputMethodInfo> enabledInputMethods = getEnabledInputMethods();
         mCallbacks.broadcast((callback, uid) -> {
-            invokeCallback((int) uid, translationActivityUid, callback, result,
-                    enabledInputMethods);
+            invokeCallback((int) uid, translatedAppUid, callback, result, enabledInputMethods);
         });
     }
 
@@ -374,9 +486,9 @@
     }
 
     private void invokeCallback(
-            int callbackSourceUid, int translationActivityUid, IRemoteCallback callback,
+            int callbackSourceUid, int translatedAppUid, IRemoteCallback callback,
             Bundle result, List<InputMethodInfo> enabledInputMethods) {
-        if (callbackSourceUid == translationActivityUid) {
+        if (callbackSourceUid == translatedAppUid) {
             // Invoke callback for the application being translated.
             try {
                 callback.sendResult(result);
@@ -417,29 +529,26 @@
         // Trigger the callback for already active translations.
         List<InputMethodInfo> enabledInputMethods = getEnabledInputMethods();
         for (int i = 0; i < mActiveTranslations.size(); i++) {
-            int activeTranslationUid = mActiveTranslations.keyAt(i);
             ActiveTranslation activeTranslation = mActiveTranslations.valueAt(i);
-            if (activeTranslation == null) {
-                continue;
-            }
+            int translatedAppUid = activeTranslation.translatedAppUid;
             String packageName = activeTranslation.packageName;
             if (DEBUG) {
                 Slog.d(TAG, "Triggering callback for sourceUid=" + sourceUid
-                        + " for translated activity with uid=" + activeTranslationUid
+                        + " for translated app with uid=" + translatedAppUid
                         + "packageName=" + packageName + " isPaused=" + activeTranslation.isPaused);
             }
 
             Bundle startedResult = createResultForCallback(STATE_UI_TRANSLATION_STARTED,
                     activeTranslation.sourceSpec, activeTranslation.targetSpec,
                     packageName);
-            invokeCallback(sourceUid, activeTranslationUid, callback, startedResult,
+            invokeCallback(sourceUid, translatedAppUid, callback, startedResult,
                     enabledInputMethods);
             if (activeTranslation.isPaused) {
                 // Also send event so callback owners know that translation was started then paused.
                 Bundle pausedResult = createResultForCallback(STATE_UI_TRANSLATION_PAUSED,
                         activeTranslation.sourceSpec, activeTranslation.targetSpec,
                         packageName);
-                invokeCallback(sourceUid, activeTranslationUid, callback, pausedResult,
+                invokeCallback(sourceUid, translatedAppUid, callback, pausedResult,
                         enabledInputMethods);
             }
         }
@@ -492,13 +601,34 @@
         public final TranslationSpec sourceSpec;
         public final TranslationSpec targetSpec;
         public final String packageName;
+        public final int translatedAppUid;
         public boolean isPaused = false;
 
         private ActiveTranslation(TranslationSpec sourceSpec, TranslationSpec targetSpec,
-                String packageName) {
+                int translatedAppUid, String packageName) {
             this.sourceSpec = sourceSpec;
             this.targetSpec = targetSpec;
+            this.translatedAppUid = translatedAppUid;
             this.packageName = packageName;
         }
     }
+
+    @Override
+    public void binderDied() {
+        // Don't need to implement this with binderDied(IBinder) implemented.
+    }
+
+    @Override
+    public void binderDied(IBinder who) {
+        synchronized (mLock) {
+            mWaitingFinishedCallbackActivities.remove(who);
+            ActiveTranslation activeTranslation = mActiveTranslations.remove(who);
+            if (activeTranslation != null) {
+                // Let apps with registered callbacks know about the activity's death.
+                invokeCallbacks(STATE_UI_TRANSLATION_FINISHED, activeTranslation.sourceSpec,
+                        activeTranslation.targetSpec, activeTranslation.packageName,
+                        activeTranslation.translatedAppUid);
+            }
+        }
+    }
 }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 1b07e9a..6ea416b 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -556,6 +556,7 @@
         protected boolean mCurrentUsbFunctionsReceived;
         protected int mUsbSpeed;
         protected int mCurrentGadgetHalVersion;
+        protected boolean mPendingBootAccessoryHandshakeBroadcast;
 
         /**
          * The persistent property which stores whether adb is enabled or not.
@@ -1113,7 +1114,13 @@
                     if (DEBUG) {
                         Slog.v(TAG, "Accessory handshake timeout");
                     }
-                    broadcastUsbAccessoryHandshake();
+                    if (mBootCompleted) {
+                        broadcastUsbAccessoryHandshake();
+                    } else {
+                        if (DEBUG) Slog.v(TAG, "Pending broadcasting intent as "
+                                + "not boot completed yet.");
+                        mPendingBootAccessoryHandshakeBroadcast = true;
+                    }
                     break;
                 }
                 case MSG_INCREASE_SENDSTRING_COUNT: {
@@ -1137,8 +1144,11 @@
                 if (mCurrentAccessory != null) {
                     mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory);
                     broadcastUsbAccessoryHandshake();
+                } else if (mPendingBootAccessoryHandshakeBroadcast) {
+                    broadcastUsbAccessoryHandshake();
                 }
 
+                mPendingBootAccessoryHandshakeBroadcast = false;
                 updateUsbNotification(false);
                 updateAdbNotification(false);
                 updateUsbFunctions();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 8cbbe94..f31cdcb 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -1824,6 +1824,32 @@
             }
         }
 
+        public void setSessionWindowVisible(IBinder token, boolean visible) {
+            synchronized (this) {
+                if (mImpl == null) {
+                    Slog.w(TAG, "setSessionWindowVisible called without running voice interaction "
+                            + "service");
+                    return;
+                }
+                if (mImpl.mActiveSession == null || token != mImpl.mActiveSession.mToken) {
+                    Slog.w(TAG, "setSessionWindowVisible does not match active session");
+                    return;
+                }
+                final long caller = Binder.clearCallingIdentity();
+                try {
+                    mVoiceInteractionSessionListeners.broadcast(listener -> {
+                        try {
+                            listener.onVoiceSessionWindowVisibilityChanged(visible);
+                        } catch (RemoteException e) {
+                            Slog.e(TAG, "Error delivering window visibility event to listener.", e);
+                        }
+                    });
+                } finally {
+                    Binder.restoreCallingIdentity(caller);
+                }
+            }
+        }
+
         @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 09d3a0d..e21301e 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -908,6 +908,9 @@
      * Combines VoLTE, VT, VoWiFI calling provisioning into one parameter.
      * @deprecated Use {@link Ims#KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE} instead for
      * finer-grained control.
+     * changing carrier_volte_provisioning_required_bool requires changes to
+     * mmtel_requires_provisioning_bundle and vice versa
+     * {@link Ims#KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE}
      */
     @Deprecated
     public static final String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL
@@ -5437,6 +5440,10 @@
          * </ul>
          * <p> The values are defined in
          * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech}
+         *
+         * changing mmtel_requires_provisioning_bundle requires changes to
+         * carrier_volte_provisioning_required_bool and vice versa
+         * {@link Ims#KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL}
          */
         public static final String KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE =
                 KEY_PREFIX + "mmtel_requires_provisioning_bundle";
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index c56cc62..235ed84 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1293,8 +1293,8 @@
                 && Objects.equals(this.mOperatorNumeric, other.mOperatorNumeric)
                 && Objects.equals(this.mProtocol, other.mProtocol)
                 && Objects.equals(this.mRoamingProtocol, other.mRoamingProtocol)
-                && xorEqualsInt(this.mMtuV4, other.mMtuV4)
-                && xorEqualsInt(this.mMtuV6, other.mMtuV6)
+                && mtuUnsetOrEquals(this.mMtuV4, other.mMtuV4)
+                && mtuUnsetOrEquals(this.mMtuV6, other.mMtuV6)
                 && Objects.equals(this.mCarrierEnabled, other.mCarrierEnabled)
                 && Objects.equals(this.mNetworkTypeBitmask, other.mNetworkTypeBitmask)
                 && Objects.equals(this.mLingeringNetworkTypeBitmask,
@@ -1322,7 +1322,12 @@
     // Equal or one is not specified.
     private boolean xorEqualsInt(int first, int second) {
         return first == UNSPECIFIED_INT || second == UNSPECIFIED_INT
-            || Objects.equals(first, second);
+                || first == second;
+    }
+
+    // Equal or one is not specified. Specific to MTU where <= 0 indicates unset.
+    private boolean mtuUnsetOrEquals(int first, int second) {
+        return first <= 0 || second <= 0 || first == second;
     }
 
     private String nullToEmpty(String stringValue) {
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
index 1c957d4d..8419276 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
@@ -30,6 +30,7 @@
 import android.os.SystemClock;
 import android.platform.test.annotations.RootPermissionTest;
 import android.platform.test.rule.UnlockScreenRule;
+import android.util.Log;
 import android.view.WindowInsets;
 import android.view.WindowInsetsAnimation;
 import android.view.inputmethod.InputMethodManager;
@@ -40,16 +41,19 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
 import java.util.List;
 
 @RootPermissionTest
 @RunWith(AndroidJUnit4.class)
 public final class ImeOpenCloseStressTest {
 
+    private static final String TAG = "ImeOpenCloseStressTest";
     private static final int NUM_TEST_ITERATIONS = 10;
 
     @Rule
@@ -58,32 +62,103 @@
     @Rule
     public ScreenCaptureRule mScreenCaptureRule =
             new ScreenCaptureRule("/sdcard/InputMethodStressTest");
+    private Instrumentation mInstrumentation;
+
+    @Before
+    public void setUp() {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+    }
 
     @Test
-    public void test() {
-        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-        Intent intent = new Intent()
-                .setAction(Intent.ACTION_MAIN)
-                .setClass(instrumentation.getContext(), TestActivity.class)
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        TestActivity activity = (TestActivity) instrumentation.startActivitySync(intent);
+    public void testShowHide_waitingVisibilityChange() {
+        TestActivity activity = TestActivity.start();
         EditText editText = activity.getEditText();
         waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
         for (int i = 0; i < NUM_TEST_ITERATIONS; i++) {
             String msgPrefix = "Iteration #" + i + " ";
-            instrumentation.runOnMainSync(activity::showIme);
+            Log.i(TAG, msgPrefix + "start");
+            mInstrumentation.runOnMainSync(activity::showIme);
+            waitOnMainUntil(msgPrefix + "IME should be visible", () -> isImeShown(editText));
+            mInstrumentation.runOnMainSync(activity::hideIme);
+            waitOnMainUntil(msgPrefix + "IME should be hidden", () -> !isImeShown(editText));
+        }
+    }
+
+    @Test
+    public void testShowHide_waitingAnimationEnd() {
+        TestActivity activity = TestActivity.start();
+        activity.enableAnimationMonitoring();
+        EditText editText = activity.getEditText();
+        waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
+        for (int i = 0; i < NUM_TEST_ITERATIONS; i++) {
+            String msgPrefix = "Iteration #" + i + " ";
+            Log.i(TAG, msgPrefix + "start");
+            mInstrumentation.runOnMainSync(activity::showIme);
             waitOnMainUntil(msgPrefix + "IME should be visible",
                     () -> !activity.isAnimating() && isImeShown(editText));
-            instrumentation.runOnMainSync(activity::hideIme);
+            mInstrumentation.runOnMainSync(activity::hideIme);
             waitOnMainUntil(msgPrefix + "IME should be hidden",
                     () -> !activity.isAnimating() && !isImeShown(editText));
-            // b/b/221483132, wait until IMS and IMMS handles IMM#notifyImeHidden.
-            // There is no good signal, so we just wait a second.
-            SystemClock.sleep(1000);
         }
     }
 
+    @Test
+    public void testShowHide_intervalAfterHide() {
+        // Regression test for b/221483132
+        TestActivity activity = TestActivity.start();
+        EditText editText = activity.getEditText();
+        // Intervals = 10, 20, 30, ..., 100, 150, 200, ...
+        List<Integer> intervals = new ArrayList<>();
+        for (int i = 10; i < 100; i += 10) intervals.add(i);
+        for (int i = 100; i < 1000; i += 50) intervals.add(i);
+        waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
+        for (int intervalMillis : intervals) {
+            String msgPrefix = "Interval = " + intervalMillis + " ";
+            Log.i(TAG, msgPrefix + " start");
+            mInstrumentation.runOnMainSync(activity::hideIme);
+            SystemClock.sleep(intervalMillis);
+            mInstrumentation.runOnMainSync(activity::showIme);
+            waitOnMainUntil(msgPrefix + "IME should be visible",
+                    () -> isImeShown(editText));
+        }
+    }
+
+    @Test
+    public void testShowHideInSameFrame() {
+        TestActivity activity = TestActivity.start();
+        activity.enableAnimationMonitoring();
+        EditText editText = activity.getEditText();
+        waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
+
+        // hidden -> show -> hide
+        mInstrumentation.runOnMainSync(() -> {
+            Log.i(TAG, "Calling showIme() and hideIme()");
+            activity.showIme();
+            activity.hideIme();
+        });
+        // Wait until IMMS / IMS handles messages.
+        SystemClock.sleep(1000);
+        mInstrumentation.waitForIdleSync();
+        waitOnMainUntil("IME should be invisible after show/hide", () -> !isImeShown(editText));
+
+        mInstrumentation.runOnMainSync(activity::showIme);
+        waitOnMainUntil("IME should be visible",
+                () -> !activity.isAnimating() && isImeShown(editText));
+        mInstrumentation.waitForIdleSync();
+
+        // shown -> hide -> show
+        mInstrumentation.runOnMainSync(() -> {
+            Log.i(TAG, "Calling hideIme() and showIme()");
+            activity.hideIme();
+            activity.showIme();
+        });
+        // Wait until IMMS / IMS handles messages.
+        SystemClock.sleep(1000);
+        mInstrumentation.waitForIdleSync();
+        waitOnMainUntil("IME should be visible after hide/show",
+                () -> !activity.isAnimating() && isImeShown(editText));
+    }
+
     public static class TestActivity extends Activity {
 
         private EditText mEditText;
@@ -111,6 +186,15 @@
                     }
                 };
 
+        public static TestActivity start() {
+            Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+            Intent intent = new Intent()
+                    .setAction(Intent.ACTION_MAIN)
+                    .setClass(instrumentation.getContext(), TestActivity.class)
+                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            return (TestActivity) instrumentation.startActivitySync(intent);
+        }
 
         @Override
         protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -120,9 +204,6 @@
             mEditText = new EditText(this);
             rootView.addView(mEditText, new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
             setContentView(rootView);
-            // Enable WindowInsetsAnimation.
-            getWindow().setDecorFitsSystemWindows(false);
-            mEditText.setWindowInsetsAnimationCallback(mWindowInsetsAnimationCallback);
         }
 
         public EditText getEditText() {
@@ -130,16 +211,27 @@
         }
 
         public void showIme() {
+            Log.i(TAG, "TestActivity.showIme");
             mEditText.requestFocus();
             InputMethodManager imm = getSystemService(InputMethodManager.class);
             imm.showSoftInput(mEditText, 0);
         }
 
         public void hideIme() {
+            Log.i(TAG, "TestActivity.hideIme");
             InputMethodManager imm = getSystemService(InputMethodManager.class);
             imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
         }
 
+        public void enableAnimationMonitoring() {
+            // Enable WindowInsetsAnimation.
+            // Note that this has a side effect of disabling InsetsAnimationThreadControlRunner.
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+                getWindow().setDecorFitsSystemWindows(false);
+                mEditText.setWindowInsetsAnimationCallback(mWindowInsetsAnimationCallback);
+            });
+        }
+
         public boolean isAnimating() {
             return mIsAnimating;
         }
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java
index 29c52cf..47f87d6 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java
@@ -20,6 +20,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeFalse;
+
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
@@ -28,6 +30,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.graphics.drawable.Icon;
 import android.platform.test.annotations.RootPermissionTest;
 import android.platform.test.rule.UnlockScreenRule;
@@ -89,6 +92,11 @@
         mContext = InstrumentationRegistry.getInstrumentation().getContext();
         mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
         mNotificationManager = mContext.getSystemService(NotificationManager.class);
+        PackageManager pm = mContext.getPackageManager();
+        // Do not run on Automotive.
+        assumeFalse(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE));
+        // Do not run on TV. Direct Reply isn't supported on TV.
+        assumeFalse(pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY));
     }
 
     @After
diff --git a/tests/componentalias/AndroidManifest_service_aliases.xml b/tests/componentalias/AndroidManifest_service_aliases.xml
index e73bb61..c96f173 100644
--- a/tests/componentalias/AndroidManifest_service_aliases.xml
+++ b/tests/componentalias/AndroidManifest_service_aliases.xml
@@ -23,57 +23,57 @@
         -->
         <service android:name=".s.Alias00" android:exported="true" android:enabled="true" >
             <meta-data android:name="alias_target" android:value="android.content.componentalias.tests/android.content.componentalias.tests.s.Target00" />
-            <intent-filter><action android:name="android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
+            <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
             <intent-filter><action android:name="android.content.componentalias.tests.IS_ALIAS_00" /></intent-filter>
         </service>
         <service android:name=".s.Alias01" android:exported="true" android:enabled="true" >
             <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub1/android.content.componentalias.tests.s.Target01" />
-            <intent-filter><action android:name="android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
+            <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
             <intent-filter><action android:name="android.content.componentalias.tests.IS_ALIAS_01" /></intent-filter>
         </service>
         <service android:name=".s.Alias02" android:exported="true" android:enabled="true" >
             <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub2/android.content.componentalias.tests.s.Target02" />
-            <intent-filter><action android:name="android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
+            <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
             <intent-filter><action android:name="android.content.componentalias.tests.IS_ALIAS_02" /></intent-filter>
         </service>
         <service android:name=".s.Alias03" android:exported="true" android:enabled="true" >
             <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub1/android.content.componentalias.tests.s.Target03" />
-            <intent-filter><action android:name="android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
+            <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
             <intent-filter><action android:name="android.content.componentalias.tests.IS_ALIAS_03" /></intent-filter>
         </service>
         <service android:name=".s.Alias04" android:exported="true" android:enabled="true" >
             <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub2/android.content.componentalias.tests.s.Target04" />
-            <intent-filter><action android:name="android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
+            <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
             <intent-filter><action android:name="android.content.componentalias.tests.IS_ALIAS_04" /></intent-filter>
         </service>
 
         <receiver android:name=".b.Alias00" android:exported="true" android:enabled="true" >
             <meta-data android:name="alias_target" android:value="android.content.componentalias.tests/android.content.componentalias.tests.b.Target00" />
-            <intent-filter><action android:name="android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
+            <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
             <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_00" /></intent-filter>
             <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
         </receiver>
         <receiver android:name=".b.Alias01" android:exported="true" android:enabled="true" >
             <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub1/android.content.componentalias.tests.b.Target01" />
-            <intent-filter><action android:name="android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
+            <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
             <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_01" /></intent-filter>
             <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
         </receiver>
         <receiver android:name=".b.Alias02" android:exported="true" android:enabled="true" >
             <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub2/android.content.componentalias.tests.b.Target02" />
-            <intent-filter><action android:name="android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
+            <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
             <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_02" /></intent-filter>
             <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
         </receiver>
         <receiver android:name=".b.Alias03" android:exported="true" android:enabled="true" >
             <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub1/android.content.componentalias.tests.b.Target03" />
-            <intent-filter><action android:name="android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
+            <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
             <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_03" /></intent-filter>
             <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
         </receiver>
         <receiver android:name=".b.Alias04" android:exported="true" android:enabled="true" >
             <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub2/android.content.componentalias.tests.b.Target04" />
-            <intent-filter><action android:name="android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
+            <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
             <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_04" /></intent-filter>
             <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
         </receiver>