Merge "Fix lock contention between DMS and ATMS" into tm-dev
diff --git a/ApiDocs.bp b/ApiDocs.bp
index 7f5d4a3..038ee65 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -81,7 +81,6 @@
 
         ":framework-adservices-sources",
         ":framework-appsearch-sources",
-        ":framework-auxiliary-sources",
         ":framework-connectivity-sources",
         ":framework-bluetooth-sources",
         ":framework-connectivity-tiramisu-updatable-sources",
diff --git a/ProtoLibraries.bp b/ProtoLibraries.bp
index db5ba2f..0f3ea0c 100644
--- a/ProtoLibraries.bp
+++ b/ProtoLibraries.bp
@@ -33,13 +33,14 @@
         "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)",
 
     srcs: [
+        ":framework-connectivity-protos",
         ":ipconnectivity-proto-src",
         ":libstats_atom_enum_protos",
         ":libstats_atom_message_protos",
         ":libtombstone_proto-src",
         "core/proto/**/*.proto",
         "libs/incident/**/*.proto",
-        ":service-permission-protos",
+        ":service-permission-streaming-proto-sources",
     ],
     output_extension: "srcjar",
 }
@@ -63,12 +64,13 @@
         "  $(in)",
 
     srcs: [
+        ":framework-connectivity-protos",
         ":ipconnectivity-proto-src",
         ":libstats_atom_enum_protos",
         ":libstats_atom_message_protos",
         "core/proto/**/*.proto",
         "libs/incident/**/*.proto",
-        ":service-permission-protos",
+        ":service-permission-streaming-proto-sources",
     ],
 
     output_extension: "proto.h",
@@ -78,6 +80,7 @@
 java_library_host {
     name: "platformprotos",
     srcs: [
+        ":framework-connectivity-protos",
         ":ipconnectivity-proto-src",
         ":libstats_atom_enum_protos",
         ":libstats_atom_message_protos",
@@ -87,7 +90,7 @@
         "cmds/statsd/src/**/*.proto",
         "core/proto/**/*.proto",
         "libs/incident/proto/**/*.proto",
-        ":service-permission-protos",
+        ":service-permission-streaming-proto-sources",
     ],
     proto: {
         include_dirs: [
@@ -117,12 +120,13 @@
     ],
     sdk_version: "9",
     srcs: [
+        ":framework-connectivity-protos",
         ":ipconnectivity-proto-src",
         ":libstats_atom_enum_protos",
         ":libstats_atom_message_protos",
         "core/proto/**/*.proto",
         "libs/incident/proto/android/os/**/*.proto",
-        ":service-permission-protos",
+        ":service-permission-streaming-proto-sources",
     ],
     // Protos have lots of MissingOverride and similar.
     errorprone: {
@@ -139,12 +143,13 @@
     },
 
     srcs: [
+        ":framework-connectivity-protos",
         ":ipconnectivity-proto-src",
         ":libstats_atom_enum_protos",
         ":libstats_atom_message_protos",
         "core/proto/**/*.proto",
         "libs/incident/proto/android/os/**/*.proto",
-        ":service-permission-protos",
+        ":service-permission-streaming-proto-sources",
     ],
     exclude_srcs: [
         "core/proto/android/privacy.proto",
@@ -176,11 +181,12 @@
     ],
 
     srcs: [
+        ":framework-connectivity-protos",
         ":ipconnectivity-proto-src",
         ":libstats_atom_enum_protos",
         ":libstats_atom_message_protos",
         "core/proto/**/*.proto",
-        ":service-permission-protos",
+        ":service-permission-streaming-proto-sources",
     ],
 }
 
diff --git a/StubLibraries.bp b/StubLibraries.bp
index fef95e8..32101c7 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -208,6 +208,16 @@
 /////////////////////////////////////////////////////////////////////
 
 java_defaults {
+    name: "android.jar_defaults",
+    sdk_version: "none",
+    system_modules: "none",
+    java_version: "1.8",
+    compile_dex: true,
+    defaults_visibility: ["//visibility:private"],
+    visibility: ["//visibility:public"],
+}
+
+java_defaults {
     name: "android-non-updatable_defaults_stubs_current",
     libs: ["stub-annotations"],
     static_libs: ["framework-res-package-jar"], // Export package of framework-res
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
index 4ad015d..c92c634 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
@@ -20,6 +20,7 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.os.Bundle;
 import android.os.RemoteException;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
@@ -153,7 +154,8 @@
             while (state.keepRunning()) {
                 session.relayout(mWindow, mParams, mWidth, mHeight,
                         mViewVisibility.getAsInt(), mFlags, mOutFrames,
-                        mOutMergedConfiguration, mOutSurfaceControl, mOutInsetsState, mOutControls);
+                        mOutMergedConfiguration, mOutSurfaceControl, mOutInsetsState, mOutControls,
+                        new Bundle());
             }
         }
     }
diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
index 66767e2..da429af 100644
--- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java
+++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
@@ -210,6 +210,8 @@
      * on how frequently it can be scheduled.  Only available (and automatically applied) to
      * system alarms.
      *
+     * <p>Note that alarms set with a {@link WorkSource} <b>do not</b> get this flag.
+     *
      * @hide
      */
     @UnsupportedAppUsage
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 90ec700..528be3c 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -4891,13 +4891,15 @@
             filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
             filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
             filter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
-            getContext().registerReceiver(this, filter);
+            getContext().registerReceiverForAllUsers(this, filter,
+                    /* broadcastPermission */ null, /* scheduler */ null);
             // Register for events related to sdcard installation.
             IntentFilter sdFilter = new IntentFilter();
             sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
             sdFilter.addAction(Intent.ACTION_USER_STOPPED);
             sdFilter.addAction(Intent.ACTION_UID_REMOVED);
-            getContext().registerReceiver(this, sdFilter);
+            getContext().registerReceiverForAllUsers(this, sdFilter,
+                    /* broadcastPermission */ null, /* scheduler */ null);
         }
 
         @Override
@@ -4915,9 +4917,6 @@
                             }
                         }
                         return;
-                    case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
-                        pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
-                        break;
                     case Intent.ACTION_USER_STOPPED:
                         final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                         if (userHandle >= 0) {
@@ -4932,6 +4931,18 @@
                         mRemovalHistory.delete(uid);
                         mLastOpScheduleExactAlarm.delete(uid);
                         return;
+                    case Intent.ACTION_PACKAGE_ADDED:
+                        if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                            final String packageUpdated = intent.getData().getSchemeSpecificPart();
+                            mHandler.obtainMessage(
+                                    AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE, uid, -1,
+                                    packageUpdated).sendToTarget();
+                        }
+                        mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES);
+                        return;
+                    case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
+                        pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+                        break;
                     case Intent.ACTION_PACKAGE_REMOVED:
                         if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                             // This package is being updated; don't kill its alarms.
@@ -4950,15 +4961,6 @@
                             }
                         }
                         break;
-                    case Intent.ACTION_PACKAGE_ADDED:
-                        if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
-                            final String packageUpdated = intent.getData().getSchemeSpecificPart();
-                            mHandler.obtainMessage(
-                                    AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE, uid, -1,
-                                    packageUpdated).sendToTarget();
-                        }
-                        mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES);
-                        return;
                 }
                 if (pkgList != null && (pkgList.length > 0)) {
                     for (String pkg : pkgList) {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
index a8dd752..dfa1442 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
@@ -548,7 +548,7 @@
             out.attribute(null, "sourceUserId", String.valueOf(jobStatus.getSourceUserId()));
             out.attribute(null, "uid", Integer.toString(jobStatus.getUid()));
             out.attribute(null, "bias", String.valueOf(jobStatus.getBias()));
-            out.attribute(null, "priority", String.valueOf(jobStatus.getEffectivePriority()));
+            out.attribute(null, "priority", String.valueOf(jobStatus.getJob().getPriority()));
             out.attribute(null, "flags", String.valueOf(jobStatus.getFlags()));
             if (jobStatus.getInternalFlags() != 0) {
                 out.attribute(null, "internalFlags", String.valueOf(jobStatus.getInternalFlags()));
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java b/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java
index 37b0aa8..8a64238 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java
@@ -103,7 +103,7 @@
                     mIrs.onDeviceStateChanged();
                 }
             } else if (PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED.equals(action)) {
-                if (mDeviceIdle != mPowerManager.isLightDeviceIdleMode()) {
+                if (mDeviceLightIdle != mPowerManager.isLightDeviceIdleMode()) {
                     mDeviceLightIdle = mPowerManager.isLightDeviceIdleMode();
                     mIrs.onDeviceStateChanged();
                 }
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
index dd102bd..e986b1a 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
@@ -667,8 +667,8 @@
     long getBucketExpiryTimeMs(String packageName, int userId, int bucket, long elapsedRealtimeMs) {
         ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
         AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName,
-                elapsedRealtimeMs, true);
-        if (appUsageHistory.bucketExpiryTimesMs == null) {
+                elapsedRealtimeMs, false /* create */);
+        if (appUsageHistory == null || appUsageHistory.bucketExpiryTimesMs == null) {
             return 0;
         }
         return appUsageHistory.bucketExpiryTimesMs.get(bucket, 0);
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 849354b..4952894 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -78,6 +78,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
+import android.content.pm.ResolveInfo;
 import android.database.ContentObserver;
 import android.hardware.display.DisplayManager;
 import android.net.NetworkScoreManager;
@@ -219,7 +220,8 @@
 
     private static final int HEADLESS_APP_CHECK_FLAGS =
             PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
-                    | PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS;
+                    | PackageManager.MATCH_DISABLED_COMPONENTS
+                    | PackageManager.MATCH_SYSTEM_ONLY;
 
     // To name the lock for stack traces
     static class Lock {}
@@ -253,7 +255,7 @@
     private final SparseArray<Set<String>> mActiveAdminApps = new SparseArray<>();
 
     /**
-     * Set of system apps that are headless (don't have any declared activities, enabled or
+     * Set of system apps that are headless (don't have any "front door" activities, enabled or
      * disabled). Presence in this map indicates that the app is a headless system app.
      */
     @GuardedBy("mHeadlessSystemApps")
@@ -1573,8 +1575,10 @@
                     (reason & REASON_MAIN_MASK) == REASON_MAIN_FORCED_BY_SYSTEM;
 
             if (app.currentBucket == newBucket && wasForcedBySystem && isForcedBySystem) {
-                mAppIdleHistory
-                        .noteRestrictionAttempt(packageName, userId, elapsedRealtime, reason);
+                if (newBucket == STANDBY_BUCKET_RESTRICTED) {
+                    mAppIdleHistory
+                            .noteRestrictionAttempt(packageName, userId, elapsedRealtime, reason);
+                }
                 // Keep track of all restricting reasons
                 reason = REASON_MAIN_FORCED_BY_SYSTEM
                         | (app.bucketingReason & REASON_SUB_MASK)
@@ -1942,7 +1946,7 @@
         try {
             PackageInfo pi = mPackageManager.getPackageInfoAsUser(
                     packageName, HEADLESS_APP_CHECK_FLAGS, userId);
-            evaluateSystemAppException(pi);
+            maybeUpdateHeadlessSystemAppCache(pi);
         } catch (PackageManager.NameNotFoundException e) {
             synchronized (mHeadlessSystemApps) {
                 mHeadlessSystemApps.remove(packageName);
@@ -1950,19 +1954,31 @@
         }
     }
 
-    /** Returns true if the exception status changed. */
-    private boolean evaluateSystemAppException(@Nullable PackageInfo pkgInfo) {
+    /**
+     * Update the "headless system app" cache.
+     *
+     * @return true if the cache is updated.
+     */
+    private boolean maybeUpdateHeadlessSystemAppCache(@Nullable PackageInfo pkgInfo) {
         if (pkgInfo == null || pkgInfo.applicationInfo == null
                 || (!pkgInfo.applicationInfo.isSystemApp()
                         && !pkgInfo.applicationInfo.isUpdatedSystemApp())) {
             return false;
         }
+        final Intent frontDoorActivityIntent = new Intent(Intent.ACTION_MAIN)
+                .addCategory(Intent.CATEGORY_LAUNCHER)
+                .setPackage(pkgInfo.packageName);
+        List<ResolveInfo> res = mPackageManager.queryIntentActivitiesAsUser(frontDoorActivityIntent,
+                HEADLESS_APP_CHECK_FLAGS, UserHandle.USER_SYSTEM);
+        return updateHeadlessSystemAppCache(pkgInfo.packageName, ArrayUtils.isEmpty(res));
+    }
+
+    private boolean updateHeadlessSystemAppCache(String packageName, boolean add) {
         synchronized (mHeadlessSystemApps) {
-            if (pkgInfo.activities == null || pkgInfo.activities.length == 0) {
-                // Headless system app.
-                return mHeadlessSystemApps.add(pkgInfo.packageName);
+            if (add) {
+                return mHeadlessSystemApps.add(packageName);
             } else {
-                return mHeadlessSystemApps.remove(pkgInfo.packageName);
+                return mHeadlessSystemApps.remove(packageName);
             }
         }
     }
@@ -1999,20 +2015,45 @@
         }
     }
 
+    /** Returns the packages that have launcher icons. */
+    private Set<String> getSystemPackagesWithLauncherActivities() {
+        final Intent intent = new Intent(Intent.ACTION_MAIN)
+                .addCategory(Intent.CATEGORY_LAUNCHER);
+        List<ResolveInfo> activities = mPackageManager.queryIntentActivitiesAsUser(intent,
+                HEADLESS_APP_CHECK_FLAGS, UserHandle.USER_SYSTEM);
+        final ArraySet<String> ret = new ArraySet<>();
+        for (ResolveInfo ri : activities) {
+            ret.add(ri.activityInfo.packageName);
+        }
+        return ret;
+    }
+
     /** Call on system boot to get the initial set of headless system apps. */
     private void loadHeadlessSystemAppCache() {
-        Slog.d(TAG, "Loading headless system app cache. appIdleEnabled=" + mAppIdleEnabled);
+        final long start = SystemClock.uptimeMillis();
         final List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
                 HEADLESS_APP_CHECK_FLAGS, UserHandle.USER_SYSTEM);
+
+        final Set<String> systemLauncherActivities = getSystemPackagesWithLauncherActivities();
+
         final int packageCount = packages.size();
         for (int i = 0; i < packageCount; i++) {
-            PackageInfo pkgInfo = packages.get(i);
-            if (pkgInfo != null && evaluateSystemAppException(pkgInfo)) {
+            final PackageInfo pkgInfo = packages.get(i);
+            if (pkgInfo == null) {
+                continue;
+            }
+            final String pkg = pkgInfo.packageName;
+            final boolean isHeadLess = !systemLauncherActivities.contains(pkg);
+
+            if (updateHeadlessSystemAppCache(pkg, isHeadLess)) {
                 mHandler.obtainMessage(MSG_CHECK_PACKAGE_IDLE_STATE,
-                        UserHandle.USER_SYSTEM, -1, pkgInfo.packageName)
+                        UserHandle.USER_SYSTEM, -1, pkg)
                     .sendToTarget();
             }
         }
+        final long end = SystemClock.uptimeMillis();
+        Slog.d(TAG, "Loaded headless system app cache in " + (end - start) + " ms:"
+                + " appIdleEnabled=" + mAppIdleEnabled);
     }
 
     @Override
diff --git a/boot/Android.bp b/boot/Android.bp
index 00e44f8..5b265a5 100644
--- a/boot/Android.bp
+++ b/boot/Android.bp
@@ -60,10 +60,6 @@
             module: "art-bootclasspath-fragment",
         },
         {
-            apex: "com.android.auxiliary",
-            module: "com.android.auxiliary-bootclasspath-fragment",
-        },
-        {
             apex: "com.android.bluetooth",
             module: "com.android.bluetooth-bootclasspath-fragment",
         },
diff --git a/boot/hiddenapi/hiddenapi-max-target-o.txt b/boot/hiddenapi/hiddenapi-max-target-o.txt
index d3b5be9..3c16915 100644
--- a/boot/hiddenapi/hiddenapi-max-target-o.txt
+++ b/boot/hiddenapi/hiddenapi-max-target-o.txt
@@ -32472,14 +32472,6 @@
 Landroid/net/DhcpResults;->setServerAddress(Ljava/lang/String;)Z
 Landroid/net/DhcpResults;->setVendorInfo(Ljava/lang/String;)V
 Landroid/net/DhcpResults;->TAG:Ljava/lang/String;
-Landroid/net/EthernetManager;-><init>(Landroid/content/Context;Landroid/net/IEthernetManager;)V
-Landroid/net/EthernetManager;->mContext:Landroid/content/Context;
-Landroid/net/EthernetManager;->mHandler:Landroid/os/Handler;
-Landroid/net/EthernetManager;->mListeners:Ljava/util/ArrayList;
-Landroid/net/EthernetManager;->mService:Landroid/net/IEthernetManager;
-Landroid/net/EthernetManager;->mServiceListener:Landroid/net/IEthernetServiceListener$Stub;
-Landroid/net/EthernetManager;->MSG_AVAILABILITY_CHANGED:I
-Landroid/net/EthernetManager;->TAG:Ljava/lang/String;
 Landroid/net/EventLogTags;-><init>()V
 Landroid/net/EventLogTags;->NTP_FAILURE:I
 Landroid/net/EventLogTags;->NTP_SUCCESS:I
@@ -32513,39 +32505,6 @@
 Landroid/net/http/X509TrustManagerExtensions;->mDelegate:Lcom/android/org/conscrypt/TrustManagerImpl;
 Landroid/net/http/X509TrustManagerExtensions;->mIsSameTrustConfiguration:Ljava/lang/reflect/Method;
 Landroid/net/http/X509TrustManagerExtensions;->mTrustManager:Ljavax/net/ssl/X509TrustManager;
-Landroid/net/IEthernetManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/net/IEthernetManager$Stub$Proxy;->addListener(Landroid/net/IEthernetServiceListener;)V
-Landroid/net/IEthernetManager$Stub$Proxy;->getAvailableInterfaces()[Ljava/lang/String;
-Landroid/net/IEthernetManager$Stub$Proxy;->getConfiguration(Ljava/lang/String;)Landroid/net/IpConfiguration;
-Landroid/net/IEthernetManager$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/net/IEthernetManager$Stub$Proxy;->isAvailable(Ljava/lang/String;)Z
-Landroid/net/IEthernetManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/net/IEthernetManager$Stub$Proxy;->removeListener(Landroid/net/IEthernetServiceListener;)V
-Landroid/net/IEthernetManager$Stub$Proxy;->setConfiguration(Ljava/lang/String;Landroid/net/IpConfiguration;)V
-Landroid/net/IEthernetManager$Stub;-><init>()V
-Landroid/net/IEthernetManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IEthernetManager;
-Landroid/net/IEthernetManager$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_addListener:I
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_getAvailableInterfaces:I
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_getConfiguration:I
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_isAvailable:I
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_removeListener:I
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_setConfiguration:I
-Landroid/net/IEthernetManager;->addListener(Landroid/net/IEthernetServiceListener;)V
-Landroid/net/IEthernetManager;->getAvailableInterfaces()[Ljava/lang/String;
-Landroid/net/IEthernetManager;->getConfiguration(Ljava/lang/String;)Landroid/net/IpConfiguration;
-Landroid/net/IEthernetManager;->isAvailable(Ljava/lang/String;)Z
-Landroid/net/IEthernetManager;->removeListener(Landroid/net/IEthernetServiceListener;)V
-Landroid/net/IEthernetManager;->setConfiguration(Ljava/lang/String;Landroid/net/IpConfiguration;)V
-Landroid/net/IEthernetServiceListener$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/net/IEthernetServiceListener$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/net/IEthernetServiceListener$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/net/IEthernetServiceListener$Stub$Proxy;->onAvailabilityChanged(Ljava/lang/String;Z)V
-Landroid/net/IEthernetServiceListener$Stub;-><init>()V
-Landroid/net/IEthernetServiceListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IEthernetServiceListener;
-Landroid/net/IEthernetServiceListener$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/net/IEthernetServiceListener$Stub;->TRANSACTION_onAvailabilityChanged:I
-Landroid/net/IEthernetServiceListener;->onAvailabilityChanged(Ljava/lang/String;Z)V
 Landroid/net/IIpConnectivityMetrics$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/net/IIpConnectivityMetrics$Stub$Proxy;->addNetdEventCallback(ILandroid/net/INetdEventCallback;)Z
 Landroid/net/IIpConnectivityMetrics$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
diff --git a/cmds/app_process/Android.bp b/cmds/app_process/Android.bp
index 6a685a79..a157517 100644
--- a/cmds/app_process/Android.bp
+++ b/cmds/app_process/Android.bp
@@ -64,8 +64,6 @@
         "libwilhelm",
     ],
 
-    header_libs: ["bionic_libc_platform_headers"],
-
     compile_multilib: "both",
 
     cflags: [
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 815f945..12083b6 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -15,7 +15,6 @@
 
 #include <android-base/macros.h>
 #include <binder/IPCThreadState.h>
-#include <bionic/pac.h>
 #include <hwbinder/IPCThreadState.h>
 #include <utils/Log.h>
 #include <cutils/memory.h>
@@ -183,10 +182,6 @@
       ALOGV("app_process main with argv: %s", argv_String.string());
     }
 
-    // Because of applications that are using PAC instructions incorrectly, PAC
-    // is disabled in application processes for now.
-    ScopedDisablePAC x;
-
     AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
     // Process command line arguments
     // ignore argv[0]
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index c202f6f..6ef6845 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -52,6 +52,7 @@
         "-readability-braces-around-statements",
         "-readability-const-return-type",
         "-readability-convert-member-functions-to-static",
+        "-readability-duplicate-include",
         "-readability-else-after-return",
         "-readability-identifier-length",
         "-readability-named-parameter",
diff --git a/core/api/current.txt b/core/api/current.txt
index f0b86df..b5493a3 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -8,6 +8,9 @@
   public static final class Manifest.permission {
     ctor public Manifest.permission();
     field public static final String ACCEPT_HANDOVER = "android.permission.ACCEPT_HANDOVER";
+    field public static final String ACCESS_ADSERVICES_ATTRIBUTION = "android.permission.ACCESS_ADSERVICES_ATTRIBUTION";
+    field public static final String ACCESS_ADSERVICES_CUSTOM_AUDIENCES = "android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCES";
+    field public static final String ACCESS_ADSERVICES_TOPICS = "android.permission.ACCESS_ADSERVICES_TOPICS";
     field public static final String ACCESS_BACKGROUND_LOCATION = "android.permission.ACCESS_BACKGROUND_LOCATION";
     field public static final String ACCESS_BLOBS_ACROSS_USERS = "android.permission.ACCESS_BLOBS_ACROSS_USERS";
     field public static final String ACCESS_CHECKIN_PROPERTIES = "android.permission.ACCESS_CHECKIN_PROPERTIES";
@@ -17,7 +20,6 @@
     field public static final String ACCESS_MEDIA_LOCATION = "android.permission.ACCESS_MEDIA_LOCATION";
     field public static final String ACCESS_NETWORK_STATE = "android.permission.ACCESS_NETWORK_STATE";
     field public static final String ACCESS_NOTIFICATION_POLICY = "android.permission.ACCESS_NOTIFICATION_POLICY";
-    field public static final String ACCESS_SUPPLEMENTAL_APIS = "android.permission.ACCESS_SUPPLEMENTAL_APIS";
     field public static final String ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE";
     field public static final String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
     field public static final String ACTIVITY_RECOGNITION = "android.permission.ACTIVITY_RECOGNITION";
@@ -111,8 +113,9 @@
     field public static final String MANAGE_MEDIA = "android.permission.MANAGE_MEDIA";
     field public static final String MANAGE_ONGOING_CALLS = "android.permission.MANAGE_ONGOING_CALLS";
     field public static final String MANAGE_OWN_CALLS = "android.permission.MANAGE_OWN_CALLS";
-    field public static final String MANAGE_WIFI_AUTO_JOIN = "android.permission.MANAGE_WIFI_AUTO_JOIN";
+    field @Deprecated public static final String MANAGE_WIFI_AUTO_JOIN = "android.permission.MANAGE_WIFI_AUTO_JOIN";
     field public static final String MANAGE_WIFI_INTERFACES = "android.permission.MANAGE_WIFI_INTERFACES";
+    field public static final String MANAGE_WIFI_NETWORK_SELECTION = "android.permission.MANAGE_WIFI_NETWORK_SELECTION";
     field public static final String MASTER_CLEAR = "android.permission.MASTER_CLEAR";
     field public static final String MEDIA_CONTENT_CONTROL = "android.permission.MEDIA_CONTENT_CONTROL";
     field public static final String MODIFY_AUDIO_SETTINGS = "android.permission.MODIFY_AUDIO_SETTINGS";
@@ -139,7 +142,7 @@
     field @Deprecated public static final String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
     field public static final String READ_LOGS = "android.permission.READ_LOGS";
     field public static final String READ_MEDIA_AUDIO = "android.permission.READ_MEDIA_AUDIO";
-    field public static final String READ_MEDIA_IMAGE = "android.permission.READ_MEDIA_IMAGE";
+    field public static final String READ_MEDIA_IMAGES = "android.permission.READ_MEDIA_IMAGES";
     field public static final String READ_MEDIA_VIDEO = "android.permission.READ_MEDIA_VIDEO";
     field public static final String READ_NEARBY_STREAMING_POLICY = "android.permission.READ_NEARBY_STREAMING_POLICY";
     field public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS";
@@ -979,8 +982,8 @@
     field public static final int left = 16843181; // 0x10101ad
     field public static final int letterSpacing = 16843958; // 0x10104b6
     field public static final int level = 16844032; // 0x1010500
-    field public static final int lineBreakStyle = 16844365; // 0x101064d
-    field public static final int lineBreakWordStyle = 16844366; // 0x101064e
+    field public static final int lineBreakStyle;
+    field public static final int lineBreakWordStyle;
     field public static final int lineHeight = 16844159; // 0x101057f
     field public static final int lineSpacingExtra = 16843287; // 0x1010217
     field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
@@ -2094,12 +2097,8 @@
     field public static final int accessibilityActionScrollUp = 16908344; // 0x1020038
     field public static final int accessibilityActionSetProgress = 16908349; // 0x102003d
     field public static final int accessibilityActionShowOnScreen = 16908342; // 0x1020036
-    field public static final int accessibilityActionShowSuggestions;
+    field public static final int accessibilityActionShowTextSuggestions;
     field public static final int accessibilityActionShowTooltip = 16908356; // 0x1020044
-    field public static final int accessibilityActionSwipeDown;
-    field public static final int accessibilityActionSwipeLeft;
-    field public static final int accessibilityActionSwipeRight;
-    field public static final int accessibilityActionSwipeUp;
     field public static final int accessibilitySystemActionBack = 16908363; // 0x102004b
     field public static final int accessibilitySystemActionHome = 16908364; // 0x102004c
     field public static final int accessibilitySystemActionLockScreen = 16908370; // 0x1020052
@@ -3337,7 +3336,7 @@
   }
 
   public class InputMethod {
-    ctor protected InputMethod(@NonNull android.accessibilityservice.AccessibilityService);
+    ctor public InputMethod(@NonNull android.accessibilityservice.AccessibilityService);
     method @Nullable public final android.accessibilityservice.InputMethod.AccessibilityInputConnection getCurrentInputConnection();
     method @Nullable public final android.view.inputmethod.EditorInfo getCurrentInputEditorInfo();
     method public final boolean getCurrentInputStarted();
@@ -3902,6 +3901,7 @@
     method public Object getAnimatedValue(String);
     method public long getCurrentPlayTime();
     method public long getDuration();
+    method @FloatRange(from=0) public static float getDurationScale();
     method public static long getFrameDelay();
     method public int getRepeatCount();
     method public int getRepeatMode();
@@ -3913,6 +3913,7 @@
     method public static android.animation.ValueAnimator ofInt(int...);
     method public static android.animation.ValueAnimator ofObject(android.animation.TypeEvaluator, java.lang.Object...);
     method public static android.animation.ValueAnimator ofPropertyValuesHolder(android.animation.PropertyValuesHolder...);
+    method public static boolean registerDurationScaleChangeListener(@NonNull android.animation.ValueAnimator.DurationScaleChangeListener);
     method public void removeAllUpdateListeners();
     method public void removeUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public void reverse();
@@ -3929,6 +3930,7 @@
     method public void setRepeatMode(int);
     method public void setStartDelay(long);
     method public void setValues(android.animation.PropertyValuesHolder...);
+    method public static boolean unregisterDurationScaleChangeListener(@NonNull android.animation.ValueAnimator.DurationScaleChangeListener);
     field public static final int INFINITE = -1; // 0xffffffff
     field public static final int RESTART = 1; // 0x1
     field public static final int REVERSE = 2; // 0x2
@@ -3938,6 +3940,10 @@
     method public void onAnimationUpdate(@NonNull android.animation.ValueAnimator);
   }
 
+  public static interface ValueAnimator.DurationScaleChangeListener {
+    method public void onChanged(@FloatRange(from=0) float);
+  }
+
 }
 
 package android.annotation {
@@ -4277,7 +4283,6 @@
     method public void setLocusContext(@Nullable android.content.LocusId, @Nullable android.os.Bundle);
     method public final void setMediaController(android.media.session.MediaController);
     method public void setPictureInPictureParams(@NonNull android.app.PictureInPictureParams);
-    method public void setPreferDockBigOverlays(boolean);
     method @Deprecated public final void setProgress(int);
     method @Deprecated public final void setProgressBarIndeterminate(boolean);
     method @Deprecated public final void setProgressBarIndeterminateVisibility(boolean);
@@ -4287,6 +4292,7 @@
     method public final void setResult(int);
     method public final void setResult(int, android.content.Intent);
     method @Deprecated public final void setSecondaryProgress(int);
+    method public void setShouldDockBigOverlays(boolean);
     method public void setShowWhenLocked(boolean);
     method public void setTaskDescription(android.app.ActivityManager.TaskDescription);
     method public void setTitle(CharSequence);
@@ -4297,6 +4303,7 @@
     method public void setVisible(boolean);
     method public final void setVolumeControlStream(int);
     method public void setVrModeEnabled(boolean, @NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public boolean shouldDockBigOverlays();
     method public boolean shouldShowRequestPermissionRationale(@NonNull String);
     method public boolean shouldUpRecreateTask(android.content.Intent);
     method public boolean showAssist(android.os.Bundle);
@@ -7439,7 +7446,7 @@
     method @Nullable public java.util.List<java.lang.String> getPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName);
     method @Nullable public java.util.List<java.lang.String> getPermittedInputMethods(@NonNull android.content.ComponentName);
     method public int getPersonalAppsSuspendedReasons(@NonNull android.content.ComponentName);
-    method @NonNull public android.app.admin.PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig();
+    method @NonNull public java.util.List<android.app.admin.PreferentialNetworkServiceConfig> getPreferentialNetworkServiceConfigs();
     method public int getRequiredPasswordComplexity();
     method public long getRequiredStrongAuthTimeout(@Nullable android.content.ComponentName);
     method public boolean getScreenCaptureDisabled(@Nullable android.content.ComponentName);
@@ -7584,7 +7591,7 @@
     method public boolean setPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName, @Nullable java.util.List<java.lang.String>);
     method public boolean setPermittedInputMethods(@NonNull android.content.ComponentName, java.util.List<java.lang.String>);
     method public void setPersonalAppsSuspended(@NonNull android.content.ComponentName, boolean);
-    method public void setPreferentialNetworkServiceConfig(@NonNull android.app.admin.PreferentialNetworkServiceConfig);
+    method public void setPreferentialNetworkServiceConfigs(@NonNull java.util.List<android.app.admin.PreferentialNetworkServiceConfig>);
     method public void setPreferentialNetworkServiceEnabled(boolean);
     method public void setProfileEnabled(@NonNull android.content.ComponentName);
     method public void setProfileName(@NonNull android.content.ComponentName, String);
@@ -11293,6 +11300,7 @@
     method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, "android.permission.INTERACT_ACROSS_USERS"}) public void startActivity(@NonNull android.content.Intent, @NonNull android.os.UserHandle, @Nullable android.app.Activity);
     method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, "android.permission.INTERACT_ACROSS_USERS"}) public void startActivity(@NonNull android.content.Intent, @NonNull android.os.UserHandle, @Nullable android.app.Activity, @Nullable android.os.Bundle);
     method public void startMainActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
+    method public void startMainActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle, @Nullable android.app.Activity, @Nullable android.os.Bundle);
     field public static final String ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED = "android.content.pm.action.CAN_INTERACT_ACROSS_PROFILES_CHANGED";
   }
 
@@ -16400,12 +16408,8 @@
 package android.graphics.text {
 
   public final class LineBreakConfig {
-    ctor public LineBreakConfig();
     method public int getLineBreakStyle();
     method public int getLineBreakWordStyle();
-    method public void set(@NonNull android.graphics.text.LineBreakConfig);
-    method public void setLineBreakStyle(int);
-    method public void setLineBreakWordStyle(int);
     field public static final int LINE_BREAK_STYLE_LOOSE = 1; // 0x1
     field public static final int LINE_BREAK_STYLE_NONE = 0; // 0x0
     field public static final int LINE_BREAK_STYLE_NORMAL = 2; // 0x2
@@ -16414,6 +16418,13 @@
     field public static final int LINE_BREAK_WORD_STYLE_PHRASE = 1; // 0x1
   }
 
+  public static final class LineBreakConfig.Builder {
+    ctor public LineBreakConfig.Builder();
+    method @NonNull public android.graphics.text.LineBreakConfig build();
+    method @NonNull public android.graphics.text.LineBreakConfig.Builder setLineBreakStyle(int);
+    method @NonNull public android.graphics.text.LineBreakConfig.Builder setLineBreakWordStyle(int);
+  }
+
   public class LineBreaker {
     method @NonNull public android.graphics.text.LineBreaker.Result computeLineBreaks(@NonNull android.graphics.text.MeasuredText, @NonNull android.graphics.text.LineBreaker.ParagraphConstraints, @IntRange(from=0) int);
     field public static final int BREAK_STRATEGY_BALANCED = 2; // 0x2
@@ -17401,7 +17412,7 @@
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Long> REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Float> SCALER_AVAILABLE_MAX_DIGITAL_ZOOM;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> SCALER_AVAILABLE_ROTATE_AND_CROP_MODES;
-    field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> SCALER_AVAILABLE_STREAM_USE_CASES;
+    field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<long[]> SCALER_AVAILABLE_STREAM_USE_CASES;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> SCALER_CROPPING_TYPE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Size> SCALER_DEFAULT_SECURE_IMAGE_SIZE;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.MandatoryStreamCombination[]> SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS;
@@ -18186,7 +18197,7 @@
     method public int get10BitFormat();
     method @NonNull public java.util.List<android.util.Size> getAvailableSizes();
     method public int getFormat();
-    method public int getStreamUseCase();
+    method public long getStreamUseCase();
     method public boolean is10BitCapable();
     method public boolean isInput();
     method public boolean isMaximumSize();
@@ -18244,7 +18255,7 @@
     method public long getDynamicRangeProfile();
     method public int getMaxSharedSurfaceCount();
     method public int getMirrorMode();
-    method public int getStreamUseCase();
+    method public long getStreamUseCase();
     method @Nullable public android.view.Surface getSurface();
     method public int getSurfaceGroupId();
     method @NonNull public java.util.List<android.view.Surface> getSurfaces();
@@ -18254,7 +18265,7 @@
     method public void setDynamicRangeProfile(long);
     method public void setMirrorMode(int);
     method public void setPhysicalCameraId(@Nullable String);
-    method public void setStreamUseCase(int);
+    method public void setStreamUseCase(long);
     method public void setTimestampBase(int);
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
@@ -18820,6 +18831,7 @@
     method public void onStartInput(android.view.inputmethod.EditorInfo, boolean);
     method public void onStartInputView(android.view.inputmethod.EditorInfo, boolean);
     method public boolean onStartStylusHandwriting();
+    method public void onStylusHandwritingMotionEvent(@NonNull android.view.MotionEvent);
     method public void onUnbindInput();
     method @Deprecated public void onUpdateCursor(android.graphics.Rect);
     method public void onUpdateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo);
@@ -26065,11 +26077,9 @@
   public static final class AppLinkInfo.Builder {
     ctor public AppLinkInfo.Builder(@NonNull String, @NonNull String);
     method @NonNull public android.media.tv.interactive.AppLinkInfo build();
-    method @NonNull public android.media.tv.interactive.AppLinkInfo.Builder setClassName(@NonNull String);
-    method @NonNull public android.media.tv.interactive.AppLinkInfo.Builder setPackageName(@NonNull String);
-    method @NonNull public android.media.tv.interactive.AppLinkInfo.Builder setUriHost(@Nullable String);
-    method @NonNull public android.media.tv.interactive.AppLinkInfo.Builder setUriPrefix(@Nullable String);
-    method @NonNull public android.media.tv.interactive.AppLinkInfo.Builder setUriScheme(@Nullable String);
+    method @NonNull public android.media.tv.interactive.AppLinkInfo.Builder setUriHost(@NonNull String);
+    method @NonNull public android.media.tv.interactive.AppLinkInfo.Builder setUriPrefix(@NonNull String);
+    method @NonNull public android.media.tv.interactive.AppLinkInfo.Builder setUriScheme(@NonNull String);
   }
 
   public final class TvInteractiveAppInfo implements android.os.Parcelable {
@@ -26089,7 +26099,7 @@
     method @NonNull public java.util.List<android.media.tv.interactive.TvInteractiveAppInfo> getTvInteractiveAppServiceList();
     method public void prepare(@NonNull String, int);
     method public void registerAppLinkInfo(@NonNull String, @NonNull android.media.tv.interactive.AppLinkInfo);
-    method public void registerCallback(@NonNull android.media.tv.interactive.TvInteractiveAppManager.TvInteractiveAppCallback, @NonNull java.util.concurrent.Executor);
+    method public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.tv.interactive.TvInteractiveAppManager.TvInteractiveAppCallback);
     method public void sendAppLinkCommand(@NonNull String, @NonNull android.os.Bundle);
     method public void unregisterAppLinkInfo(@NonNull String, @NonNull android.media.tv.interactive.AppLinkInfo);
     method public void unregisterCallback(@NonNull android.media.tv.interactive.TvInteractiveAppManager.TvInteractiveAppCallback);
@@ -26159,10 +26169,10 @@
 
   public abstract static class TvInteractiveAppService.Session implements android.view.KeyEvent.Callback {
     ctor public TvInteractiveAppService.Session(@NonNull android.content.Context);
-    method public void layoutSurface(int, int, int, int);
-    method public final void notifyBiInteractiveAppCreated(@NonNull android.net.Uri, @Nullable String);
-    method public void notifySessionStateChanged(int, int);
-    method public final void notifyTeletextAppStateChanged(int);
+    method @CallSuper public void layoutSurface(int, int, int, int);
+    method @CallSuper public final void notifyBiInteractiveAppCreated(@NonNull android.net.Uri, @Nullable String);
+    method @CallSuper public void notifySessionStateChanged(int, int);
+    method @CallSuper public final void notifyTeletextAppStateChanged(int);
     method public void onAdResponse(@NonNull android.media.tv.AdResponse);
     method public void onBroadcastInfoResponse(@NonNull android.media.tv.BroadcastInfoResponse);
     method public void onContentAllowed();
@@ -26196,17 +26206,17 @@
     method public void onTuned(@NonNull android.net.Uri);
     method public void onVideoAvailable();
     method public void onVideoUnavailable(int);
-    method public void removeBroadcastInfo(int);
-    method public void requestAd(@NonNull android.media.tv.AdRequest);
-    method public void requestBroadcastInfo(@NonNull android.media.tv.BroadcastInfoRequest);
-    method public void requestCurrentChannelLcn();
-    method public void requestCurrentChannelUri();
-    method public void requestCurrentTvInputId();
-    method public void requestStreamVolume();
-    method public void requestTrackInfoList();
-    method public void sendPlaybackCommandRequest(@NonNull String, @Nullable android.os.Bundle);
-    method public void setMediaViewEnabled(boolean);
-    method public void setVideoBounds(@NonNull android.graphics.Rect);
+    method @CallSuper public void removeBroadcastInfo(int);
+    method @CallSuper public void requestAd(@NonNull android.media.tv.AdRequest);
+    method @CallSuper public void requestBroadcastInfo(@NonNull android.media.tv.BroadcastInfoRequest);
+    method @CallSuper public void requestCurrentChannelLcn();
+    method @CallSuper public void requestCurrentChannelUri();
+    method @CallSuper public void requestCurrentTvInputId();
+    method @CallSuper public void requestStreamVolume();
+    method @CallSuper public void requestTrackInfoList();
+    method @CallSuper public void sendPlaybackCommandRequest(@NonNull String, @Nullable android.os.Bundle);
+    method @CallSuper public void setMediaViewEnabled(boolean);
+    method @CallSuper public void setVideoBounds(@NonNull android.graphics.Rect);
   }
 
   public class TvInteractiveAppView extends android.view.ViewGroup {
@@ -26509,14 +26519,6 @@
     method public int getUid();
   }
 
-  public final class EthernetNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
-    ctor public EthernetNetworkSpecifier(@NonNull String);
-    method public int describeContents();
-    method @Nullable public String getInterfaceName();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkSpecifier> CREATOR;
-  }
-
   public final class Ikev2VpnProfile extends android.net.PlatformVpnProfile {
     method @NonNull public java.util.List<java.lang.String> getAllowedAlgorithms();
     method public int getMaxMtu();
@@ -45064,7 +45066,7 @@
   public static final class PrecomputedText.Params {
     method public int getBreakStrategy();
     method public int getHyphenationFrequency();
-    method @Nullable public android.graphics.text.LineBreakConfig getLineBreakConfig();
+    method @NonNull public android.graphics.text.LineBreakConfig getLineBreakConfig();
     method @NonNull public android.text.TextDirectionHeuristic getTextDirection();
     method @NonNull public android.text.TextPaint getTextPaint();
   }
@@ -51931,12 +51933,8 @@
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_SELECTION;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_TEXT;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_ON_SCREEN;
-    field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_SUGGESTIONS;
+    field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_TEXT_SUGGESTIONS;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_TOOLTIP;
-    field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SWIPE_DOWN;
-    field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SWIPE_LEFT;
-    field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SWIPE_RIGHT;
-    field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SWIPE_UP;
     field @NonNull public static final android.os.Parcelable.Creator<android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction> CREATOR;
   }
 
@@ -57358,7 +57356,8 @@
     method public final android.text.Layout getLayout();
     method public float getLetterSpacing();
     method public int getLineBounds(int, android.graphics.Rect);
-    method @NonNull public android.graphics.text.LineBreakConfig getLineBreakConfig();
+    method public int getLineBreakStyle();
+    method public int getLineBreakWordStyle();
     method public int getLineCount();
     method public int getLineHeight();
     method public float getLineSpacingExtra();
@@ -57486,7 +57485,8 @@
     method public void setKeyListener(android.text.method.KeyListener);
     method public void setLastBaselineToBottomHeight(@IntRange(from=0) @Px int);
     method public void setLetterSpacing(float);
-    method public void setLineBreakConfig(@NonNull android.graphics.text.LineBreakConfig);
+    method public void setLineBreakStyle(int);
+    method public void setLineBreakWordStyle(int);
     method public void setLineHeight(@IntRange(from=0) @Px int);
     method public void setLineSpacing(float, float);
     method public void setLines(int);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 5bc5bbc..3d5232b 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -20,10 +20,6 @@
     method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
   }
 
-  public class ActivityOptions {
-    method @NonNull public static android.app.ActivityOptions fromBundle(@NonNull android.os.Bundle);
-  }
-
   public class AppOpsManager {
     field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
   }
@@ -54,22 +50,6 @@
     method public void onCanceled(@NonNull android.app.PendingIntent);
   }
 
-  public class PropertyInvalidatedCache<Query, Result> {
-    ctor public PropertyInvalidatedCache(int, @NonNull String, @NonNull String, @NonNull String, @NonNull android.app.PropertyInvalidatedCache.QueryHandler<Query,Result>);
-    method public final void disableForCurrentProcess();
-    method public final void invalidateCache();
-    method public static void invalidateCache(@NonNull String, @NonNull String);
-    method @Nullable public final Result query(@NonNull Query);
-    field public static final String MODULE_BLUETOOTH = "bluetooth";
-    field public static final String MODULE_TELEPHONY = "telephony";
-  }
-
-  public abstract static class PropertyInvalidatedCache.QueryHandler<Q, R> {
-    ctor public PropertyInvalidatedCache.QueryHandler();
-    method @Nullable public abstract R apply(@NonNull Q);
-    method public boolean shouldBypassCache(@NonNull Q);
-  }
-
   public class StatusBarManager {
     method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setExpansionDisabledForSimNetworkLock(boolean);
   }
@@ -122,6 +102,8 @@
   public abstract class PackageManager {
     method @NonNull public String getPermissionControllerPackageName();
     method @NonNull public String getSdkSandboxPackageName();
+    method @RequiresPermission("android.permission.MAKE_UID_VISIBLE") public void makeUidVisible(int, int);
+    field public static final String EXTRA_VERIFICATION_ROOT_HASH = "android.content.pm.extra.VERIFICATION_ROOT_HASH";
     field public static final int MATCH_STATIC_SHARED_AND_SDK_LIBRARIES = 67108864; // 0x4000000
   }
 
@@ -251,22 +233,6 @@
 
 package android.net {
 
-  public class EthernetManager {
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void addInterfaceStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.InterfaceStateListener);
-    method public void removeInterfaceStateListener(@NonNull android.net.EthernetManager.InterfaceStateListener);
-    method public void setIncludeTestInterfaces(boolean);
-    field public static final int ROLE_CLIENT = 1; // 0x1
-    field public static final int ROLE_NONE = 0; // 0x0
-    field public static final int ROLE_SERVER = 2; // 0x2
-    field public static final int STATE_ABSENT = 0; // 0x0
-    field public static final int STATE_LINK_DOWN = 1; // 0x1
-    field public static final int STATE_LINK_UP = 2; // 0x2
-  }
-
-  public static interface EthernetManager.InterfaceStateListener {
-    method public void onInterfaceStateChanged(@NonNull String, int, int, @Nullable android.net.IpConfiguration);
-  }
-
   public class LocalSocket implements java.io.Closeable {
     ctor public LocalSocket(@NonNull java.io.FileDescriptor);
   }
@@ -358,13 +324,29 @@
     field public static final int DEVICE_INITIAL_SDK_INT;
   }
 
+  public class IpcDataCache<Query, Result> {
+    ctor public IpcDataCache(int, @NonNull String, @NonNull String, @NonNull String, @NonNull android.os.IpcDataCache.QueryHandler<Query,Result>);
+    method public void disableForCurrentProcess();
+    method public static void disableForCurrentProcess(@NonNull String);
+    method public void invalidateCache();
+    method public static void invalidateCache(@NonNull String, @NonNull String);
+    method @Nullable public Result query(@NonNull Query);
+    field public static final String MODULE_BLUETOOTH = "bluetooth";
+  }
+
+  public abstract static class IpcDataCache.QueryHandler<Q, R> {
+    ctor public IpcDataCache.QueryHandler();
+    method @Nullable public abstract R apply(@NonNull Q);
+    method public boolean shouldBypassCache(@NonNull Q);
+  }
+
   public interface Parcelable {
     method public default int getStability();
   }
 
   public class Process {
+    method public static final int getAppUidForSdkSandboxUid(int);
     method public static final boolean isSdkSandboxUid(int);
-    method public static final int sdkSandboxToAppUid(int);
     method public static final int toSdkSandboxUid(int);
     field public static final int NFC_UID = 1027; // 0x403
     field public static final int VPN_UID = 1016; // 0x3f8
@@ -458,6 +440,14 @@
 
 }
 
+package android.telecom {
+
+  public abstract class ConnectionService extends android.app.Service {
+    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telecom.Connection onCreateUnknownConnection(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
+  }
+
+}
+
 package android.telephony {
 
   public abstract class CellSignalStrength {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 1566601..5da1f39 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -34,6 +34,7 @@
     field public static final String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
     field public static final String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK";
     field public static final String ALLOW_PLACE_IN_MULTI_PANE_SETTINGS = "android.permission.ALLOW_PLACE_IN_MULTI_PANE_SETTINGS";
+    field public static final String ALLOW_SLIPPERY_TOUCHES = "android.permission.ALLOW_SLIPPERY_TOUCHES";
     field public static final String AMBIENT_WALLPAPER = "android.permission.AMBIENT_WALLPAPER";
     field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS";
     field public static final String ASSOCIATE_COMPANION_DEVICES = "android.permission.ASSOCIATE_COMPANION_DEVICES";
@@ -234,6 +235,7 @@
     field public static final String POWER_SAVER = "android.permission.POWER_SAVER";
     field public static final String PROVIDE_RESOLVER_RANKER_SERVICE = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
     field public static final String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
+    field public static final String PROVISION_DEMO_DEVICE = "android.permission.PROVISION_DEMO_DEVICE";
     field public static final String QUERY_ADMIN_POLICY = "android.permission.QUERY_ADMIN_POLICY";
     field public static final String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
     field public static final String QUERY_USERS = "android.permission.QUERY_USERS";
@@ -242,6 +244,7 @@
     field public static final String READ_APP_SPECIFIC_LOCALES = "android.permission.READ_APP_SPECIFIC_LOCALES";
     field public static final String READ_CARRIER_APP_INFO = "android.permission.READ_CARRIER_APP_INFO";
     field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS";
+    field public static final String READ_CLIPBOARD_IN_BACKGROUND = "android.permission.READ_CLIPBOARD_IN_BACKGROUND";
     field public static final String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS";
     field public static final String READ_DEVICE_CONFIG = "android.permission.READ_DEVICE_CONFIG";
     field public static final String READ_DREAM_STATE = "android.permission.READ_DREAM_STATE";
@@ -468,7 +471,6 @@
     method public boolean convertToTranslucent(android.app.Activity.TranslucentConversionListener, android.app.ActivityOptions);
     method @Deprecated public boolean isBackgroundVisibleBehind();
     method @Deprecated public void onBackgroundVisibleBehindChanged(boolean);
-    method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public void startActivityAsUser(@NonNull android.content.Intent, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
     method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public void startActivityForResultAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
     method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public void startActivityForResultAsUser(@NonNull android.content.Intent, int, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
     method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public void startActivityForResultAsUser(@NonNull android.content.Intent, @NonNull String, int, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
@@ -1101,7 +1103,7 @@
     method @RequiresPermission("android.permission.NOTIFY_PENDING_SYSTEM_UPDATE") public void notifyPendingSystemUpdate(long);
     method @RequiresPermission("android.permission.NOTIFY_PENDING_SYSTEM_UPDATE") public void notifyPendingSystemUpdate(long, boolean);
     method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public boolean packageHasActiveAdmins(String);
-    method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void provisionFullyManagedDevice(@NonNull android.app.admin.FullyManagedDeviceProvisioningParams) throws android.app.admin.ProvisioningException;
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, android.Manifest.permission.PROVISION_DEMO_DEVICE}) public void provisionFullyManagedDevice(@NonNull android.app.admin.FullyManagedDeviceProvisioningParams) throws android.app.admin.ProvisioningException;
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES) public void resetDrawables(@NonNull String[]);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES) public void resetStrings(@NonNull String[]);
     method @RequiresPermission(android.Manifest.permission.SEND_LOST_MODE_LOCATION_UPDATES) public void sendLostModeLocationUpdate(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
@@ -1127,7 +1129,7 @@
     field @RequiresPermission(android.Manifest.permission.LAUNCH_DEVICE_MANAGER_SETUP) public static final String ACTION_ROLE_HOLDER_PROVISION_MANAGED_PROFILE = "android.app.action.ROLE_HOLDER_PROVISION_MANAGED_PROFILE";
     field public static final String ACTION_SET_PROFILE_OWNER = "android.app.action.SET_PROFILE_OWNER";
     field @Deprecated public static final String ACTION_STATE_USER_SETUP_COMPLETE = "android.app.action.STATE_USER_SETUP_COMPLETE";
-    field @RequiresPermission(android.Manifest.permission.LAUNCH_DEVICE_MANAGER_SETUP) public static final String ACTION_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER = "android.app.action.UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER";
+    field @RequiresPermission(android.Manifest.permission.LAUNCH_DEVICE_MANAGER_SETUP) public static final String ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER = "android.app.action.UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER";
     field public static final String EXTRA_FORCE_UPDATE_ROLE_HOLDER = "android.app.extra.FORCE_UPDATE_ROLE_HOLDER";
     field public static final String EXTRA_LOST_MODE_LOCATION = "android.app.extra.LOST_MODE_LOCATION";
     field public static final String EXTRA_PROFILE_OWNER_NAME = "android.app.extra.PROFILE_OWNER_NAME";
@@ -1160,8 +1162,8 @@
     field public static final String REQUIRED_APP_MANAGED_PROFILE = "android.app.REQUIRED_APP_MANAGED_PROFILE";
     field public static final String REQUIRED_APP_MANAGED_USER = "android.app.REQUIRED_APP_MANAGED_USER";
     field public static final int RESULT_DEVICE_OWNER_SET = 123; // 0x7b
-    field public static final int RESULT_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR = 1; // 0x1
-    field public static final int RESULT_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR = 2; // 0x2
+    field public static final int RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR = 1; // 0x1
+    field public static final int RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR = 2; // 0x2
     field public static final int RESULT_UPDATE_ROLE_HOLDER = 2; // 0x2
     field public static final int RESULT_WORK_PROFILE_CREATED = 122; // 0x7a
     field public static final int STATE_USER_PROFILE_COMPLETE = 4; // 0x4
@@ -1254,6 +1256,7 @@
     method @Nullable public java.util.Locale getLocale();
     method @NonNull public String getOwnerName();
     method @Nullable public String getTimeZone();
+    method public boolean isDemoDevice();
     method public boolean isLeaveAllSystemAppsEnabled();
     method public void writeToParcel(@NonNull android.os.Parcel, @Nullable int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.FullyManagedDeviceProvisioningParams> CREATOR;
@@ -1264,6 +1267,7 @@
     method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams build();
     method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setAdminExtras(@NonNull android.os.PersistableBundle);
     method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setCanDeviceOwnerGrantSensorsPermissions(boolean);
+    method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setDemoDevice(boolean);
     method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setLeaveAllSystemAppsEnabled(boolean);
     method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setLocalTime(long);
     method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setLocale(@Nullable java.util.Locale);
@@ -1647,13 +1651,13 @@
 
   public final class SearchRequest implements android.os.Parcelable {
     method public int describeContents();
+    method @NonNull public String getCallerPackageName();
     method public float getMaxLatencyMillis();
     method @NonNull public String getQuery();
     method @NonNull public String getRequestId();
     method public int getResultNumber();
     method public int getResultOffset();
     method @NonNull public android.os.Bundle getSearchConstraints();
-    method @NonNull public String getSource();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field public static final String CONSTRAINT_IS_PRESUBMIT_SUGGESTION = "android.app.cloudsearch.IS_PRESUBMIT_SUGGESTION";
     field public static final String CONSTRAINT_SEARCH_PROVIDER_FILTER = "android.app.cloudsearch.SEARCH_PROVIDER_FILTER";
@@ -1698,8 +1702,10 @@
     method @NonNull public String getTitle();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.cloudsearch.SearchResult> CREATOR;
+    field public static final String EXTRAINFO_ACTION_APP_CARD = "android.app.cloudsearch.ACTION_APP_CARD";
     field public static final String EXTRAINFO_ACTION_BUTTON_IMAGE_PREREGISTERING = "android.app.cloudsearch.ACTION_BUTTON_IMAGE";
     field public static final String EXTRAINFO_ACTION_BUTTON_TEXT_PREREGISTERING = "android.app.cloudsearch.ACTION_BUTTON_TEXT";
+    field public static final String EXTRAINFO_ACTION_INSTALL_BUTTON = "android.app.cloudsearch.ACTION_INSTALL_BUTTON";
     field public static final String EXTRAINFO_APP_BADGES = "android.app.cloudsearch.APP_BADGES";
     field public static final String EXTRAINFO_APP_CONTAINS_ADS_DISCLAIMER = "android.app.cloudsearch.APP_CONTAINS_ADS_DISCLAIMER";
     field public static final String EXTRAINFO_APP_CONTAINS_IAP_DISCLAIMER = "android.app.cloudsearch.APP_CONTAINS_IAP_DISCLAIMER";
@@ -1707,6 +1713,8 @@
     field public static final String EXTRAINFO_APP_DOMAIN_URL = "android.app.cloudsearch.APP_DOMAIN_URL";
     field public static final String EXTRAINFO_APP_IARC = "android.app.cloudsearch.APP_IARC";
     field public static final String EXTRAINFO_APP_ICON = "android.app.cloudsearch.APP_ICON";
+    field public static final String EXTRAINFO_APP_INSTALL_COUNT = "android.app.cloudsearch.APP_INSTALL_COUNT";
+    field public static final String EXTRAINFO_APP_PACKAGE_NAME = "android.app.cloudsearch.APP_PACKAGE_NAME";
     field public static final String EXTRAINFO_APP_REVIEW_COUNT = "android.app.cloudsearch.APP_REVIEW_COUNT";
     field public static final String EXTRAINFO_APP_SIZE_BYTES = "android.app.cloudsearch.APP_SIZE_BYTES";
     field public static final String EXTRAINFO_APP_STAR_RATING = "android.app.cloudsearch.APP_STAR_RATING";
@@ -2945,6 +2953,7 @@
     method public void sendBroadcastMultiplePermissions(@NonNull android.content.Intent, @NonNull String[], @Nullable android.app.BroadcastOptions);
     method public abstract void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable android.os.Bundle, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
     method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.os.UserHandle);
+    method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
     field public static final String AMBIENT_CONTEXT_SERVICE = "ambient_context";
     field public static final String APP_HIBERNATION_SERVICE = "app_hibernation";
     field public static final String APP_INTEGRITY_SERVICE = "app_integrity";
@@ -3184,6 +3193,7 @@
   }
 
   public class CrossProfileApps {
+    method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, android.Manifest.permission.START_CROSS_PROFILE_ACTIVITIES}) public void startActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle, @Nullable android.app.Activity, @Nullable android.os.Bundle);
     method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, android.Manifest.permission.START_CROSS_PROFILE_ACTIVITIES}) public void startActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
   }
 
@@ -6943,7 +6953,7 @@
   }
 
   public class Lnb implements java.lang.AutoCloseable {
-    method public void addCallback(@NonNull android.media.tv.tuner.LnbCallback, @NonNull java.util.concurrent.Executor);
+    method public void addCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.tv.tuner.LnbCallback);
     method public void close();
     method public boolean removeCallback(@NonNull android.media.tv.tuner.LnbCallback);
     method public int sendDiseqcMessage(@NonNull byte[]);
@@ -8518,45 +8528,6 @@
 
 package android.net {
 
-  public class EthernetManager {
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) public void connectNetwork(@NonNull String, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.BiConsumer<android.net.Network,android.net.EthernetNetworkManagementException>);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) public void disconnectNetwork(@NonNull String, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.BiConsumer<android.net.Network,android.net.EthernetNetworkManagementException>);
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) public void updateConfiguration(@NonNull String, @NonNull android.net.EthernetNetworkUpdateRequest, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.BiConsumer<android.net.Network,android.net.EthernetNetworkManagementException>);
-  }
-
-  public static interface EthernetManager.TetheredInterfaceCallback {
-    method public void onAvailable(@NonNull String);
-    method public void onUnavailable();
-  }
-
-  public static class EthernetManager.TetheredInterfaceRequest {
-    method public void release();
-  }
-
-  public final class EthernetNetworkManagementException extends java.lang.RuntimeException implements android.os.Parcelable {
-    ctor public EthernetNetworkManagementException(@NonNull String);
-    method public int describeContents();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkManagementException> CREATOR;
-  }
-
-  public final class EthernetNetworkUpdateRequest implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public android.net.IpConfiguration getIpConfiguration();
-    method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkUpdateRequest> CREATOR;
-  }
-
-  public static final class EthernetNetworkUpdateRequest.Builder {
-    ctor public EthernetNetworkUpdateRequest.Builder();
-    ctor public EthernetNetworkUpdateRequest.Builder(@NonNull android.net.EthernetNetworkUpdateRequest);
-    method @NonNull public android.net.EthernetNetworkUpdateRequest build();
-    method @NonNull public android.net.EthernetNetworkUpdateRequest.Builder setIpConfiguration(@NonNull android.net.IpConfiguration);
-    method @NonNull public android.net.EthernetNetworkUpdateRequest.Builder setNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
-  }
-
   public final class MatchAllNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
     ctor public MatchAllNetworkSpecifier();
     method public int describeContents();
@@ -9027,6 +8998,7 @@
     method public void enableVerboseLogging(boolean);
     method @NonNull public int[] getChannelsMhzForBand(int);
     method @Nullable public android.net.wifi.nl80211.DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String);
+    method public int getMaxSsidsPerScan(@NonNull String);
     method @NonNull public java.util.List<android.net.wifi.nl80211.NativeScanResult> getScanResults(@NonNull String, int);
     method @Nullable public android.net.wifi.nl80211.WifiNl80211Manager.TxPacketCounters getTxPacketCounters(@NonNull String);
     method public void notifyCountryCodeChanged(@Nullable String);
@@ -9816,11 +9788,12 @@
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean hasUserRestrictionForUser(@NonNull String, @NonNull android.os.UserHandle);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isAdminUser();
     method public boolean isCloneProfile();
-    method public boolean isCredentialSharedWithParent();
+    method public boolean isCredentialSharableWithParent();
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isGuestUser();
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isManagedProfile(int);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isMediaSharedWithParent();
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isPrimaryUser();
+    method public static boolean isRemoveResultSuccessful(int);
     method public boolean isRestrictedProfile();
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional=true) public boolean isRestrictedProfile(@NonNull android.os.UserHandle);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isSameProfileGroup(@NonNull android.os.UserHandle, @NonNull android.os.UserHandle);
@@ -9838,7 +9811,10 @@
     field public static final String DISALLOW_RUN_IN_BACKGROUND = "no_run_in_background";
     field public static final int REMOVE_RESULT_ALREADY_BEING_REMOVED = 2; // 0x2
     field public static final int REMOVE_RESULT_DEFERRED = 1; // 0x1
-    field public static final int REMOVE_RESULT_ERROR = 3; // 0x3
+    field public static final int REMOVE_RESULT_ERROR_SYSTEM_USER = -4; // 0xfffffffc
+    field public static final int REMOVE_RESULT_ERROR_UNKNOWN = -1; // 0xffffffff
+    field public static final int REMOVE_RESULT_ERROR_USER_NOT_FOUND = -3; // 0xfffffffd
+    field public static final int REMOVE_RESULT_ERROR_USER_RESTRICTION = -2; // 0xfffffffe
     field public static final int REMOVE_RESULT_REMOVED = 0; // 0x0
     field public static final int RESTRICTION_NOT_SET = 0; // 0x0
     field public static final int RESTRICTION_SOURCE_DEVICE_OWNER = 2; // 0x2
@@ -10328,6 +10304,7 @@
     field public static final String NAMESPACE_MEDIA_NATIVE = "media_native";
     field public static final String NAMESPACE_NETD_NATIVE = "netd_native";
     field public static final String NAMESPACE_NNAPI_NATIVE = "nnapi_native";
+    field public static final String NAMESPACE_ON_DEVICE_PERSONALIZATION = "on_device_personalization";
     field public static final String NAMESPACE_OTA = "ota";
     field public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";
     field public static final String NAMESPACE_PERMISSIONS = "permissions";
@@ -10577,7 +10554,6 @@
     field public static final String AUTO_REVOKE_DISABLED = "auto_revoke_disabled";
     field public static final String COMPLETED_CATEGORY_PREFIX = "suggested.completed_category.";
     field public static final String DOZE_ALWAYS_ON = "doze_always_on";
-    field public static final String FAST_PAIR_SCAN_ENABLED = "fast_pair_scan_enabled";
     field public static final String HUSH_GESTURE_USED = "hush_gesture_used";
     field public static final String INSTANT_APPS_ENABLED = "instant_apps_enabled";
     field public static final String LAST_SETUP_SHOWN = "last_setup_shown";
@@ -11402,7 +11378,7 @@
 
   public static interface GameSession.ScreenshotCallback {
     method public void onFailure(int);
-    method public void onSuccess(@NonNull android.graphics.Bitmap);
+    method public void onSuccess();
     field public static final int ERROR_TAKE_SCREENSHOT_INTERNAL_ERROR = 0; // 0x0
   }
 
@@ -12214,7 +12190,6 @@
 
   public abstract class ConnectionService extends android.app.Service {
     method public final void addExistingConnection(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.Connection, @NonNull android.telecom.Conference);
-    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telecom.Connection onCreateUnknownConnection(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
   }
 
   public abstract class InCallService extends android.app.Service {
@@ -13372,7 +13347,7 @@
   }
 
   public class TelephonyManager {
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void addCarrierPrivilegesListener(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CarrierPrivilegesListener);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void addCarrierPrivilegesListener(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CarrierPrivilegesListener);
     method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) @WorkerThread public void bootstrapAuthenticationRequest(int, @NonNull android.net.Uri, @NonNull android.telephony.gba.UaSecurityProtocolIdentifier, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.BootstrapAuthenticationCallback);
     method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult changeIccLockPin(@NonNull String, @NonNull String);
@@ -13472,7 +13447,8 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyOtaEmergencyNumberDbInstalled();
     method @RequiresPermission(android.Manifest.permission.REBOOT) public int prepareForUnattendedReboot();
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void removeCarrierPrivilegesListener(@NonNull android.telephony.TelephonyManager.CarrierPrivilegesListener);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerCarrierPrivilegesCallback(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CarrierPrivilegesCallback);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void removeCarrierPrivilegesListener(@NonNull android.telephony.TelephonyManager.CarrierPrivilegesListener);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean);
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestModemActivityInfo(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.ModemActivityInfo,android.telephony.TelephonyManager.ModemActivityInfoException>);
@@ -13522,6 +13498,7 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterCarrierPrivilegesCallback(@NonNull android.telephony.TelephonyManager.CarrierPrivilegesCallback);
     method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor);
     method public void updateServiceLocation();
     field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED";
@@ -13627,8 +13604,13 @@
     field public static final int RESULT_SUCCESS = 0; // 0x0
   }
 
-  public static interface TelephonyManager.CarrierPrivilegesListener {
-    method public void onCarrierPrivilegesChanged(@NonNull java.util.List<java.lang.String>, @NonNull int[]);
+  public static interface TelephonyManager.CarrierPrivilegesCallback {
+    method public void onCarrierPrivilegesChanged(@NonNull java.util.Set<java.lang.String>, @NonNull java.util.Set<java.lang.Integer>);
+    method public default void onCarrierServiceChanged(@Nullable String, int);
+  }
+
+  @Deprecated public static interface TelephonyManager.CarrierPrivilegesListener {
+    method @Deprecated public void onCarrierPrivilegesChanged(@NonNull java.util.List<java.lang.String>, @NonNull int[]);
   }
 
   public static class TelephonyManager.ModemActivityInfoException extends java.lang.Exception {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 1b627b2..db95a1f 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -19,6 +19,7 @@
     field public static final String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES";
     field public static final String INSTALL_TEST_ONLY_PACKAGE = "android.permission.INSTALL_TEST_ONLY_PACKAGE";
     field public static final String KEEP_UNINSTALLED_PACKAGES = "android.permission.KEEP_UNINSTALLED_PACKAGES";
+    field public static final String MAKE_UID_VISIBLE = "android.permission.MAKE_UID_VISIBLE";
     field @Deprecated public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
     field public static final String MANAGE_ACTIVITY_TASKS = "android.permission.MANAGE_ACTIVITY_TASKS";
     field public static final String MANAGE_CRATES = "android.permission.MANAGE_CRATES";
@@ -95,8 +96,7 @@
 package android.animation {
 
   public class ValueAnimator extends android.animation.Animator {
-    method public static float getDurationScale();
-    method public static void setDurationScale(float);
+    method @MainThread public static void setDurationScale(@FloatRange(from=0) float);
   }
 
 }
@@ -154,7 +154,6 @@
   }
 
   public class ActivityOptions {
-    method @NonNull public static android.app.ActivityOptions fromBundle(@NonNull android.os.Bundle);
     method public boolean isEligibleForLegacyPermissionPrompt();
     method @NonNull public static android.app.ActivityOptions makeCustomAnimation(@NonNull android.content.Context, int, int, int, @Nullable android.os.Handler, @Nullable android.app.ActivityOptions.OnAnimationStartedListener, @Nullable android.app.ActivityOptions.OnAnimationFinishedListener);
     method @NonNull @RequiresPermission(android.Manifest.permission.START_TASKS_FROM_RECENTS) public static android.app.ActivityOptions makeCustomTaskAnimation(@NonNull android.content.Context, int, int, @Nullable android.os.Handler, @Nullable android.app.ActivityOptions.OnAnimationStartedListener, @Nullable android.app.ActivityOptions.OnAnimationFinishedListener);
@@ -374,16 +373,17 @@
   public class PropertyInvalidatedCache<Query, Result> {
     ctor public PropertyInvalidatedCache(int, @NonNull String, @NonNull String, @NonNull String, @NonNull android.app.PropertyInvalidatedCache.QueryHandler<Query,Result>);
     method @NonNull public static String createPropertyName(@NonNull String, @NonNull String);
-    method public final void disableForCurrentProcess();
+    method public void disableForCurrentProcess();
+    method public static void disableForCurrentProcess(@NonNull String);
     method public static void disableForTestMode();
     method public final void disableInstance();
     method public final void disableSystemWide();
     method public final void forgetDisableLocal();
     method public boolean getDisabledState();
-    method public final void invalidateCache();
+    method public void invalidateCache();
     method public static void invalidateCache(@NonNull String, @NonNull String);
     method public final boolean isDisabled();
-    method @Nullable public final Result query(@NonNull Query);
+    method @Nullable public Result query(@NonNull Query);
     method public static void setTestMode(boolean);
     method public void testPropertyName();
     field public static final String MODULE_BLUETOOTH = "bluetooth";
@@ -422,9 +422,9 @@
     method @NonNull public android.content.res.Configuration getConfiguration();
     method public int getParentTaskId();
     method @Nullable public android.app.PictureInPictureParams getPictureInPictureParams();
-    method public boolean getPreferDockBigOverlays();
     method @NonNull public android.window.WindowContainerToken getToken();
     method public boolean hasParentTask();
+    method public boolean shouldDockBigOverlays();
   }
 
   public class TimePickerDialog extends android.app.AlertDialog implements android.content.DialogInterface.OnClickListener android.widget.TimePicker.OnTimeChangedListener {
@@ -622,7 +622,7 @@
 package android.app.cloudsearch {
 
   public static final class SearchRequest.Builder {
-    method @NonNull public android.app.cloudsearch.SearchRequest.Builder setSource(@NonNull String);
+    method @NonNull public android.app.cloudsearch.SearchRequest.Builder setCallerPackageName(@NonNull String);
   }
 
 }
@@ -836,6 +836,7 @@
     method @Nullable public String getSystemTextClassifierPackageName();
     method @Nullable public String getWellbeingPackageName();
     method public void holdLock(android.os.IBinder, int);
+    method @RequiresPermission(android.Manifest.permission.MAKE_UID_VISIBLE) public void makeUidVisible(int, int);
     method @RequiresPermission(android.Manifest.permission.KEEP_UNINSTALLED_PACKAGES) public void setKeepUninstalledPackages(@NonNull java.util.List<java.lang.String>);
     field public static final String FEATURE_ADOPTABLE_STORAGE = "android.software.adoptable_storage";
     field public static final String FEATURE_COMMUNAL_MODE = "android.software.communal_mode";
@@ -1466,6 +1467,7 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public android.media.AudioTrack getCallUplinkInjectionAudioTrack(@NonNull android.media.AudioFormat);
     method @Nullable public static android.media.AudioDeviceInfo getDeviceInfoFromType(int);
     method @IntRange(from=0) @RequiresPermission("android.permission.QUERY_AUDIO_STATE") public long getFadeOutDurationOnFocusLossMillis(@NonNull android.media.AudioAttributes);
+    method @Nullable public static String getHalVersion();
     method public static final int[] getPublicStreamTypes();
     method @NonNull public java.util.List<java.lang.Integer> getReportedSurroundFormats();
     method public int getStreamMinVolumeInt(int);
@@ -1726,6 +1728,19 @@
     method @NonNull public static byte[] digest(@NonNull java.io.InputStream, @NonNull String) throws java.io.IOException, java.security.NoSuchAlgorithmException;
   }
 
+  public class IpcDataCache<Query, Result> extends android.app.PropertyInvalidatedCache<Query,Result> {
+    ctor public IpcDataCache(int, @NonNull String, @NonNull String, @NonNull String, @NonNull android.os.IpcDataCache.QueryHandler<Query,Result>);
+    method public static void disableForCurrentProcess(@NonNull String);
+    method public static void invalidateCache(@NonNull String, @NonNull String);
+    field public static final String MODULE_BLUETOOTH = "bluetooth";
+    field public static final String MODULE_SYSTEM = "system_server";
+    field public static final String MODULE_TEST = "test";
+  }
+
+  public abstract static class IpcDataCache.QueryHandler<Q, R> extends android.app.PropertyInvalidatedCache.QueryHandler<Q,R> {
+    ctor public IpcDataCache.QueryHandler();
+  }
+
   public final class MessageQueue {
     method public int postSyncBarrier();
     method public void removeSyncBarrier(int);
@@ -1777,9 +1792,9 @@
   }
 
   public class Process {
+    method public static final int getAppUidForSdkSandboxUid(int);
     method public static final int getThreadScheduler(int) throws java.lang.IllegalArgumentException;
     method public static final boolean isSdkSandboxUid(int);
-    method public static final int sdkSandboxToAppUid(int);
     method public static final int toSdkSandboxUid(int);
     field public static final int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000; // 0x15f90
     field public static final int FIRST_ISOLATED_UID = 99000; // 0x182b8
@@ -1787,6 +1802,7 @@
     field public static final int LAST_ISOLATED_UID = 99999; // 0x1869f
     field public static final int NFC_UID = 1027; // 0x403
     field public static final int NUM_UIDS_PER_APP_ZYGOTE = 100; // 0x64
+    field public static final int SDK_SANDBOX_VIRTUAL_UID = 1090; // 0x442
   }
 
   public final class StrictMode {
@@ -2163,6 +2179,7 @@
     field @Deprecated public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
     field public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices";
     field public static final String SHOW_FIRST_CRASH_DIALOG = "show_first_crash_dialog";
+    field public static final String STYLUS_HANDWRITING_ENABLED = "stylus_handwriting_enabled";
     field public static final String USER_DISABLED_HDR_FORMATS = "user_disabled_hdr_formats";
     field public static final String USER_PREFERRED_REFRESH_RATE = "user_preferred_refresh_rate";
     field public static final String USER_PREFERRED_RESOLUTION_HEIGHT = "user_preferred_resolution_height";
@@ -2876,6 +2893,7 @@
     method public static int getHoverTooltipHideTimeout();
     method public static int getHoverTooltipShowTimeout();
     method public static int getLongPressTooltipHideTimeout();
+    method public int getPreferKeepClearForFocusDelay();
   }
 
   public class ViewDebug {
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index c82f5f6..3cb04e7 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -825,17 +825,7 @@
             for (int i = 0; i < mMagnificationControllers.size(); i++) {
                 mMagnificationControllers.valueAt(i).onServiceConnectedLocked();
             }
-            AccessibilityServiceInfo info = getServiceInfo();
-            if (info != null) {
-                boolean requestIme = (info.flags
-                        & AccessibilityServiceInfo.FLAG_INPUT_METHOD_EDITOR) != 0;
-                if (requestIme && !mInputMethodInitialized) {
-                    mInputMethod = onCreateInputMethod();
-                    mInputMethodInitialized = true;
-                }
-            } else {
-                Log.e(LOG_TAG, "AccessibilityServiceInfo is null in dispatchServiceConnected");
-            }
+            updateInputMethod(getServiceInfo());
         }
         if (mSoftKeyboardController != null) {
             mSoftKeyboardController.onServiceConnected();
@@ -846,6 +836,20 @@
         onServiceConnected();
     }
 
+    private void updateInputMethod(AccessibilityServiceInfo info) {
+        if (info != null) {
+            boolean requestIme = (info.flags
+                    & AccessibilityServiceInfo.FLAG_INPUT_METHOD_EDITOR) != 0;
+            if (requestIme && !mInputMethodInitialized) {
+                mInputMethod = onCreateInputMethod();
+                mInputMethodInitialized = true;
+            } else if (!requestIme & mInputMethodInitialized) {
+                mInputMethod = null;
+                mInputMethodInitialized = false;
+            }
+        }
+    }
+
     /**
      * This method is a part of the {@link AccessibilityService} lifecycle and is
      * called after the system has successfully bound to the service. If is
@@ -2521,6 +2525,7 @@
      */
     public final void setServiceInfo(AccessibilityServiceInfo info) {
         mInfo = info;
+        updateInputMethod(info);
         sendServiceInfo();
     }
 
diff --git a/core/java/android/accessibilityservice/InputMethod.java b/core/java/android/accessibilityservice/InputMethod.java
index 001d804..36cfd0e 100644
--- a/core/java/android/accessibilityservice/InputMethod.java
+++ b/core/java/android/accessibilityservice/InputMethod.java
@@ -67,7 +67,7 @@
     private InputConnection mStartedInputConnection;
     private EditorInfo mInputEditorInfo;
 
-    protected InputMethod(@NonNull AccessibilityService service) {
+    public InputMethod(@NonNull AccessibilityService service) {
         mService = service;
     }
 
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 06b424b..6ab7ae6 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -17,7 +17,9 @@
 package android.animation;
 
 import android.annotation.CallSuper;
+import android.annotation.FloatRange;
 import android.annotation.IntDef;
+import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
@@ -35,8 +37,10 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 
 /**
  * This class provides a simple timing engine for running animations
@@ -91,6 +95,9 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private static float sDurationScale = 1.0f;
 
+    private static final ArrayList<WeakReference<DurationScaleChangeListener>>
+            sDurationScaleChangeListeners = new ArrayList<>();
+
     /**
      * Internal variables
      * NOTE: This object implements the clone() method, making a deep copy of any referenced
@@ -308,20 +315,92 @@
      */
     @UnsupportedAppUsage
     @TestApi
-    public static void setDurationScale(float durationScale) {
+    @MainThread
+    public static void setDurationScale(@FloatRange(from = 0) float durationScale) {
         sDurationScale = durationScale;
+        List<WeakReference<DurationScaleChangeListener>> listenerCopy;
+
+        synchronized (sDurationScaleChangeListeners) {
+            listenerCopy = new ArrayList<>(sDurationScaleChangeListeners);
+        }
+
+        for (WeakReference<DurationScaleChangeListener> listenerRef : listenerCopy) {
+            final DurationScaleChangeListener listener = listenerRef.get();
+            if (listener != null) {
+                listener.onChanged(durationScale);
+            }
+        }
     }
 
     /**
-     * @hide
+     * Returns the system-wide scaling factor for Animator-based animations.
+     *
+     * This affects both the start delay and duration of all such animations. Setting to 0 will
+     * cause animations to end immediately. The default value is 1.0f.
+     *
+     * @return the duration scale.
      */
-    @UnsupportedAppUsage
-    @TestApi
+    @FloatRange(from = 0)
     public static float getDurationScale() {
         return sDurationScale;
     }
 
     /**
+     * Registers a {@link DurationScaleChangeListener}
+     *
+     * This listens for changes to the system-wide scaling factor for Animator-based animations.
+     * Listeners will be called on the main thread.
+     *
+     * @param listener the listener to register.
+     * @return true if the listener was registered.
+     */
+    public static boolean registerDurationScaleChangeListener(
+            @NonNull DurationScaleChangeListener listener) {
+        int posToReplace = -1;
+        synchronized (sDurationScaleChangeListeners) {
+            for (int i = 0; i < sDurationScaleChangeListeners.size(); i++) {
+                final WeakReference<DurationScaleChangeListener> ref =
+                        sDurationScaleChangeListeners.get(i);
+                if (ref.get() == null) {
+                    if (posToReplace == -1) {
+                        posToReplace = i;
+                    }
+                } else if (ref.get() == listener) {
+                    return false;
+                }
+            }
+            if (posToReplace != -1) {
+                sDurationScaleChangeListeners.set(posToReplace, new WeakReference<>(listener));
+                return true;
+            } else {
+                return sDurationScaleChangeListeners.add(new WeakReference<>(listener));
+            }
+        }
+    }
+
+    /**
+     * Unregisters a DurationScaleChangeListener.
+     *
+     * @see #registerDurationScaleChangeListener(DurationScaleChangeListener)
+     * @param listener the listener to unregister.
+     * @return true if the listener was unregistered.
+     */
+    public static boolean unregisterDurationScaleChangeListener(
+            @NonNull DurationScaleChangeListener listener) {
+        synchronized (sDurationScaleChangeListeners) {
+            WeakReference<DurationScaleChangeListener> listenerRefToRemove = null;
+            for (WeakReference<DurationScaleChangeListener> listenerRef :
+                    sDurationScaleChangeListeners) {
+                if (listenerRef.get() == listener) {
+                    listenerRefToRemove = listenerRef;
+                    break;
+                }
+            }
+            return sDurationScaleChangeListeners.remove(listenerRefToRemove);
+        }
+    }
+
+    /**
      * Returns whether animators are currently enabled, system-wide. By default, all
      * animators are enabled. This can change if either the user sets a Developer Option
      * to set the animator duration scale to 0 or by Battery Savery mode being enabled
@@ -1709,4 +1788,18 @@
     public void setAnimationHandler(@Nullable AnimationHandler animationHandler) {
         mAnimationHandler = animationHandler;
     }
+
+    /**
+     * Listener interface for the system-wide scaling factor for Animator-based animations.
+     *
+     * @see #registerDurationScaleChangeListener(DurationScaleChangeListener)
+     * @see #unregisterDurationScaleChangeListener(DurationScaleChangeListener)
+     */
+    public interface DurationScaleChangeListener {
+        /**
+         * Called when the duration scale changes.
+         * @param scale the duration scale
+         */
+        void onChanged(@FloatRange(from = 0) float scale);
+    }
 }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 8f348a4..ec9bb26 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -984,6 +984,8 @@
     private boolean mIsInMultiWindowMode;
     private boolean mIsInPictureInPictureMode;
 
+    private boolean mShouldDockBigOverlays;
+
     private UiTranslationController mUiTranslationController;
 
     private SplashScreen mSplashScreen;
@@ -2977,13 +2979,28 @@
      * <p> If specified, the system will try to respect the preference, but it may be
      * overridden by a user preference.
      *
-     * @param preferDockBigOverlays indicates that the activity prefers big overlays to be
-     *                              docked next to it instead of overlaying its content
+     * @param shouldDockBigOverlays indicates that big overlays should be docked next to the
+     *                              activity instead of overlay its content
      *
      * @see PictureInPictureParams.Builder#setExpandedAspectRatio
+     * @see #shouldDockBigOverlays
      */
-    public void setPreferDockBigOverlays(boolean preferDockBigOverlays) {
-        ActivityClient.getInstance().setPreferDockBigOverlays(mToken, preferDockBigOverlays);
+    public void setShouldDockBigOverlays(boolean shouldDockBigOverlays) {
+        ActivityClient.getInstance().setShouldDockBigOverlays(mToken, shouldDockBigOverlays);
+        mShouldDockBigOverlays = shouldDockBigOverlays;
+    }
+
+    /**
+     * Returns whether big overlays should be docked next to the activity as set by
+     * {@link #setShouldDockBigOverlays}.
+     *
+     * @return {@code true} if big overlays should be docked next to the activity instead
+     *         of overlay its content
+     *
+     * @see #setShouldDockBigOverlays
+     */
+    public boolean shouldDockBigOverlays() {
+        return mShouldDockBigOverlays;
     }
 
     void dispatchMovedToDisplay(int displayId, Configuration config) {
@@ -5663,7 +5680,6 @@
      * @throws ActivityNotFoundException &nbsp;
      * @hide
      */
-    @SystemApi
     @RequiresPermission(anyOf = {INTERACT_ACROSS_USERS, INTERACT_ACROSS_USERS_FULL})
     public void startActivityAsUser(@NonNull Intent intent,
             @Nullable Bundle options, @NonNull UserHandle user) {
@@ -8249,6 +8265,7 @@
                 .getWindowingMode();
         mIsInMultiWindowMode = inMultiWindowMode(windowingMode);
         mIsInPictureInPictureMode = windowingMode == WINDOWING_MODE_PINNED;
+        mShouldDockBigOverlays = getResources().getBoolean(R.bool.config_dockBigOverlayWindows);
         restoreHasCurrentPermissionRequest(icicle);
         if (persistentState != null) {
             onCreate(icicle, persistentState);
diff --git a/core/java/android/app/ActivityClient.java b/core/java/android/app/ActivityClient.java
index cf8480c..7b7b1ef 100644
--- a/core/java/android/app/ActivityClient.java
+++ b/core/java/android/app/ActivityClient.java
@@ -324,9 +324,9 @@
         }
     }
 
-    void setPreferDockBigOverlays(IBinder token, boolean preferDockBigOverlays) {
+    void setShouldDockBigOverlays(IBinder token, boolean shouldDockBigOverlays) {
         try {
-            getActivityClientController().setPreferDockBigOverlays(token, preferDockBigOverlays);
+            getActivityClientController().setShouldDockBigOverlays(token, shouldDockBigOverlays);
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 87ac6cb..0178fa1 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -1421,17 +1421,9 @@
         return mRemoteTransition;
     }
 
-    /**
-     * Creates an ActivityOptions from the Bundle generated from {@link ActivityOptions#toBundle()}.
-     * Returns an instance of ActivityOptions populated with options with known keys from the
-     * provided Bundle, stripping out unknown entries.
-     * @hide
-     */
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    @TestApi
-    @NonNull
-    public static ActivityOptions fromBundle(@NonNull Bundle bOptions) {
-        return new ActivityOptions(bOptions);
+    /** @hide */
+    public static ActivityOptions fromBundle(Bundle bOptions) {
+        return bOptions != null ? new ActivityOptions(bOptions) : null;
     }
 
     /** @hide */
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 64f0301..3d0ed20 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -868,6 +868,7 @@
         String processName;
         @UnsupportedAppUsage
         ApplicationInfo appInfo;
+        String sdkSandboxClientAppPackage;
         @UnsupportedAppUsage
         List<ProviderInfo> providers;
         ComponentName instrumentationName;
@@ -1113,9 +1114,9 @@
 
         @Override
         public final void bindApplication(String processName, ApplicationInfo appInfo,
-                ProviderInfoList providerList, ComponentName instrumentationName,
-                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
-                IInstrumentationWatcher instrumentationWatcher,
+                String sdkSandboxClientAppPackage, ProviderInfoList providerList,
+                ComponentName instrumentationName, ProfilerInfo profilerInfo,
+                Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
                 IUiAutomationConnection instrumentationUiConnection, int debugMode,
                 boolean enableBinderTracking, boolean trackAllocation,
                 boolean isRestrictedBackupMode, boolean persistent, Configuration config,
@@ -1155,6 +1156,7 @@
             AppBindData data = new AppBindData();
             data.processName = processName;
             data.appInfo = appInfo;
+            data.sdkSandboxClientAppPackage = sdkSandboxClientAppPackage;
             data.providers = providerList.getList();
             data.instrumentationName = instrumentationName;
             data.instrumentationArgs = instrumentationArgs;
@@ -3587,7 +3589,7 @@
         }
 
         try {
-            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
+            Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);
 
             if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
             if (localLOGV) Slog.v(
@@ -4286,7 +4288,7 @@
         BroadcastReceiver receiver;
         ContextImpl context;
         try {
-            app = packageInfo.makeApplication(false, mInstrumentation);
+            app = packageInfo.makeApplicationInner(false, mInstrumentation);
             context = (ContextImpl) app.getBaseContext();
             if (data.info.splitName != null) {
                 context = (ContextImpl) context.createContextForSplit(data.info.splitName);
@@ -4475,7 +4477,7 @@
         try {
             if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
 
-            Application app = packageInfo.makeApplication(false, mInstrumentation);
+            Application app = packageInfo.makeApplicationInner(false, mInstrumentation);
 
             final java.lang.ClassLoader cl;
             if (data.info.splitName != null) {
@@ -6536,6 +6538,9 @@
         }
 
         data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
+        if (data.sdkSandboxClientAppPackage != null) {
+            data.info.setSdkSandboxStorage(data.sdkSandboxClientAppPackage);
+        }
 
         if (agent != null) {
             handleAttachAgent(agent, data.info);
@@ -6695,7 +6700,7 @@
         try {
             // If the app is being launched for full backup or restore, bring it up in
             // a restricted environment with the base application class.
-            app = data.info.makeApplication(data.restrictedBackupMode, null);
+            app = data.info.makeApplicationInner(data.restrictedBackupMode, null);
 
             // Propagate autofill compat state
             app.setAutofillOptions(data.autofillOptions);
@@ -7565,7 +7570,7 @@
                 mInstrumentation.basicInit(this);
                 ContextImpl context = ContextImpl.createAppContext(
                         this, getSystemContext().mPackageInfo);
-                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
+                mInitialApplication = context.mPackageInfo.makeApplicationInner(true, null);
                 mInitialApplication.onCreate();
             } catch (Exception e) {
                 throw new RuntimeException(
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 7c7c7ef..4829dc0 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2367,7 +2367,7 @@
             null, // no permission for OP_WRITE_MEDIA_AUDIO
             Manifest.permission.READ_MEDIA_VIDEO,
             null, // no permission for OP_WRITE_MEDIA_VIDEO
-            Manifest.permission.READ_MEDIA_IMAGE,
+            Manifest.permission.READ_MEDIA_IMAGES,
             null, // no permission for OP_WRITE_MEDIA_IMAGES
             null, // no permission for OP_LEGACY_STORAGE
             null, // no permission for OP_ACCESS_ACCESSIBILITY
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
index 60e22f4..9bdddd0 100644
--- a/core/java/android/app/ApplicationExitInfo.java
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -360,6 +360,53 @@
      */
     public static final int SUBREASON_FREEZER_BINDER_TRANSACTION = 20;
 
+    /**
+     * The process was killed because of force-stop, it could be due to that
+     * the user clicked the "Force stop" button of the application in the Settings;
+     * this would be set only when the reason is {@link #REASON_USER_REQUESTED}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_FORCE_STOP = 21;
+
+    /**
+     * The process was killed because the user removed the application away from Recents;
+     * this would be set only when the reason is {@link #REASON_USER_REQUESTED}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_REMOVE_TASK = 22;
+
+    /**
+     * The process was killed because the user stopped the application from the task manager;
+     * this would be set only when the reason is {@link #REASON_USER_REQUESTED}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_STOP_APP = 23;
+
+    /**
+     * The process was killed because the user stopped the application from developer options,
+     * or via the adb shell commmand interface; this would be set only when the reason is
+     * {@link #REASON_USER_REQUESTED}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_KILL_BACKGROUND = 24;
+
+    /**
+     * The process was killed because of package update; this would be set only when the reason is
+     * {@link #REASON_USER_REQUESTED}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_PACKAGE_UPDATE = 25;
+
     // If there is any OEM code which involves additional app kill reasons, it should
     // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000.
 
@@ -520,6 +567,11 @@
         SUBREASON_ISOLATED_NOT_NEEDED,
         SUBREASON_FREEZER_BINDER_IOCTL,
         SUBREASON_FREEZER_BINDER_TRANSACTION,
+        SUBREASON_FORCE_STOP,
+        SUBREASON_REMOVE_TASK,
+        SUBREASON_STOP_APP,
+        SUBREASON_KILL_BACKGROUND,
+        SUBREASON_PACKAGE_UPDATE,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface SubReason {}
@@ -1193,6 +1245,16 @@
                 return "FREEZER BINDER IOCTL";
             case SUBREASON_FREEZER_BINDER_TRANSACTION:
                 return "FREEZER BINDER TRANSACTION";
+            case SUBREASON_FORCE_STOP:
+                return "FORCE STOP";
+            case SUBREASON_REMOVE_TASK:
+                return "REMOVE TASK";
+            case SUBREASON_STOP_APP:
+                return "STOP APP";
+            case SUBREASON_KILL_BACKGROUND:
+                return "KILL BACKGROUND";
+            case SUBREASON_PACKAGE_UPDATE:
+                return "PACKAGE UPDATE";
             default:
                 return "UNKNOWN";
         }
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index dca5c54..7ffa61b 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3832,4 +3832,13 @@
             throw re.rethrowAsRuntimeException();
         }
     }
+
+    @Override
+    public void makeUidVisible(int recipientUid, int visibleUid) {
+        try {
+            mPM.makeUidVisible(recipientUid, visibleUid);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
 }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index a3dd705a..f5eb1f6 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1998,7 +1998,7 @@
     private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
             String instanceName, Handler handler, Executor executor, UserHandle user) {
         // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser and
-        // ActivityManagerLocal.bindSupplementalProcessService
+        // ActivityManagerLocal.bindSdkSandboxService
         IServiceConnection sd;
         if (conn == null) {
             throw new IllegalArgumentException("connection is null");
diff --git a/core/java/android/app/IActivityClientController.aidl b/core/java/android/app/IActivityClientController.aidl
index caf1c41b7..1307161 100644
--- a/core/java/android/app/IActivityClientController.aidl
+++ b/core/java/android/app/IActivityClientController.aidl
@@ -88,7 +88,7 @@
 
     boolean enterPictureInPictureMode(in IBinder token, in PictureInPictureParams params);
     void setPictureInPictureParams(in IBinder token, in PictureInPictureParams params);
-    oneway void setPreferDockBigOverlays(in IBinder token, in boolean preferDockBigOverlays);
+    oneway void setShouldDockBigOverlays(in IBinder token, in boolean shouldDockBigOverlays);
     void toggleFreeformWindowingMode(in IBinder token);
 
     oneway void startLockTaskModeByToken(in IBinder token);
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 77657d5..f4fbcce 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -72,6 +72,7 @@
     @UnsupportedAppUsage
     void scheduleStopService(IBinder token);
     void bindApplication(in String packageName, in ApplicationInfo info,
+            in String sdkSandboxClientAppPackage,
             in ProviderInfoList providerList, in ComponentName testName,
             in ProfilerInfo profilerInfo, in Bundle testArguments,
             IInstrumentationWatcher testWatcher, IUiAutomationConnection uiAutomationConnection,
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index a82ecce..4fbe232 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -116,7 +116,7 @@
     ParceledListSlice getNotificationChannelGroups(String pkg);
     boolean onlyHasDefaultChannel(String pkg, int uid);
     boolean areChannelsBypassingDnd();
-    ParceledListSlice getNotificationChannelsBypassingDnd(String pkg, int userId);
+    ParceledListSlice getNotificationChannelsBypassingDnd(String pkg, int uid);
     boolean isPackagePaused(String pkg);
     void deleteNotificationHistoryItem(String pkg, int uid, long postedTime);
     boolean isPermissionFixed(String pkg, int userId);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index cf259e57..deefea8 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -37,6 +37,7 @@
 import android.content.res.Resources;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Environment;
 import android.os.FileUtils;
 import android.os.GraphicsEnvironment;
 import android.os.Handler;
@@ -411,6 +412,26 @@
         }
     }
 
+    /** @hide */
+    void setSdkSandboxStorage(String sdkSandboxClientAppPackage) {
+        int userId = UserHandle.myUserId();
+        mDeviceProtectedDataDirFile = Environment
+                .getDataMiscDeSharedSdkSandboxDirectory(userId, sdkSandboxClientAppPackage)
+                .getAbsoluteFile();
+        mCredentialProtectedDataDirFile = Environment
+                .getDataMiscCeSharedSdkSandboxDirectory(userId, sdkSandboxClientAppPackage)
+                .getAbsoluteFile();
+
+        if ((mApplicationInfo.privateFlags
+                & ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) != 0
+                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
+            mDataDirFile = mDeviceProtectedDataDirFile;
+        } else {
+            mDataDirFile = mCredentialProtectedDataDirFile;
+        }
+        mDataDir = mDataDirFile.getAbsolutePath();
+    }
+
     public static void makePaths(ActivityThread activityThread,
                                  ApplicationInfo aInfo,
                                  List<String> outZipPaths) {
@@ -1352,9 +1373,28 @@
         return mResources;
     }
 
+    /**
+     * This is for 3p apps accessing this hidden API directly... in which case, we don't return
+     * the cached Application instance.
+     */
     @UnsupportedAppUsage
     public Application makeApplication(boolean forceDefaultAppClass,
             Instrumentation instrumentation) {
+        return makeApplicationInner(forceDefaultAppClass, instrumentation,
+                /* allowDuplicateInstances= */ true);
+    }
+
+    /**
+     * This is for all the (internal) callers, for which we do return the cached instance.
+     */
+    public Application makeApplicationInner(boolean forceDefaultAppClass,
+            Instrumentation instrumentation) {
+        return makeApplicationInner(forceDefaultAppClass, instrumentation,
+                /* allowDuplicateInstances= */ false);
+    }
+
+    private Application makeApplicationInner(boolean forceDefaultAppClass,
+            Instrumentation instrumentation, boolean allowDuplicateInstances) {
         if (mApplication != null) {
             return mApplication;
         }
@@ -1366,11 +1406,15 @@
                 // Looks like this is always happening for the system server, because
                 // the LoadedApk created in systemMain() -> attach() isn't cached properly?
                 if (!"android".equals(mPackageName)) {
-                    Slog.wtf(TAG, "App instance already created for package=" + mPackageName
+                    Slog.wtfStack(TAG, "App instance already created for package=" + mPackageName
                             + " instance=" + cached);
                 }
-                mApplication = cached;
-                return cached;
+                if (!allowDuplicateInstances) {
+                    mApplication = cached;
+                    return cached;
+                }
+                // Some apps intentionally call makeApplication() to create a new Application
+                // instance... Sigh...
             }
         }
 
@@ -1421,8 +1465,10 @@
         }
         mActivityThread.mAllApplications.add(app);
         mApplication = app;
-        synchronized (sApplications) {
-            sApplications.put(mPackageName, app);
+        if (!allowDuplicateInstances) {
+            synchronized (sApplications) {
+                sApplications.put(mPackageName, app);
+            }
         }
 
         if (instrumentation != null) {
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 2f202d95..df7bf7b 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -18,7 +18,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.os.Handler;
 import android.os.Looper;
@@ -137,6 +136,26 @@
  * With this cache, clients perform a binder call to birthdayd if asking for a user's birthday
  * for the first time; on subsequent queries, we return the already-known Birthday object.
  *
+ * The second parameter to the IpcDataCache constructor is a string that identifies the "module"
+ * that owns the cache. There are some well-known modules (such as {@code MODULE_SYSTEM} but any
+ * string is permitted.  The third parameters is the name of the API being cached; this, too, can
+ * any value.  The fourth is the name of the cache.  The cache is usually named after th API.
+ * Some things you must know about the three strings:
+ * <list>
+ * <ul> The system property that controls the cache is named {@code cache_key.<module>.<api>}.
+ * Usually, the SELinux rules permit a process to write a system property (and therefore
+ * invalidate a cache) based on the wildcard {@code cache_key.<module>.*}.  This means that
+ * although the cache can be constructed with any module string, whatever string is chosen must be
+ * consistent with the SELinux configuration.
+ * <ul> The API name can be any string of alphanumeric characters.  All caches with the same API
+ * are invalidated at the same time.  If a server supports several caches and all are invalidated
+ * in common, then it is most efficient to assign the same API string to every cache.
+ * <ul> The cache name can be any string.  In debug output, the name is used to distiguish between
+ * caches with the same API name.  The cache name is also used when disabling caches in the
+ * current process.  So, invalidation is based on the module+api but disabling (which is generally
+ * a once-per-process operation) is based on the cache name.
+ * </list>
+ *
  * User birthdays do occasionally change, so we have to modify the server to invalidate this
  * cache when necessary. That invalidation code looks like this:
  *
@@ -192,25 +211,23 @@
  * <pre>
  * public class ActivityThread {
  *   ...
- *   private static final int BDAY_CACHE_MAX = 8;  // Maximum birthdays to cache
- *   private static final String BDAY_CACHE_KEY = "cache_key.birthdayd";
- *   private final PropertyInvalidatedCache&lt;Integer, Birthday%&gt; mBirthdayCache = new
- *     PropertyInvalidatedCache&lt;Integer, Birthday%&gt;(BDAY_CACHE_MAX, BDAY_CACHE_KEY) {
- *       {@literal @}Override
- *       protected Birthday recompute(Integer userId) {
- *         return GetService("birthdayd").getUserBirthday(userId);
- *       }
- *       {@literal @}Override
- *       protected boolean bypass(Integer userId) {
- *         return userId == NEXT_BIRTHDAY;
- *       }
- *     };
+ *   private final IpcDataCache.QueryHandler&lt;Integer, Birthday&gt; mBirthdayQuery =
+ *       new IpcDataCache.QueryHandler&lt;Integer, Birthday&gt;() {
+ *           {@literal @}Override
+ *           public Birthday apply(Integer) {
+ *              return GetService("birthdayd").getUserBirthday(userId);
+ *           }
+ *           {@literal @}Override
+ *           public boolean shouldBypassQuery(Integer userId) {
+ *               return userId == NEXT_BIRTHDAY;
+ *           }
+ *       };
  *   ...
  * }
  * </pre>
  *
- * If the {@code bypass()} method returns true then the cache is not used for that
- * particular query.  The {@code bypass()} method is not abstract and the default
+ * If the {@code shouldBypassQuery()} method returns true then the cache is not used for that
+ * particular query.  The {@code shouldBypassQuery()} method is not abstract and the default
  * implementation returns false.
  *
  * For security, there is a allowlist of processes that are allowed to invalidate a cache.
@@ -231,14 +248,12 @@
  * @param <Result> The class holding cache entries; use a boxed primitive if possible
  * @hide
  */
-@SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
 @TestApi
 public class PropertyInvalidatedCache<Query, Result> {
     /**
      * This is a configuration class that customizes a cache instance.
      * @hide
      */
-    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
     @TestApi
     public static abstract class QueryHandler<Q,R> {
         /**
@@ -285,7 +300,6 @@
      * The module used for bluetooth caches.
      * @hide
      */
-    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
     @TestApi
     public static final String MODULE_BLUETOOTH = "bluetooth";
 
@@ -533,7 +547,6 @@
      * @param computer The code to compute values that are not in the cache.
      * @hide
      */
-    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
     @TestApi
     public PropertyInvalidatedCache(int maxEntries, @NonNull String module, @NonNull String api,
             @NonNull String cacheName, @NonNull QueryHandler<Query, Result> computer) {
@@ -792,7 +805,7 @@
      * TODO(216112648) Remove this in favor of disableForCurrentProcess().
      * @hide
      */
-    public final void disableLocal() {
+    public void disableLocal() {
         disableForCurrentProcess();
     }
 
@@ -802,12 +815,17 @@
      * property.
      * @hide
      */
-    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
     @TestApi
-    public final void disableForCurrentProcess() {
+    public void disableForCurrentProcess() {
         disableLocal(mCacheName);
     }
 
+    /** @hide */
+    @TestApi
+    public static void disableForCurrentProcess(@NonNull String cacheName) {
+        disableLocal(cacheName);
+    }
+
     /**
      * Return whether a cache instance is disabled.
      * @hide
@@ -821,9 +839,8 @@
      * Get a value from the cache or recompute it.
      * @hide
      */
-    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
     @TestApi
-    public final @Nullable Result query(@NonNull Query query) {
+    public @Nullable Result query(@NonNull Query query) {
         // Let access to mDisabled race: it's atomic anyway.
         long currentNonce = (!isDisabled()) ? getCurrentNonce() : NONCE_DISABLED;
         if (bypass(query)) {
@@ -964,9 +981,8 @@
      * PropertyInvalidatedCache is keyed on a particular property value.
      * @hide
      */
-    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
     @TestApi
-    public final void invalidateCache() {
+    public void invalidateCache() {
         invalidateCache(mPropertyName);
     }
 
@@ -974,7 +990,6 @@
      * Invalidate caches in all processes that are keyed for the module and api.
      * @hide
      */
-    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
     @TestApi
     public static void invalidateCache(@NonNull String module, @NonNull String api) {
         invalidateCache(createPropertyName(module, api));
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index c6e36a3..150888c 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -24,6 +24,9 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
@@ -39,6 +42,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.util.Pair;
 import android.util.Slog;
 import android.view.View;
@@ -520,6 +524,27 @@
     private final Map<NearbyMediaDevicesProvider, NearbyMediaDevicesProviderWrapper>
             nearbyMediaDevicesProviderMap = new HashMap<>();
 
+    /**
+     * Media controls based on {@link android.app.Notification.MediaStyle} notifications will have
+     * actions based on the media session's {@link android.media.session.PlaybackState}, rather than
+     * the notification's actions.
+     *
+     * These actions will be:
+     * - Play/Pause (depending on whether the current state is a playing state)
+     * - Previous (if declared), or a custom action if the slot is not reserved with
+     *   {@code SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV}
+     * - Next (if declared), or a custom action if the slot is not reserved with
+     *   {@code SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT}
+     * - Custom action
+     * - Custom action
+     *
+     * @see androidx.media.utils.MediaConstants#SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV
+     * @see androidx.media.utils.MediaConstants#SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    private static final long MEDIA_CONTROL_SESSION_ACTIONS = 203800354L;
+
     @UnsupportedAppUsage
     private Context mContext;
     private IStatusBarService mService;
@@ -844,6 +869,24 @@
     }
 
     /**
+     * Sets an active {@link android.service.quicksettings.TileService} to listening state
+     *
+     * The {@code componentName}'s package must match the calling package.
+     *
+     * @param componentName the tile to set into listening state
+     * @see android.service.quicksettings.TileService#requestListeningState
+     * @hide
+     */
+    public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
+        Objects.requireNonNull(componentName);
+        try {
+            getService().requestTileServiceListeningState(componentName, mContext.getUserId());
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Request to the user to add a {@link android.service.quicksettings.TileService}
      * to the set of current QS tiles.
      * <p>
@@ -1109,6 +1152,20 @@
         }
     }
 
+    /**
+     * Checks whether the given package should use session-based actions for its media controls.
+     *
+     * @param packageName App posting media controls
+     * @param userId Current user ID
+     * @return true if the app supports session actions
+     *
+     * @hide
+     */
+    public static boolean useMediaSessionActionsForApp(String packageName, int userId) {
+        UserHandle handle = UserHandle.getUserHandleForUid(userId);
+        return CompatChanges.isChangeEnabled(MEDIA_CONTROL_SESSION_ACTIONS, packageName, handle);
+    }
+
     /** @hide */
     public static String windowStateToString(int state) {
         if (state == WINDOW_STATE_HIDING) return "WINDOW_STATE_HIDING";
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 58db93c..6615374 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -138,8 +138,6 @@
 import android.nearby.NearbyFrameworkInitializer;
 import android.net.ConnectivityFrameworkInitializer;
 import android.net.ConnectivityFrameworkInitializerTiramisu;
-import android.net.EthernetManager;
-import android.net.IEthernetManager;
 import android.net.INetworkPolicyManager;
 import android.net.IPacProxyManager;
 import android.net.IVpnManager;
@@ -156,6 +154,7 @@
 import android.net.wifi.WifiFrameworkInitializer;
 import android.net.wifi.nl80211.WifiNl80211Manager;
 import android.nfc.NfcManager;
+import android.ondevicepersonalization.OnDevicePersonalizationFrameworkInitializer;
 import android.os.BatteryManager;
 import android.os.BatteryStats;
 import android.os.BatteryStatsManager;
@@ -789,15 +788,6 @@
                 return new LowpanManager(ctx.getOuterContext(), service);
             }});
 
-        registerService(Context.ETHERNET_SERVICE, EthernetManager.class,
-                new CachedServiceFetcher<EthernetManager>() {
-            @Override
-            public EthernetManager createService(ContextImpl ctx) throws ServiceNotFoundException {
-                IBinder b = ServiceManager.getServiceOrThrow(Context.ETHERNET_SERVICE);
-                IEthernetManager service = IEthernetManager.Stub.asInterface(b);
-                return new EthernetManager(ctx.getOuterContext(), service);
-            }});
-
         registerService(Context.WIFI_NL80211_SERVICE, WifiNl80211Manager.class,
                 new CachedServiceFetcher<WifiNl80211Manager>() {
                     @Override
@@ -1571,6 +1561,7 @@
             SafetyCenterFrameworkInitializer.registerServiceWrappers();
             ConnectivityFrameworkInitializerTiramisu.registerServiceWrappers();
             NearbyFrameworkInitializer.registerServiceWrappers();
+            OnDevicePersonalizationFrameworkInitializer.registerServiceWrappers();
         } finally {
             // If any of the above code throws, we're in a pretty bad shape and the process
             // will likely crash, but we'll reset it just in case there's an exception handler...
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 5c7c73c..1a38fcf 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -188,7 +188,7 @@
     /**
      * @hide
      */
-    public boolean preferDockBigOverlays;
+    public boolean shouldDockBigOverlays;
 
     /**
      * The task id of the host Task of the launch-into-pip Activity, i.e., it points to the Task
@@ -392,8 +392,8 @@
 
     /** @hide */
     @TestApi
-    public boolean getPreferDockBigOverlays() {
-        return preferDockBigOverlays;
+    public boolean shouldDockBigOverlays() {
+        return shouldDockBigOverlays;
     }
 
     /** @hide */
@@ -465,7 +465,7 @@
                 && displayAreaFeatureId == that.displayAreaFeatureId
                 && Objects.equals(positionInParent, that.positionInParent)
                 && Objects.equals(pictureInPictureParams, that.pictureInPictureParams)
-                && Objects.equals(preferDockBigOverlays, that.preferDockBigOverlays)
+                && Objects.equals(shouldDockBigOverlays, that.shouldDockBigOverlays)
                 && Objects.equals(displayCutoutInsets, that.displayCutoutInsets)
                 && getWindowingMode() == that.getWindowingMode()
                 && Objects.equals(taskDescription, that.taskDescription)
@@ -522,7 +522,7 @@
         token = WindowContainerToken.CREATOR.createFromParcel(source);
         topActivityType = source.readInt();
         pictureInPictureParams = source.readTypedObject(PictureInPictureParams.CREATOR);
-        preferDockBigOverlays = source.readBoolean();
+        shouldDockBigOverlays = source.readBoolean();
         launchIntoPipHostTaskId = source.readInt();
         displayCutoutInsets = source.readTypedObject(Rect.CREATOR);
         topActivityInfo = source.readTypedObject(ActivityInfo.CREATOR);
@@ -569,7 +569,7 @@
         token.writeToParcel(dest, flags);
         dest.writeInt(topActivityType);
         dest.writeTypedObject(pictureInPictureParams, flags);
-        dest.writeBoolean(preferDockBigOverlays);
+        dest.writeBoolean(shouldDockBigOverlays);
         dest.writeInt(launchIntoPipHostTaskId);
         dest.writeTypedObject(displayCutoutInsets, flags);
         dest.writeTypedObject(topActivityInfo, flags);
@@ -610,7 +610,7 @@
                 + " token=" + token
                 + " topActivityType=" + topActivityType
                 + " pictureInPictureParams=" + pictureInPictureParams
-                + " preferDockBigOverlays=" + preferDockBigOverlays
+                + " shouldDockBigOverlays=" + shouldDockBigOverlays
                 + " launchIntoPipHostTaskId=" + launchIntoPipHostTaskId
                 + " displayCutoutSafeInsets=" + displayCutoutInsets
                 + " topActivityInfo=" + topActivityInfo
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index b436f6e..27fe312 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -16,6 +16,8 @@
 
 package android.app.admin;
 
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
+
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
 import android.Manifest.permission;
@@ -717,10 +719,11 @@
 
     /**
      * A {@code boolean} extra which determines whether to force a role holder update, regardless
-     * of any internal conditions {@link #ACTION_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER} might have.
+     * of any internal conditions {@link #ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER} might
+     * have.
      *
      * <p>This extra can be provided to intents with action {@link
-     * #ACTION_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER}.
+     * #ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER}.
      *
      * @hide
      */
@@ -1413,6 +1416,9 @@
      * admin app when performing the admin-integrated provisioning flow as a result of the
      * {@link #ACTION_GET_PROVISIONING_MODE} activity.
      *
+     * <p>This extra may also be provided to the admin app via an intent extra for {@link
+     * #ACTION_GET_PROVISIONING_MODE}.
+     *
      * @see #ACTION_GET_PROVISIONING_MODE
      */
     public static final String EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT =
@@ -3062,6 +3068,8 @@
      *     <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}</li>
      *     <li>{@link #EXTRA_PROVISIONING_IMEI}</li>
      *     <li>{@link #EXTRA_PROVISIONING_SERIAL_NUMBER}</li>
+     *     <li>{@link #EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES}</li>
+     *     <li>{@link #EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT}</li>
      * </ul>
      *
      * <p>The target activity should return one of the following values in
@@ -3085,8 +3093,22 @@
      * activity, along with the values of the {@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE} extra
      * that are already supplied to this activity.
      *
-     * @see #EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION
-     * @see #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED
+     * <p>Other extras the target activity may include in the intent result:
+     * <ul>
+     *     <li>{@link #EXTRA_PROVISIONING_DISCLAIMERS}</li>
+     *     <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}</li>
+     *     <li>{@link #EXTRA_PROVISIONING_KEEP_SCREEN_ON}</li>
+     *     <li>{@link #EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION} for work profile
+     *     provisioning</li>
+     *     <li>{@link #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED} for work profile
+     *     provisioning</li>
+     *     <li>{@link #EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT} for fully-managed
+     *     device provisioning</li>
+     *     <li>{@link #EXTRA_PROVISIONING_LOCALE} for fully-managed device provisioning</li>
+     *     <li>{@link #EXTRA_PROVISIONING_LOCAL_TIME} for fully-managed device provisioning</li>
+     *     <li>{@link #EXTRA_PROVISIONING_TIME_ZONE} for fully-managed device provisioning</li>
+     * </ul>
+     *
      * @see #ACTION_ADMIN_POLICY_COMPLIANCE
      */
     public static final String ACTION_GET_PROVISIONING_MODE =
@@ -3260,39 +3282,43 @@
      *
      * <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, {@link
-     * #RESULT_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR} if it encounters a problem
-     * that may be solved by relaunching it again, or {@link
-     * #RESULT_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR} if it encounters a problem
-     * that will not be solved by relaunching it again.
+     * #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR} if it encounters a
+     * problem that may be solved by relaunching it again, or {@link
+     * #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR} if it encounters a
+     * problem that will not be solved by relaunching it again.
      *
      * <p>If this activity has additional internal conditions which are not met, it should return
-     * {@link #RESULT_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR}.
+     * {@link #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR}.
      *
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.LAUNCH_DEVICE_MANAGER_SETUP)
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     @SystemApi
-    public static final String ACTION_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER =
-            "android.app.action.UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER";
+    public static final String ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER =
+            "android.app.action.UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER";
 
     /**
-     * Result code that can be returned by the {@link #ACTION_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER}
-     * handler if it encounters a problem that may be solved by relaunching it again.
+     * Result code that can be returned by the {@link
+     * #ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER} handler if it encounters a problem
+     * that may be solved by relaunching it again.
      *
      * @hide
      */
     @SystemApi
-    public static final int RESULT_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR = 1;
+    public static final int RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR =
+            1;
 
     /**
-     * Result code that can be returned by the {@link #ACTION_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER}
-     * handler if it encounters a problem that will not be solved by relaunching it again.
+     * Result code that can be returned by the {@link
+     * #ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER} handler if it encounters a problem that
+     * will not be solved by relaunching it again.
      *
      * @hide
      */
     @SystemApi
-    public static final int RESULT_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR = 2;
+    public static final int RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR =
+            2;
 
     /**
      * An {@link Intent} extra which resolves to a custom user consent screen.
@@ -11012,7 +11038,7 @@
     }
 
     /**
-     * Sets whether preferential network service is enabled on the work profile.
+     * Sets whether preferential network service is enabled.
      * For example, an organization can have a deal/agreement with a carrier that all of
      * the work data from its employees’ devices will be sent via a network service dedicated
      * for enterprise use.
@@ -11020,75 +11046,72 @@
      * An example of a supported preferential network service is the Enterprise
      * slice on 5G networks.
      *
-     * By default, preferential network service is disabled on the work profile on supported
-     * carriers and devices. Admins can explicitly enable it with this API.
-     * On fully-managed devices this method is unsupported because all traffic is considered
-     * work traffic.
+     * By default, preferential network service is disabled on the work profile and
+     * fully managed devices, on supported carriers and devices.
+     * Admins can explicitly enable it with this API.
      *
      * <p> This method enables preferential network service with a default configuration.
-     * To fine-tune the configuration, use {@link #setPreferentialNetworkServiceConfig) instead.
+     * To fine-tune the configuration, use {@link #setPreferentialNetworkServiceConfigs) instead.
+     * <p> Before Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}:
+     * this method can be called by the profile owner of a managed profile.
+     * <p> Starting from Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}:
+     * This method can be called by the profile owner of a managed profile
+     * or device owner.
      *
-     * <p>This method can only be called by the profile owner of a managed profile.
      * @param enabled whether preferential network service should be enabled.
-     * @throws SecurityException if the caller is not the profile owner.
+     * @throws SecurityException if the caller is not the profile owner or device owner.
      **/
     public void setPreferentialNetworkServiceEnabled(boolean enabled) {
         throwIfParentInstance("setPreferentialNetworkServiceEnabled");
-        if (mService == null) {
-            return;
+        PreferentialNetworkServiceConfig.Builder configBuilder =
+                new PreferentialNetworkServiceConfig.Builder();
+        configBuilder.setEnabled(enabled);
+        if (enabled) {
+            configBuilder.setNetworkId(NET_ENTERPRISE_ID_1);
         }
-
-        try {
-            mService.setPreferentialNetworkServiceEnabled(enabled);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        setPreferentialNetworkServiceConfigs(List.of(configBuilder.build()));
     }
 
     /**
      * Indicates whether preferential network service is enabled.
      *
-     * <p>This method can be called by the profile owner of a managed profile.
+     * <p> Before Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}:
+     * This method can be called by the profile owner of a managed profile.
+     * <p> Starting from Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}:
+     * This method can be called by the profile owner of a managed profile
+     * or device owner.
      *
      * @return whether preferential network service is enabled.
-     * @throws SecurityException if the caller is not the profile owner.
+     * @throws SecurityException if the caller is not the profile owner or device owner.
      */
     public boolean isPreferentialNetworkServiceEnabled() {
         throwIfParentInstance("isPreferentialNetworkServiceEnabled");
-        if (mService == null) {
-            return false;
-        }
-        try {
-            return mService.isPreferentialNetworkServiceEnabled(myUserId());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        return getPreferentialNetworkServiceConfigs().stream().anyMatch(c -> c.isEnabled());
     }
 
     /**
-     * Sets preferential network configuration on the work profile.
+     * Sets preferential network configurations.
      * {@see PreferentialNetworkServiceConfig}
      *
      * An example of a supported preferential network service is the Enterprise
      * slice on 5G networks.
      *
-     * By default, preferential network service is disabled on the work profile on supported
-     * carriers and devices. Admins can explicitly enable it with this API.
-     * On fully-managed devices this method is unsupported because all traffic is considered
-     * work traffic.
+     * By default, preferential network service is disabled on the work profile and fully managed
+     * devices, on supported carriers and devices. Admins can explicitly enable it with this API.
+     * If admin wants to have multiple enterprise slices,
+     * it can be configured by passing list of {@link PreferentialNetworkServiceConfig} objects.
      *
-     * <p>This method can only be called by the profile owner of a managed profile.
-     * @param preferentialNetworkServiceConfig preferential network configuration.
-     * @throws SecurityException if the caller is not the profile owner.
+     * @param preferentialNetworkServiceConfigs list of preferential network configurations.
+     * @throws SecurityException if the caller is not the profile owner or device owner.
      **/
-    public void setPreferentialNetworkServiceConfig(
-            @NonNull PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) {
-        throwIfParentInstance("setPreferentialNetworkServiceConfig");
+    public void setPreferentialNetworkServiceConfigs(
+            @NonNull List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs) {
+        throwIfParentInstance("setPreferentialNetworkServiceConfigs");
         if (mService == null) {
             return;
         }
         try {
-            mService.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfig);
+            mService.setPreferentialNetworkServiceConfigs(preferentialNetworkServiceConfigs);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -11098,18 +11121,16 @@
      * Get preferential network configuration
      * {@see PreferentialNetworkServiceConfig}
      *
-     * <p>This method can be called by the profile owner of a managed profile.
-     *
      * @return preferential network configuration.
-     * @throws SecurityException if the caller is not the profile owner.
+     * @throws SecurityException if the caller is not the profile owner or device owner.
      */
-    public @NonNull PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig() {
-        throwIfParentInstance("getPreferentialNetworkServiceConfig");
+    public @NonNull List<PreferentialNetworkServiceConfig> getPreferentialNetworkServiceConfigs() {
+        throwIfParentInstance("getPreferentialNetworkServiceConfigs");
         if (mService == null) {
-            return PreferentialNetworkServiceConfig.DEFAULT;
+            return List.of(PreferentialNetworkServiceConfig.DEFAULT);
         }
         try {
-            return mService.getPreferentialNetworkServiceConfig();
+            return mService.getPreferentialNetworkServiceConfigs();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -13593,13 +13614,18 @@
     }
 
     /**
-     * Called by device owner to add an override APN.
+     * Called by device owner or profile owner to add an override APN.
      *
      * <p>This method may returns {@code -1} if {@code apnSetting} conflicts with an existing
      * override APN. Update the existing conflicted APN with
      * {@link #updateOverrideApn(ComponentName, int, ApnSetting)} instead of adding a new entry.
      * <p>Two override APNs are considered to conflict when all the following APIs return
      * the same values on both override APNs:
+     * <p> Before Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}:
+     * Only device owners can add APNs.
+     * <p> Starting from Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}:
+     * Device and profile owners can add enterprise APNs
+     * ({@link ApnSetting#TYPE_ENTERPRISE}), while only device owners can add other type of APNs.
      * <ul>
      *   <li>{@link ApnSetting#getOperatorNumeric()}</li>
      *   <li>{@link ApnSetting#getApnName()}</li>
@@ -13618,7 +13644,8 @@
      * @param apnSetting the override APN to insert
      * @return The {@code id} of inserted override APN. Or {@code -1} when failed to insert into
      *         the database.
-     * @throws SecurityException if {@code admin} is not a device owner.
+     * @throws SecurityException If request is for enterprise APN {@code admin} is either device
+     * owner or profile owner and in all other types of APN if {@code admin} is not a device owner.
      *
      * @see #setOverrideApnsEnabled(ComponentName, boolean)
      */
@@ -13635,20 +13662,26 @@
     }
 
     /**
-     * Called by device owner to update an override APN.
+     * Called by device owner or profile owner to update an override APN.
      *
      * <p>This method may returns {@code false} if there is no override APN with the given
      * {@code apnId}.
      * <p>This method may also returns {@code false} if {@code apnSetting} conflicts with an
      * existing override APN. Update the existing conflicted APN instead.
      * <p>See {@link #addOverrideApn} for the definition of conflict.
+     * <p> Before Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}:
+     * Only device owners can update APNs.
+     * <p> Starting from Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}:
+     * Device and profile owners can update enterprise APNs
+     * ({@link ApnSetting#TYPE_ENTERPRISE}), while only device owners can update other type of APNs.
      *
      * @param admin which {@link DeviceAdminReceiver} this request is associated with
      * @param apnId the {@code id} of the override APN to update
      * @param apnSetting the override APN to update
      * @return {@code true} if the required override APN is successfully updated,
      *         {@code false} otherwise.
-     * @throws SecurityException if {@code admin} is not a device owner.
+     * @throws SecurityException If request is for enterprise APN {@code admin} is either device
+     * owner or profile owner and in all other types of APN if {@code admin} is not a device owner.
      *
      * @see #setOverrideApnsEnabled(ComponentName, boolean)
      */
@@ -13666,16 +13699,22 @@
     }
 
     /**
-     * Called by device owner to remove an override APN.
+     * Called by device owner or profile owner to remove an override APN.
      *
      * <p>This method may returns {@code false} if there is no override APN with the given
      * {@code apnId}.
+     * <p> Before Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}:
+     * Only device owners can remove APNs.
+     * <p> Starting from Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}:
+     * Device and profile owners can remove enterprise APNs
+     * ({@link ApnSetting#TYPE_ENTERPRISE}), while only device owners can remove other type of APNs.
      *
      * @param admin which {@link DeviceAdminReceiver} this request is associated with
      * @param apnId the {@code id} of the override APN to remove
      * @return {@code true} if the required override APN is successfully removed, {@code false}
      *         otherwise.
-     * @throws SecurityException if {@code admin} is not a device owner.
+     * @throws SecurityException If request is for enterprise APN {@code admin} is either device
+     * owner or profile owner and in all other types of APN if {@code admin} is not a device owner.
      *
      * @see #setOverrideApnsEnabled(ComponentName, boolean)
      */
@@ -14776,17 +14815,20 @@
      * <p>The method {@link #checkProvisioningPrecondition} must be returning {@link #STATUS_OK}
      * before calling this method.
      *
+     * <p>Holders of {@link android.Manifest.permission#PROVISION_DEMO_DEVICE} can call this API
+     * only if {@link FullyManagedDeviceProvisioningParams#isDemoDevice()} is {@code true}.</p>
+     *
      * @param provisioningParams Params required to provision a fully managed device,
      * see {@link FullyManagedDeviceProvisioningParams}.
      *
-     * @throws SecurityException if the caller does not hold
-     * {@link android.Manifest.permission#MANAGE_PROFILE_AND_DEVICE_OWNERS}.
      * @throws ProvisioningException if an error occurred during provisioning.
      *
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS,
+            android.Manifest.permission.PROVISION_DEMO_DEVICE})
     public void provisionFullyManagedDevice(
             @NonNull FullyManagedDeviceProvisioningParams provisioningParams)
             throws ProvisioningException {
diff --git a/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
index 1f7ae4a..4999245 100644
--- a/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
+++ b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
@@ -26,6 +26,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
+import android.provider.Settings;
 import android.stats.devicepolicy.DevicePolicyEnums;
 
 import java.util.Locale;
@@ -44,6 +45,7 @@
             "CAN_DEVICE_OWNER_GRANT_SENSOR_PERMISSIONS";
     private static final String TIME_ZONE_PROVIDED_PARAM = "TIME_ZONE_PROVIDED";
     private static final String LOCALE_PROVIDED_PARAM = "LOCALE_PROVIDED";
+    private static final String DEMO_DEVICE = "DEMO_DEVICE";
 
     @NonNull private final ComponentName mDeviceAdminComponentName;
     @NonNull private final String mOwnerName;
@@ -54,6 +56,8 @@
     @Nullable private final Locale mLocale;
     private final boolean mDeviceOwnerCanGrantSensorsPermissions;
     @NonNull private final PersistableBundle mAdminExtras;
+    private final boolean mDemoDevice;
+
 
     private FullyManagedDeviceProvisioningParams(
             @NonNull ComponentName deviceAdminComponentName,
@@ -63,7 +67,8 @@
             long localTime,
             @Nullable @SuppressLint("UseIcu") Locale locale,
             boolean deviceOwnerCanGrantSensorsPermissions,
-            @NonNull PersistableBundle adminExtras) {
+            @NonNull PersistableBundle adminExtras,
+            boolean demoDevice) {
         this.mDeviceAdminComponentName = requireNonNull(deviceAdminComponentName);
         this.mOwnerName = requireNonNull(ownerName);
         this.mLeaveAllSystemAppsEnabled = leaveAllSystemAppsEnabled;
@@ -73,6 +78,7 @@
         this.mDeviceOwnerCanGrantSensorsPermissions =
                 deviceOwnerCanGrantSensorsPermissions;
         this.mAdminExtras = adminExtras;
+        this.mDemoDevice = demoDevice;
     }
 
     private FullyManagedDeviceProvisioningParams(
@@ -83,7 +89,8 @@
             long localTime,
             @Nullable String localeStr,
             boolean deviceOwnerCanGrantSensorsPermissions,
-            @Nullable PersistableBundle adminExtras) {
+            @Nullable PersistableBundle adminExtras,
+            boolean demoDevice) {
         this(deviceAdminComponentName,
                 ownerName,
                 leaveAllSystemAppsEnabled,
@@ -91,7 +98,8 @@
                 localTime,
                 getLocale(localeStr),
                 deviceOwnerCanGrantSensorsPermissions,
-                adminExtras);
+                adminExtras,
+                demoDevice);
     }
 
     @Nullable
@@ -166,6 +174,14 @@
     }
 
     /**
+     * @return true if this device is being setup as a retail demo device, see
+     * {@link Settings.Global#DEVICE_DEMO_MODE}.
+     */
+    public boolean isDemoDevice() {
+        return mDemoDevice;
+    }
+
+    /**
      * Logs the provisioning params using {@link DevicePolicyEventLogger}.
      *
      * @hide
@@ -178,6 +194,7 @@
                 mDeviceOwnerCanGrantSensorsPermissions);
         logParam(callerPackage, TIME_ZONE_PROVIDED_PARAM, /* value= */ mTimeZone != null);
         logParam(callerPackage, LOCALE_PROVIDED_PARAM, /* value= */ mLocale != null);
+        logParam(callerPackage, DEMO_DEVICE, mDemoDevice);
     }
 
     private void logParam(String callerPackage, String param, boolean value) {
@@ -204,6 +221,9 @@
         // Default to allowing control over sensor permission grants.
         boolean mDeviceOwnerCanGrantSensorsPermissions = true;
         @NonNull private PersistableBundle mAdminExtras;
+        // Default is normal user devices
+        boolean mDemoDevice = false;
+
 
         /**
          * Initialize a new {@link Builder} to construct a
@@ -289,6 +309,16 @@
         }
 
         /**
+         * Marks the device as a demo device, see {@link Settings.Global#DEVICE_DEMO_MODE}. The
+         * default value if unset is {@code false}.
+         */
+        @NonNull
+        public Builder setDemoDevice(boolean demoDevice) {
+            this.mDemoDevice = demoDevice;
+            return this;
+        }
+
+        /**
          * Combines all of the attributes that have been set on this {@code Builder}
          *
          * @return a new {@link FullyManagedDeviceProvisioningParams} object.
@@ -303,7 +333,8 @@
                     mLocalTime,
                     mLocale,
                     mDeviceOwnerCanGrantSensorsPermissions,
-                    mAdminExtras);
+                    mAdminExtras,
+                    mDemoDevice);
         }
     }
 
@@ -327,6 +358,7 @@
                 + ", mDeviceOwnerCanGrantSensorsPermissions="
                 + mDeviceOwnerCanGrantSensorsPermissions
                 + ", mAdminExtras=" + mAdminExtras
+                + ", mDemoDevice=" + mDemoDevice
                 + '}';
     }
 
@@ -340,6 +372,7 @@
         dest.writeString(mLocale == null ? null : mLocale.toLanguageTag());
         dest.writeBoolean(mDeviceOwnerCanGrantSensorsPermissions);
         dest.writePersistableBundle(mAdminExtras);
+        dest.writeBoolean(mDemoDevice);
     }
 
     @NonNull
@@ -355,6 +388,7 @@
                     String locale = in.readString();
                     boolean deviceOwnerCanGrantSensorsPermissions = in.readBoolean();
                     PersistableBundle adminExtras = in.readPersistableBundle();
+                    boolean demoDevice = in.readBoolean();
 
                     return new FullyManagedDeviceProvisioningParams(
                             componentName,
@@ -364,7 +398,8 @@
                             localtime,
                             locale,
                             deviceOwnerCanGrantSensorsPermissions,
-                            adminExtras);
+                            adminExtras,
+                            demoDevice);
                 }
 
                 @Override
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 9d28dde..77db146 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -285,12 +285,9 @@
     void setSecondaryLockscreenEnabled(in ComponentName who, boolean enabled);
     boolean isSecondaryLockscreenEnabled(in UserHandle userHandle);
 
-    void setPreferentialNetworkServiceEnabled(in boolean enabled);
-    boolean isPreferentialNetworkServiceEnabled(int userHandle);
-
-    void setPreferentialNetworkServiceConfig(
-            in PreferentialNetworkServiceConfig preferentialNetworkServiceConfig);
-    PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig();
+    void setPreferentialNetworkServiceConfigs(
+            in List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs);
+    List<PreferentialNetworkServiceConfig> getPreferentialNetworkServiceConfigs();
 
     void setLockTaskPackages(in ComponentName who, in String[] packages);
     String[] getLockTaskPackages(in ComponentName who);
diff --git a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
index 2849139..54170a2 100644
--- a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
+++ b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
@@ -28,7 +28,7 @@
 
 /**
  * Network configuration to be set for the user profile
- * {@see DevicePolicyManager#setPreferentialNetworkServiceConfig}.
+ * {@see DevicePolicyManager#setPreferentialNetworkServiceConfigs}.
  */
 public final class PreferentialNetworkServiceConfig implements Parcelable {
     final boolean mIsEnabled;
@@ -147,8 +147,6 @@
 
     /**
      * @return preference enterprise identifier.
-     * valid values starts from
-     * {@link #PREFERENTIAL_NETWORK_ID_1} to {@link #PREFERENTIAL_NETWORK_ID_5}.
      * preference identifier is applicable only if preference network service is enabled
      *
      */
@@ -286,8 +284,6 @@
 
         /**
          * Set the preferential network identifier.
-         * Valid values starts from {@link #PREFERENTIAL_NETWORK_ID_1} to
-         * {@link #PREFERENTIAL_NETWORK_ID_5}.
          * preference identifier is applicable only if preferential network service is enabled.
          * @param preferenceId  preference Id
          * @return The builder to facilitate chaining.
diff --git a/core/java/android/app/cloudsearch/SearchRequest.java b/core/java/android/app/cloudsearch/SearchRequest.java
index 4d6507a..bf78325 100644
--- a/core/java/android/app/cloudsearch/SearchRequest.java
+++ b/core/java/android/app/cloudsearch/SearchRequest.java
@@ -100,7 +100,7 @@
      *
      */
     @NonNull
-    private String mSource;
+    private String mCallerPackageName;
 
     private SearchRequest(Parcel in) {
         this.mQuery = in.readString();
@@ -109,17 +109,17 @@
         this.mMaxLatencyMillis = in.readFloat();
         this.mSearchConstraints = in.readBundle();
         this.mId = in.readString();
-        this.mSource = in.readString();
+        this.mCallerPackageName = in.readString();
     }
 
     private SearchRequest(String query, int resultOffset, int resultNumber, float maxLatencyMillis,
-            Bundle searchConstraints, String source) {
+            Bundle searchConstraints, String callerPackageName) {
         mQuery = query;
         mResultOffset = resultOffset;
         mResultNumber = resultNumber;
         mMaxLatencyMillis = maxLatencyMillis;
         mSearchConstraints = searchConstraints;
-        mSource = source;
+        mCallerPackageName = callerPackageName;
     }
 
     /** Returns the original query. */
@@ -151,8 +151,8 @@
 
     /** Gets the caller's package name. */
     @NonNull
-    public String getSource() {
-        return mSource;
+    public String getCallerPackageName() {
+        return mCallerPackageName;
     }
 
     /** Returns the search request id, which is used to identify the request. */
@@ -169,8 +169,8 @@
      *
      * @hide
      */
-    public void setSource(@NonNull String source) {
-        this.mSource = source;
+    public void setCallerPackageName(@NonNull String callerPackageName) {
+        this.mCallerPackageName = callerPackageName;
     }
 
     private SearchRequest(Builder b) {
@@ -179,7 +179,7 @@
         mResultNumber = b.mResultNumber;
         mMaxLatencyMillis = b.mMaxLatencyMillis;
         mSearchConstraints = requireNonNull(b.mSearchConstraints);
-        mSource = requireNonNull(b.mSource);
+        mCallerPackageName = requireNonNull(b.mCallerPackageName);
     }
 
     /**
@@ -207,7 +207,7 @@
         dest.writeFloat(this.mMaxLatencyMillis);
         dest.writeBundle(this.mSearchConstraints);
         dest.writeString(getRequestId());
-        dest.writeString(this.mSource);
+        dest.writeString(this.mCallerPackageName);
     }
 
     @Override
@@ -231,7 +231,7 @@
                 && mResultNumber == that.mResultNumber
                 && mMaxLatencyMillis == that.mMaxLatencyMillis
                 && Objects.equals(mSearchConstraints, that.mSearchConstraints)
-                && Objects.equals(mSource, that.mSource);
+                && Objects.equals(mCallerPackageName, that.mCallerPackageName);
     }
 
     @Override
@@ -246,14 +246,15 @@
         }
 
         return String.format("SearchRequest: {query:%s,offset:%d;number:%d;max_latency:%f;"
-                        + "is_presubmit:%b;search_provider:%s;source:%s}", mQuery, mResultOffset,
-                mResultNumber, mMaxLatencyMillis, isPresubmit, searchProvider, mSource);
+                        + "is_presubmit:%b;search_provider:%s;callerPackageName:%s}", mQuery,
+                mResultOffset, mResultNumber, mMaxLatencyMillis, isPresubmit, searchProvider,
+                mCallerPackageName);
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mQuery, mResultOffset, mResultNumber, mMaxLatencyMillis,
-                mSearchConstraints, mSource);
+                mSearchConstraints, mCallerPackageName);
     }
 
     /**
@@ -268,7 +269,7 @@
         private int mResultNumber;
         private float mMaxLatencyMillis;
         private Bundle mSearchConstraints;
-        private String mSource;
+        private String mCallerPackageName;
 
         /**
          *
@@ -284,7 +285,7 @@
             mResultNumber = 10;
             mMaxLatencyMillis = 200;
             mSearchConstraints = Bundle.EMPTY;
-            mSource = "DEFAULT_CALLER";
+            mCallerPackageName = "DEFAULT_CALLER";
         }
 
         /** Sets the input query. */
@@ -329,8 +330,8 @@
          */
         @NonNull
         @TestApi
-        public Builder setSource(@NonNull String source) {
-            this.mSource = source;
+        public Builder setCallerPackageName(@NonNull String callerPackageName) {
+            this.mCallerPackageName = callerPackageName;
             return this;
         }
 
@@ -343,7 +344,7 @@
             }
 
             return new SearchRequest(mQuery, mResultOffset, mResultNumber, mMaxLatencyMillis,
-                               mSearchConstraints, mSource);
+                               mSearchConstraints, mCallerPackageName);
         }
     }
 }
diff --git a/core/java/android/app/cloudsearch/SearchResult.java b/core/java/android/app/cloudsearch/SearchResult.java
index af8adac..c6583b6 100644
--- a/core/java/android/app/cloudsearch/SearchResult.java
+++ b/core/java/android/app/cloudsearch/SearchResult.java
@@ -71,6 +71,10 @@
             EXTRAINFO_APP_BADGES,
             EXTRAINFO_ACTION_BUTTON_TEXT_PREREGISTERING,
             EXTRAINFO_ACTION_BUTTON_IMAGE_PREREGISTERING,
+            EXTRAINFO_ACTION_APP_CARD,
+            EXTRAINFO_ACTION_INSTALL_BUTTON,
+            EXTRAINFO_APP_PACKAGE_NAME,
+            EXTRAINFO_APP_INSTALL_COUNT,
             EXTRAINFO_WEB_URL,
             EXTRAINFO_WEB_ICON})
     public @interface SearchResultExtraInfoKey {}
@@ -119,6 +123,20 @@
     @SuppressLint("IntentName")
     public static final String EXTRAINFO_ACTION_BUTTON_IMAGE_PREREGISTERING =
             "android.app.cloudsearch.ACTION_BUTTON_IMAGE";
+    /** Intent for tapping the app card, PendingIntent expected. */
+    @SuppressLint("IntentName")
+    public static final String EXTRAINFO_ACTION_APP_CARD =
+            "android.app.cloudsearch.ACTION_APP_CARD";
+    /** Intent for tapping the install button, PendingIntent expected. */
+    @SuppressLint("IntentName")
+    public static final String EXTRAINFO_ACTION_INSTALL_BUTTON =
+            "android.app.cloudsearch.ACTION_INSTALL_BUTTON";
+    /** App's package name, String value expected. */
+    public static final String EXTRAINFO_APP_PACKAGE_NAME =
+            "android.app.cloudsearch.APP_PACKAGE_NAME";
+    /** App's install count, double value expected. */
+    public static final String EXTRAINFO_APP_INSTALL_COUNT =
+            "android.app.cloudsearch.APP_INSTALL_COUNT";
     /** Web content's URL, String value expected. */
     public static final String EXTRAINFO_WEB_URL = "android.app.cloudsearch.WEB_URL";
     /** Web content's domain icon, android.graphics.drawable.Icon expected. */
diff --git a/core/java/android/app/servertransaction/ActivityTransactionItem.java b/core/java/android/app/servertransaction/ActivityTransactionItem.java
index 6a6d76d..469a9bf 100644
--- a/core/java/android/app/servertransaction/ActivityTransactionItem.java
+++ b/core/java/android/app/servertransaction/ActivityTransactionItem.java
@@ -64,11 +64,11 @@
         final ActivityClientRecord r = client.getActivityClient(token);
         if (r == null) {
             throw new IllegalArgumentException("Activity client record must not be null to execute "
-                    + "transaction item");
+                    + "transaction item: " + this);
         }
         if (client.getActivity(token) == null) {
             throw new IllegalArgumentException("Activity must not be null to execute "
-                    + "transaction item");
+                    + "transaction item: " + this);
         }
         return r;
     }
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index abf1058..d7e0951 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -179,7 +179,7 @@
                 in.readPersistableBundle(getClass().getClassLoader()),
                 in.createTypedArrayList(ResultInfo.CREATOR),
                 in.createTypedArrayList(ReferrerIntent.CREATOR),
-                readActivityOptions(in), in.readBoolean(),
+                ActivityOptions.fromBundle(in.readBundle()), in.readBoolean(),
                 in.readTypedObject(ProfilerInfo.CREATOR),
                 in.readStrongBinder(),
                 IActivityClientController.Stub.asInterface(in.readStrongBinder()),
@@ -187,11 +187,6 @@
                 in.readBoolean());
     }
 
-    private static ActivityOptions readActivityOptions(Parcel in) {
-        Bundle bundle = in.readBundle();
-        return bundle != null ? ActivityOptions.fromBundle(bundle) : null;
-    }
-
     public static final @NonNull Creator<LaunchActivityItem> CREATOR =
             new Creator<LaunchActivityItem>() {
         public LaunchActivityItem createFromParcel(Parcel in) {
diff --git a/core/java/android/app/servertransaction/StartActivityItem.java b/core/java/android/app/servertransaction/StartActivityItem.java
index f267060..15f65f6 100644
--- a/core/java/android/app/servertransaction/StartActivityItem.java
+++ b/core/java/android/app/servertransaction/StartActivityItem.java
@@ -23,7 +23,6 @@
 import android.app.ActivityOptions;
 import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Trace;
 
@@ -84,8 +83,7 @@
 
     /** Read from Parcel. */
     private StartActivityItem(Parcel in) {
-        Bundle bundle = in.readBundle();
-        mActivityOptions = bundle != null ? ActivityOptions.fromBundle(bundle) : null;
+        mActivityOptions = ActivityOptions.fromBundle(in.readBundle());
     }
 
     public static final @NonNull Creator<StartActivityItem> CREATOR =
diff --git a/core/java/android/app/trust/TEST_MAPPING b/core/java/android/app/trust/TEST_MAPPING
new file mode 100644
index 0000000..b9c46bf
--- /dev/null
+++ b/core/java/android/app/trust/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+  "presubmit": [
+    {
+      "name": "TrustTests",
+      "options": [
+        {
+          "include-filter": "android.trust.test"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java
index 41b1a1f..cbb5183 100644
--- a/core/java/android/companion/virtual/VirtualDeviceParams.java
+++ b/core/java/android/companion/virtual/VirtualDeviceParams.java
@@ -28,6 +28,8 @@
 import android.os.UserHandle;
 import android.util.ArraySet;
 
+import com.android.internal.util.Preconditions;
+
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -82,7 +84,7 @@
     public static final int ACTIVITY_POLICY_DEFAULT_BLOCKED = 1;
 
     private final int mLockState;
-    private final ArraySet<UserHandle> mUsersWithMatchingAccounts;
+    @NonNull private final ArraySet<UserHandle> mUsersWithMatchingAccounts;
     @NonNull private final ArraySet<ComponentName> mAllowedActivities;
     @NonNull private final ArraySet<ComponentName> mBlockedActivities;
     @ActivityPolicy
@@ -94,10 +96,14 @@
             @NonNull Set<ComponentName> allowedActivities,
             @NonNull Set<ComponentName> blockedActivities,
             @ActivityPolicy int defaultActivityPolicy) {
+        Preconditions.checkNotNull(usersWithMatchingAccounts);
+        Preconditions.checkNotNull(allowedActivities);
+        Preconditions.checkNotNull(blockedActivities);
+
         mLockState = lockState;
         mUsersWithMatchingAccounts = new ArraySet<>(usersWithMatchingAccounts);
-        mAllowedActivities = allowedActivities == null ? null : new ArraySet<>(allowedActivities);
-        mBlockedActivities = blockedActivities == null ? null : new ArraySet<>(blockedActivities);
+        mAllowedActivities = new ArraySet<>(allowedActivities);
+        mBlockedActivities = new ArraySet<>(blockedActivities);
         mDefaultActivityPolicy = defaultActivityPolicy;
     }
 
@@ -130,30 +136,24 @@
     }
 
     /**
-     * Returns the set of activities allowed to be streamed, or {@code null} if all activities are
+     * Returns the set of activities allowed to be streamed, or empty set if all activities are
      * allowed, except the ones explicitly blocked.
      *
      * @see Builder#setAllowedActivities(Set)
      */
     @NonNull
     public Set<ComponentName> getAllowedActivities() {
-        if (mAllowedActivities == null) {
-            return Collections.emptySet();
-        }
         return Collections.unmodifiableSet(mAllowedActivities);
     }
 
     /**
-     * Returns the set of activities that are blocked from streaming, or {@code null} to indicate
+     * Returns the set of activities that are blocked from streaming, or empty set to indicate
      * that all activities in {@link #getAllowedActivities} are allowed.
      *
      * @see Builder#setBlockedActivities(Set)
      */
     @NonNull
     public Set<ComponentName> getBlockedActivities() {
-        if (mBlockedActivities == null) {
-            return Collections.emptySet();
-        }
         return Collections.unmodifiableSet(mBlockedActivities);
     }
 
@@ -237,7 +237,7 @@
     public static final class Builder {
 
         private @LockState int mLockState = LOCK_STATE_DEFAULT;
-        private Set<UserHandle> mUsersWithMatchingAccounts;
+        @NonNull private Set<UserHandle> mUsersWithMatchingAccounts = Collections.emptySet();;
         @NonNull private Set<ComponentName> mBlockedActivities = Collections.emptySet();
         @NonNull private Set<ComponentName> mAllowedActivities = Collections.emptySet();
         @ActivityPolicy
@@ -282,6 +282,7 @@
         @NonNull
         public Builder setUsersWithMatchingAccounts(
                 @NonNull Set<UserHandle> usersWithMatchingAccounts) {
+            Preconditions.checkNotNull(usersWithMatchingAccounts);
             mUsersWithMatchingAccounts = usersWithMatchingAccounts;
             return this;
         }
@@ -301,6 +302,7 @@
          */
         @NonNull
         public Builder setAllowedActivities(@NonNull Set<ComponentName> allowedActivities) {
+            Preconditions.checkNotNull(allowedActivities);
             if (mDefaultActivityPolicyConfigured
                     && mDefaultActivityPolicy != ACTIVITY_POLICY_DEFAULT_BLOCKED) {
                 throw new IllegalArgumentException(
@@ -327,6 +329,7 @@
          */
         @NonNull
         public Builder setBlockedActivities(@NonNull Set<ComponentName> blockedActivities) {
+            Preconditions.checkNotNull(blockedActivities);
             if (mDefaultActivityPolicyConfigured
                     && mDefaultActivityPolicy != ACTIVITY_POLICY_DEFAULT_ALLOWED) {
                 throw new IllegalArgumentException(
@@ -343,9 +346,6 @@
          */
         @NonNull
         public VirtualDeviceParams build() {
-            if (mUsersWithMatchingAccounts == null) {
-                mUsersWithMatchingAccounts = Collections.emptySet();
-            }
             return new VirtualDeviceParams(
                     mLockState,
                     mUsersWithMatchingAccounts,
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 2bda020..60efb4d 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2011,9 +2011,9 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
-    @UnsupportedAppUsage
-    public void startActivityAsUser(@RequiresPermission Intent intent, @Nullable Bundle options,
-            UserHandle userId) {
+    @SystemApi
+    public void startActivityAsUser(@RequiresPermission @NonNull Intent intent,
+            @Nullable Bundle options, @NonNull UserHandle userId) {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
     }
 
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 673127e..2961b55 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -2084,7 +2084,7 @@
         splitNames = source.createString8Array();
         splitSourceDirs = source.createString8Array();
         splitPublicSourceDirs = source.createString8Array();
-        splitDependencies = source.readSparseArray(null);
+        splitDependencies = source.readSparseArray(null, int[].class);
         nativeLibraryDir = source.readString8();
         secondaryNativeLibraryDir = source.readString8();
         nativeLibraryRootDir = source.readString8();
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index 94f0561..b6917e26 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -104,7 +104,44 @@
                     mContext.getAttributionTag(),
                     component,
                     targetUser.getIdentifier(),
-                    true);
+                    true,
+                    null,
+                    null);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Starts the specified main activity of the caller package in the specified profile, launching
+     * in the specified activity.
+     *
+     * @param component The ComponentName of the activity to launch, it must be exported and has
+     *        action {@link android.content.Intent#ACTION_MAIN}, category
+     *        {@link android.content.Intent#CATEGORY_LAUNCHER}. Otherwise, SecurityException will
+     *        be thrown.
+     * @param targetUser The UserHandle of the profile, must be one of the users returned by
+     *        {@link #getTargetUserProfiles()}, otherwise a {@link SecurityException} will
+     *        be thrown.
+     * @param callingActivity The activity to start the new activity from for the purposes of
+     *        deciding which task the new activity should belong to. If {@code null}, the activity
+     *        will always be started in a new task.
+     * @param options The activity options or {@code null}. See {@link android.app.ActivityOptions}.
+     */
+    public void startMainActivity(@NonNull ComponentName component,
+            @NonNull UserHandle targetUser,
+            @Nullable Activity callingActivity,
+            @Nullable Bundle options) {
+        try {
+            mService.startActivityAsUser(
+                    mContext.getIApplicationThread(),
+                    mContext.getPackageName(),
+                    mContext.getAttributionTag(),
+                    component,
+                    targetUser.getIdentifier(),
+                    true,
+                    callingActivity != null ? callingActivity.getActivityToken() : null,
+                    options);
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
         }
@@ -191,6 +228,48 @@
      * @param targetUser The UserHandle of the profile, must be one of the users returned by
      *        {@link #getTargetUserProfiles()}, otherwise a {@link SecurityException} will
      *        be thrown.
+     * @param callingActivity The activity to start the new activity from for the purposes of
+     *        deciding which task the new activity should belong to. If {@code null}, the activity
+     *        will always be started in a new task.
+     * @param options The activity options or {@code null}. See {@link android.app.ActivityOptions}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.INTERACT_ACROSS_PROFILES,
+            android.Manifest.permission.START_CROSS_PROFILE_ACTIVITIES})
+    public void startActivity(
+            @NonNull ComponentName component,
+            @NonNull UserHandle targetUser,
+            @Nullable Activity callingActivity,
+            @Nullable Bundle options) {
+        try {
+            mService.startActivityAsUser(
+                    mContext.getIApplicationThread(),
+                    mContext.getPackageName(),
+                    mContext.getAttributionTag(),
+                    component,
+                    targetUser.getIdentifier(),
+                    false,
+                    callingActivity != null ? callingActivity.getActivityToken() : null,
+                    options);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Starts the specified activity of the caller package in the specified profile. Unlike
+     * {@link #startMainActivity}, this can start any activity of the caller package, not just
+     * the main activity.
+     * The caller must have the {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES}
+     * or {@link android.Manifest.permission#START_CROSS_PROFILE_ACTIVITIES}
+     * permission and both the caller and target user profiles must be in the same profile group.
+     *
+     * @param component The ComponentName of the activity to launch. It must be exported.
+     * @param targetUser The UserHandle of the profile, must be one of the users returned by
+     *        {@link #getTargetUserProfiles()}, otherwise a {@link SecurityException} will
+     *        be thrown.
      * @hide
      */
     @SystemApi
@@ -201,7 +280,7 @@
         try {
             mService.startActivityAsUser(mContext.getIApplicationThread(),
                     mContext.getPackageName(), mContext.getAttributionTag(), component,
-                    targetUser.getIdentifier(), false);
+                    targetUser.getIdentifier(), false, null, null);
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
         }
diff --git a/core/java/android/content/pm/ICrossProfileApps.aidl b/core/java/android/content/pm/ICrossProfileApps.aidl
index e2850f1..4f2c106 100644
--- a/core/java/android/content/pm/ICrossProfileApps.aidl
+++ b/core/java/android/content/pm/ICrossProfileApps.aidl
@@ -29,7 +29,7 @@
 interface ICrossProfileApps {
     void startActivityAsUser(in IApplicationThread caller, in String callingPackage,
             in String callingFeatureId, in ComponentName component, int userId,
-            boolean launchMainActivity);
+            boolean launchMainActivity, in IBinder task, in Bundle options);
     void startActivityAsUserByIntent(in IApplicationThread caller, in String callingPackage,
             in String callingFeatureId, in Intent intent, int userId, in IBinder callingActivity,
             in Bundle options);
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index 18e205f..8d6c8e8d 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -57,4 +57,5 @@
     int getParentSessionId();
 
     boolean isStaged();
+    int getInstallFlags();
 }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index e9e6cd3..ca7d77b 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -497,21 +497,10 @@
     void enterSafeMode();
     @UnsupportedAppUsage
     boolean isSafeMode();
-    void systemReady();
     @UnsupportedAppUsage
     boolean hasSystemUidErrors();
 
     /**
-     * Ask the package manager to fstrim the disk if needed.
-     */
-    void performFstrimIfNeeded();
-
-    /**
-     * Ask the package manager to update packages if needed.
-     */
-    void updatePackagesIfNeeded();
-
-    /**
      * Notify the package manager that a package is going to be used and why.
      *
      * See PackageManager.NOTIFY_PACKAGE_USE_* for reasons.
@@ -792,7 +781,11 @@
 
     boolean isAutoRevokeWhitelisted(String packageName);
 
-    void grantImplicitAccess(int queryingUid, String visibleAuthority);
+    void makeProviderVisible(int recipientAppId, String visibleAuthority);
+
+    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+            + ".permission.MAKE_UID_VISIBLE)")
+    void makeUidVisible(int recipientAppId, int visibleUid);
 
     IBinder getHoldLockToken();
 
diff --git a/core/java/android/content/pm/PackageInfoLite.java b/core/java/android/content/pm/PackageInfoLite.java
index 410e106..148eacc 100644
--- a/core/java/android/content/pm/PackageInfoLite.java
+++ b/core/java/android/content/pm/PackageInfoLite.java
@@ -79,6 +79,11 @@
     public boolean debuggable;
 
     /**
+     * Indicates if this apk is a sdk.
+     */
+    public boolean isSdkLibrary;
+
+    /**
      * Specifies the recommended install location. Can be one of
      * {@link InstallLocationUtils#RECOMMEND_INSTALL_INTERNAL} to install on internal storage,
      * {@link InstallLocationUtils#RECOMMEND_INSTALL_EXTERNAL} to install on external media,
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 67a2dc8..450e09a 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1586,6 +1586,18 @@
         }
 
         /**
+         * @return Session's {@link SessionParams#installFlags}.
+         * @hide
+         */
+        public int getInstallFlags() {
+            try {
+                return mSession.getInstallFlags();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
          * @return the session ID of the multi-package session that this belongs to or
          * {@link SessionInfo#INVALID_ID} if it does not belong to a multi-package session.
          */
@@ -2421,15 +2433,6 @@
         /** {@hide} */
         private static final int[] NO_SESSIONS = {};
 
-        /** @hide */
-        @IntDef(prefix = { "SESSION_" }, value = {
-                SESSION_NO_ERROR,
-                SESSION_VERIFICATION_FAILED,
-                SESSION_ACTIVATION_FAILED,
-                SESSION_UNKNOWN_ERROR,
-                SESSION_CONFLICT})
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface SessionErrorCode {}
         /**
          * @deprecated use {@link #SESSION_NO_ERROR}.
          */
@@ -3113,7 +3116,7 @@
          * If something went wrong with a staged session, clients can check this error code to
          * understand which kind of failure happened. Only meaningful if {@code isStaged} is true.
          */
-        public @SessionErrorCode int getStagedSessionErrorCode() {
+        public int getStagedSessionErrorCode() {
             checkSessionIsStaged();
             return mSessionErrorCode;
         }
@@ -3128,7 +3131,7 @@
         }
 
         /** {@hide} */
-        public void setSessionErrorCode(@SessionErrorCode int errorCode, String errorMessage) {
+        public void setSessionErrorCode(int errorCode, String errorMessage) {
             mSessionErrorCode = errorCode;
             mSessionErrorMessage = errorMessage;
         }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index f4bc161..81c941e 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -121,6 +121,9 @@
     /** {@hide} */
     public static final boolean APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE = true;
 
+    /** {@hide} */
+    public static final boolean ENABLE_SHARED_UID_MIGRATION = true;
+
     /**
      * This exception is thrown when a given package, application, or component
      * name cannot be found.
@@ -2202,6 +2205,14 @@
      */
     public static final int INSTALL_FAILED_BAD_PERMISSION_GROUP = -127;
 
+    /**
+     * Installation failed return code: an error occurred during the activation phase of this
+     * session.
+     *
+     * @hide
+     */
+    public static final int INSTALL_ACTIVATION_FAILED = -128;
+
     /** @hide */
     @IntDef(flag = true, prefix = { "DELETE_" }, value = {
             DELETE_KEEP_DATA,
@@ -4251,8 +4262,9 @@
      * for more details.
      * @hide
      */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final String EXTRA_VERIFICATION_ROOT_HASH =
-            "android.content.pm.extra.EXTRA_VERIFICATION_ROOT_HASH";
+            "android.content.pm.extra.VERIFICATION_ROOT_HASH";
 
     /**
      * Extra field name for the ID of a intent filter pending verification.
@@ -10269,19 +10281,38 @@
     }
 
     /**
-     * Grants implicit visibility of the package that provides an authority to a querying UID.
+     * Makes a package that provides an authority {@code visibleAuthority} become visible to the
+     * application {@code recipientUid}.
      *
      * @throws SecurityException when called by a package other than the contacts provider
      * @hide
      */
-    public void grantImplicitAccess(int queryingUid, String visibleAuthority) {
+    public void makeProviderVisible(int recipientUid, String visibleAuthority) {
         try {
-            ActivityThread.getPackageManager().grantImplicitAccess(queryingUid, visibleAuthority);
+            ActivityThread.getPackageManager().makeProviderVisible(recipientUid, visibleAuthority);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
+    /**
+     * Makes the package associated with the uid {@code visibleUid} become visible to the
+     * recipient uid application.
+     *
+     * @param recipientUid The uid of the application that is being given access to {@code
+     *                     visibleUid}
+     * @param visibleUid The uid of the application that is becoming accessible to {@code
+     *                   recipientAppId}
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MAKE_UID_VISIBLE)
+    @TestApi
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void makeUidVisible(int recipientUid, int visibleUid) {
+        throw new UnsupportedOperationException(
+                "makeUidVisible not implemented in subclass");
+    }
+
     // Some of the flags don't affect the query result, but let's be conservative and cache
     // each combination of flags separately.
 
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e914432..4d4a57d 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1944,19 +1944,26 @@
         TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifest);
 
-        String str = sa.getNonConfigurationString(
-                com.android.internal.R.styleable.AndroidManifest_sharedUserId, 0);
-        if (str != null && str.length() > 0) {
-            String nameError = validateName(str, true, true);
-            if (nameError != null && !"android".equals(pkg.packageName)) {
-                outError[0] = "<manifest> specifies bad sharedUserId name \""
-                    + str + "\": " + nameError;
-                mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID;
-                return null;
+        int maxSdkVersion = 0;
+        if (PackageManager.ENABLE_SHARED_UID_MIGRATION) {
+            maxSdkVersion = sa.getInteger(
+                    com.android.internal.R.styleable.AndroidManifest_sharedUserMaxSdkVersion, 0);
+        }
+        if (maxSdkVersion == 0 || maxSdkVersion >= Build.VERSION.RESOURCES_SDK_INT) {
+            String str = sa.getNonConfigurationString(
+                    com.android.internal.R.styleable.AndroidManifest_sharedUserId, 0);
+            if (str != null && str.length() > 0) {
+                String nameError = validateName(str, true, true);
+                if (nameError != null && !"android".equals(pkg.packageName)) {
+                    outError[0] = "<manifest> specifies bad sharedUserId name \""
+                            + str + "\": " + nameError;
+                    mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID;
+                    return null;
+                }
+                pkg.mSharedUserId = str.intern();
+                pkg.mSharedUserLabel = sa.getResourceId(
+                        com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0);
             }
-            pkg.mSharedUserId = str.intern();
-            pkg.mSharedUserLabel = sa.getResourceId(
-                    com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0);
         }
 
         pkg.installLocation = sa.getInteger(
diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java
index 3f5c5d2..d94b0d8 100644
--- a/core/java/android/content/pm/Signature.java
+++ b/core/java/android/content/pm/Signature.java
@@ -312,7 +312,7 @@
      * @hide
      */
     public static boolean areExactMatch(Signature[] a, Signature[] b) {
-        return (a.length == b.length) && ArrayUtils.containsAll(a, b)
+        return (ArrayUtils.size(a) == ArrayUtils.size(b)) && ArrayUtils.containsAll(a, b)
                 && ArrayUtils.containsAll(b, a);
     }
 
@@ -387,4 +387,4 @@
 
         return sPrime;
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/content/pm/parsing/ApkLite.java b/core/java/android/content/pm/parsing/ApkLite.java
index 5ffb958..269bec2 100644
--- a/core/java/android/content/pm/parsing/ApkLite.java
+++ b/core/java/android/content/pm/parsing/ApkLite.java
@@ -133,6 +133,11 @@
      */
     private final boolean mHasDeviceAdminReceiver;
 
+    /**
+     * Indicates if this apk is a sdk.
+     */
+    private final boolean mIsSdkLibrary;
+
     public ApkLite(String path, String packageName, String splitName, boolean isFeatureSplit,
             String configForSplit, String usesSplitName, boolean isSplitRequired, int versionCode,
             int versionCodeMajor, int revisionCode, int installLocation,
@@ -143,7 +148,7 @@
             String requiredSystemPropertyName, String requiredSystemPropertyValue,
             int minSdkVersion, int targetSdkVersion, int rollbackDataPolicy,
             Set<String> requiredSplitTypes, Set<String> splitTypes,
-            boolean hasDeviceAdminReceiver) {
+            boolean hasDeviceAdminReceiver, boolean isSdkLibrary) {
         mPath = path;
         mPackageName = packageName;
         mSplitName = splitName;
@@ -176,6 +181,7 @@
         mTargetSdkVersion = targetSdkVersion;
         mRollbackDataPolicy = rollbackDataPolicy;
         mHasDeviceAdminReceiver = hasDeviceAdminReceiver;
+        mIsSdkLibrary = isSdkLibrary;
     }
 
     /**
@@ -473,11 +479,19 @@
         return mHasDeviceAdminReceiver;
     }
 
+    /**
+     * Indicates if this apk is a sdk.
+     */
+    @DataClass.Generated.Member
+    public boolean isIsSdkLibrary() {
+        return mIsSdkLibrary;
+    }
+
     @DataClass.Generated(
-            time = 1635266936769L,
+            time = 1643063342990L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java",
-            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final  int mRollbackDataPolicy\nprivate final  boolean mHasDeviceAdminReceiver\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final  int mRollbackDataPolicy\nprivate final  boolean mHasDeviceAdminReceiver\nprivate final  boolean mIsSdkLibrary\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 165cae8..5680bcd 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -87,6 +87,7 @@
     private static final String TAG_USES_SDK = "uses-sdk";
     private static final String TAG_USES_SPLIT = "uses-split";
     private static final String TAG_MANIFEST = "manifest";
+    private static final String TAG_SDK_LIBRARY = "sdk-library";
     private static final int SDK_VERSION = Build.VERSION.SDK_INT;
     private static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES;
 
@@ -449,6 +450,8 @@
 
         boolean hasDeviceAdminReceiver = false;
 
+        boolean isSdkLibrary = false;
+
         // Only search the tree when the tag is the direct child of <manifest> tag
         int type;
         final int searchDepth = parser.getDepth() + 1;
@@ -506,6 +509,8 @@
                     } else if (TAG_RECEIVER.equals(parser.getName())) {
                         hasDeviceAdminReceiver |= isDeviceAdminReceiver(
                                 parser, hasBindDeviceAdminPermission);
+                    } else if (TAG_SDK_LIBRARY.equals(parser.getName())) {
+                        isSdkLibrary = true;
                     }
                 }
             } else if (TAG_OVERLAY.equals(parser.getName())) {
@@ -598,7 +603,7 @@
                         overlayIsStatic, overlayPriority, requiredSystemPropertyName,
                         requiredSystemPropertyValue, minSdkVersion, targetSdkVersion,
                         rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second,
-                        hasDeviceAdminReceiver));
+                        hasDeviceAdminReceiver, isSdkLibrary));
     }
 
     private static boolean isDeviceAdminReceiver(
diff --git a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
index 8b86a16..a65b681 100644
--- a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
@@ -379,6 +379,30 @@
     }
 
     /**
+     * Computes the maxSdkVersion. If the package is not compatible with this platform, populates
+     * {@code outError[0]} with an error message.
+     * <p>
+     * {@code maxVers} is compared against {@code platformSdkVersion}. If {@code maxVers} is less
+     * than the {@code platformSdkVersion} then populates {@code outError[0]} with an error message.
+     * Otherwise, it returns {@code maxVers} unmodified.
+     *
+     * @param maxVers maxSdkVersion number, if specified in the application manifest, or {@code
+     *                Integer.MAX_VALUE} otherwise
+     * @param platformSdkVersion   platform SDK version number, typically Build.VERSION.SDK_INT
+     * @return the maxSdkVersion that was recognised or an error if the condition is not satisfied
+     */
+    public static ParseResult<Integer> computeMaxSdkVersion(@IntRange(from = 0) int maxVers,
+            @IntRange(from = 1) int platformSdkVersion, @NonNull ParseInput input) {
+        if (platformSdkVersion > maxVers) {
+            return input.error(PackageManager.INSTALL_FAILED_NEWER_SDK,
+                    "Requires max SDK version " + maxVers + " but is "
+                            + platformSdkVersion);
+        } else {
+            return input.success(maxVers);
+        }
+    }
+
+    /**
      * Matches a given {@code targetCode} against a set of release codeNames. Target codes can
      * either be of the form {@code [codename]}" (e.g {@code "Q"}) or of the form {@code
      * [codename].[fingerprint]} (e.g {@code "Q.cafebc561"}).
diff --git a/core/java/android/content/pm/parsing/PackageLite.java b/core/java/android/content/pm/parsing/PackageLite.java
index 5f5e812..e2789c9 100644
--- a/core/java/android/content/pm/parsing/PackageLite.java
+++ b/core/java/android/content/pm/parsing/PackageLite.java
@@ -105,6 +105,10 @@
      * or locally compiled variants.
      */
     private final boolean mUseEmbeddedDex;
+    /**
+     * Indicates if this package is a sdk.
+     */
+    private final boolean mIsSdkLibrary;
 
     public PackageLite(String path, String baseApkPath, ApkLite baseApk,
             String[] splitNames, boolean[] isFeatureSplits, String[] usesSplitNames,
@@ -131,6 +135,7 @@
         mRequiredSplitTypes = requiredSplitTypes;
         mSplitRequired = (baseApk.isSplitRequired() || hasAnyRequiredSplitTypes());
         mProfileableByShell = baseApk.isProfileableByShell();
+        mIsSdkLibrary = baseApk.isIsSdkLibrary();
         mSplitNames = splitNames;
         mSplitTypes = splitTypes;
         mIsFeatureSplits = isFeatureSplits;
@@ -401,11 +406,20 @@
         return mUseEmbeddedDex;
     }
 
+    /**
+     * Indicates if this package is a sdk.
+     */
+    @DataClass.Generated.Member
+    public boolean isIsSdkLibrary() {
+        return mIsSdkLibrary;
+    }
+
     @DataClass.Generated(
-            time = 1628562559343L,
+            time = 1643132127068L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java",
-            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mTargetSdk\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+            inputSignatures =
+                    "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mTargetSdk\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\nprivate final  boolean mIsSdkLibrary\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/hardware/CameraSessionStats.java b/core/java/android/hardware/CameraSessionStats.java
index f34e2bf..698cc76 100644
--- a/core/java/android/hardware/CameraSessionStats.java
+++ b/core/java/android/hardware/CameraSessionStats.java
@@ -59,6 +59,7 @@
     private long mRequestCount;
     private long mResultErrorCount;
     private boolean mDeviceError;
+    private float mMaxPreviewFps;
     private ArrayList<CameraStreamStats> mStreamStats;
 
     public CameraSessionStats() {
@@ -67,6 +68,7 @@
         mApiLevel = -1;
         mIsNdk = false;
         mLatencyMs = -1;
+        mMaxPreviewFps = 0;
         mSessionType = -1;
         mInternalReconfigure = -1;
         mRequestCount = 0;
@@ -77,7 +79,7 @@
 
     public CameraSessionStats(String cameraId, int facing, int newCameraState,
             String clientName, int apiLevel, boolean isNdk, int creationDuration,
-            int sessionType, int internalReconfigure) {
+            float maxPreviewFps, int sessionType, int internalReconfigure) {
         mCameraId = cameraId;
         mFacing = facing;
         mNewCameraState = newCameraState;
@@ -85,6 +87,7 @@
         mApiLevel = apiLevel;
         mIsNdk = isNdk;
         mLatencyMs = creationDuration;
+        mMaxPreviewFps = maxPreviewFps;
         mSessionType = sessionType;
         mInternalReconfigure = internalReconfigure;
         mStreamStats = new ArrayList<CameraStreamStats>();
@@ -121,6 +124,7 @@
         dest.writeInt(mApiLevel);
         dest.writeBoolean(mIsNdk);
         dest.writeInt(mLatencyMs);
+        dest.writeFloat(mMaxPreviewFps);
         dest.writeInt(mSessionType);
         dest.writeInt(mInternalReconfigure);
         dest.writeLong(mRequestCount);
@@ -137,6 +141,7 @@
         mApiLevel = in.readInt();
         mIsNdk = in.readBoolean();
         mLatencyMs = in.readInt();
+        mMaxPreviewFps = in.readFloat();
         mSessionType = in.readInt();
         mInternalReconfigure = in.readInt();
         mRequestCount = in.readLong();
@@ -176,6 +181,10 @@
         return mLatencyMs;
     }
 
+    public float getMaxPreviewFps() {
+        return mMaxPreviewFps;
+    }
+
     public int getSessionType() {
         return mSessionType;
     }
diff --git a/core/java/android/hardware/CameraStreamStats.java b/core/java/android/hardware/CameraStreamStats.java
index 823d454..3952467 100644
--- a/core/java/android/hardware/CameraStreamStats.java
+++ b/core/java/android/hardware/CameraStreamStats.java
@@ -15,8 +15,8 @@
  */
 package android.hardware;
 
-import android.hardware.camera2.params.DynamicRangeProfiles;
 import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.params.DynamicRangeProfiles;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
@@ -37,6 +37,7 @@
     private int mWidth;
     private int mHeight;
     private int mFormat;
+    private float mMaxPreviewFps;
     private int mDataSpace;
     private long mUsage;
     private long mRequestCount;
@@ -48,7 +49,7 @@
     private float[] mHistogramBins;
     private long[] mHistogramCounts;
     private long mDynamicRangeProfile;
-    private int mStreamUseCase;
+    private long mStreamUseCase;
 
     private static final String TAG = "CameraStreamStats";
 
@@ -56,6 +57,7 @@
         mWidth = 0;
         mHeight = 0;
         mFormat = 0;
+        mMaxPreviewFps = 0;
         mDataSpace = 0;
         mUsage = 0;
         mRequestCount = 0;
@@ -68,13 +70,14 @@
         mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
     }
 
-    public CameraStreamStats(int width, int height, int format,
+    public CameraStreamStats(int width, int height, int format, float maxPreviewFps,
             int dataSpace, long usage, long requestCount, long errorCount,
             int startLatencyMs, int maxHalBuffers, int maxAppBuffers, long dynamicRangeProfile,
-            int streamUseCase) {
+            long streamUseCase) {
         mWidth = width;
         mHeight = height;
         mFormat = format;
+        mMaxPreviewFps = maxPreviewFps;
         mDataSpace = dataSpace;
         mUsage = usage;
         mRequestCount = requestCount;
@@ -120,6 +123,7 @@
         dest.writeInt(mWidth);
         dest.writeInt(mHeight);
         dest.writeInt(mFormat);
+        dest.writeFloat(mMaxPreviewFps);
         dest.writeInt(mDataSpace);
         dest.writeLong(mUsage);
         dest.writeLong(mRequestCount);
@@ -131,13 +135,14 @@
         dest.writeFloatArray(mHistogramBins);
         dest.writeLongArray(mHistogramCounts);
         dest.writeLong(mDynamicRangeProfile);
-        dest.writeInt(mStreamUseCase);
+        dest.writeLong(mStreamUseCase);
     }
 
     public void readFromParcel(Parcel in) {
         mWidth = in.readInt();
         mHeight = in.readInt();
         mFormat = in.readInt();
+        mMaxPreviewFps = in.readFloat();
         mDataSpace = in.readInt();
         mUsage = in.readLong();
         mRequestCount = in.readLong();
@@ -149,7 +154,7 @@
         mHistogramBins = in.createFloatArray();
         mHistogramCounts = in.createLongArray();
         mDynamicRangeProfile = in.readLong();
-        mStreamUseCase = in.readInt();
+        mStreamUseCase = in.readLong();
     }
 
     public int getWidth() {
@@ -164,6 +169,10 @@
         return mFormat;
     }
 
+    public float getMaxPreviewFps() {
+        return mMaxPreviewFps;
+    }
+
     public int getDataSpace() {
         return mDataSpace;
     }
@@ -208,7 +217,7 @@
         return mDynamicRangeProfile;
     }
 
-    public int getStreamUseCase() {
+    public long getStreamUseCase() {
         return mStreamUseCase;
     }
 }
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index abdc64c..d8ebb62 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -298,4 +298,33 @@
      * @hide
      */
     int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
+
+    /**
+     * Whether the FingerprintAcquired message is a signal to turn off HBM
+     */
+    static boolean shouldTurnOffHbm(@FingerprintAcquired int acquiredInfo) {
+        switch (acquiredInfo) {
+            case FINGERPRINT_ACQUIRED_START:
+                // Authentication just began
+                return false;
+            case FINGERPRINT_ACQUIRED_GOOD:
+                // Good image captured. Turn off HBM. Success/Reject comes after, which is when
+                // hideUdfpsOverlay will be called.
+                return true;
+            case FINGERPRINT_ACQUIRED_PARTIAL:
+            case FINGERPRINT_ACQUIRED_INSUFFICIENT:
+            case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
+            case FINGERPRINT_ACQUIRED_TOO_SLOW:
+            case FINGERPRINT_ACQUIRED_TOO_FAST:
+            case FINGERPRINT_ACQUIRED_IMMOBILE:
+            case FINGERPRINT_ACQUIRED_TOO_BRIGHT:
+            case FINGERPRINT_ACQUIRED_VENDOR:
+                // Bad image captured. Turn off HBM. Matcher will not run, so there's no need to
+                // keep HBM on.
+                return true;
+            case FINGERPRINT_ACQUIRED_UNKNOWN:
+            default:
+                return false;
+        }
+    }
 }
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 7bebe1f..b05e6d1 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -3563,8 +3563,8 @@
      */
     @PublicKey
     @NonNull
-    public static final Key<int[]> SCALER_AVAILABLE_STREAM_USE_CASES =
-            new Key<int[]>("android.scaler.availableStreamUseCases", int[].class);
+    public static final Key<long[]> SCALER_AVAILABLE_STREAM_USE_CASES =
+            new Key<long[]>("android.scaler.availableStreamUseCases", long[].class);
 
     /**
      * <p>An array of mandatory stream combinations with stream use cases.
diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
index 465abfb..a3bc665 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -66,7 +66,7 @@
         private final boolean mIsUltraHighResolution;
         private final boolean mIsMaximumSize;
         private final boolean mIs10BitCapable;
-        private final int mStreamUseCase;
+        private final long mStreamUseCase;
 
         /**
          * Create a new {@link MandatoryStreamInformation}.
@@ -168,7 +168,7 @@
          */
         public MandatoryStreamInformation(@NonNull List<Size> availableSizes, @Format int format,
                 boolean isMaximumSize, boolean isInput, boolean isUltraHighResolution,
-                boolean is10BitCapable, @StreamUseCase int streamUseCase) {
+                boolean is10BitCapable, @StreamUseCase long streamUseCase) {
             if (availableSizes.isEmpty()) {
                 throw new IllegalArgumentException("No available sizes");
             }
@@ -308,9 +308,9 @@
          * For {@link MandatoryStreamInformation} belonging to other mandatory stream
          * combinations, the return value will be DEFAULT. </p>
          *
-         * @return the integer stream use case.
+         * @return the long integer stream use case.
          */
-        public @StreamUseCase int getStreamUseCase() {
+        public @StreamUseCase long getStreamUseCase() {
             return mStreamUseCase;
         }
 
@@ -365,15 +365,15 @@
     /**
      * Short hand for stream use cases
      */
-    private static final int STREAM_USE_CASE_PREVIEW =
+    private static final long STREAM_USE_CASE_PREVIEW =
             CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW;
-    private static final int STREAM_USE_CASE_STILL_CAPTURE =
+    private static final long STREAM_USE_CASE_STILL_CAPTURE =
             CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE;
-    private static final int STREAM_USE_CASE_RECORD =
+    private static final long STREAM_USE_CASE_RECORD =
             CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD;
-    private static final int STREAM_USE_CASE_PREVIEW_VIDEO_STILL =
+    private static final long STREAM_USE_CASE_PREVIEW_VIDEO_STILL =
             CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL;
-    private static final int STREAM_USE_CASE_VIDEO_CALL =
+    private static final long STREAM_USE_CASE_VIDEO_CALL =
             CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL;
 
     /**
@@ -471,12 +471,12 @@
     private static final class StreamTemplate {
         public int mFormat;
         public SizeThreshold mSizeThreshold;
-        public int mStreamUseCase;
+        public long mStreamUseCase;
         public StreamTemplate(int format, SizeThreshold sizeThreshold) {
             this(format, sizeThreshold, CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
         }
         public StreamTemplate(@Format int format, @NonNull SizeThreshold sizeThreshold,
-                @StreamUseCase int streamUseCase) {
+                @StreamUseCase long streamUseCase) {
             mFormat = format;
             mSizeThreshold = sizeThreshold;
             mStreamUseCase = streamUseCase;
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 2350b7c..39cb7f3 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -918,9 +918,9 @@
      * @throws IllegalArgumentException If the streamUseCase isn't within the range of valid
      *                                  values.
      */
-    public void setStreamUseCase(@StreamUseCase int streamUseCase) {
+    public void setStreamUseCase(@StreamUseCase long streamUseCase) {
         // Verify that the value is in range
-        int maxUseCaseValue = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL;
+        long maxUseCaseValue = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL;
         if (streamUseCase > maxUseCaseValue &&
                 streamUseCase < CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START) {
             throw new IllegalArgumentException("Not a valid stream use case value " +
@@ -938,7 +938,7 @@
      *
      * @return the currently set stream use case
      */
-    public int getStreamUseCase() {
+    public long getStreamUseCase() {
         return mStreamUseCase;
     }
 
@@ -1067,7 +1067,7 @@
         String physicalCameraId = source.readString();
         boolean isMultiResolutionOutput = source.readInt() == 1;
         int[] sensorPixelModesUsed = source.createIntArray();
-        int streamUseCase = source.readInt();
+        long streamUseCase = source.readLong();
 
         checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
         long dynamicRangeProfile = source.readLong();
@@ -1218,7 +1218,7 @@
         // writeList doesn't seem to work well with Integer list.
         dest.writeIntArray(convertIntegerToIntList(mSensorPixelModesUsed));
         dest.writeLong(mDynamicRangeProfile);
-        dest.writeInt(mStreamUseCase);
+        dest.writeLong(mStreamUseCase);
         dest.writeInt(mTimestampBase);
         dest.writeInt(mMirrorMode);
     }
@@ -1337,7 +1337,7 @@
     // Dynamic range profile
     private long mDynamicRangeProfile;
     // Stream use case
-    private int mStreamUseCase;
+    private long mStreamUseCase;
     // Timestamp base
     private int mTimestampBase;
     // Mirroring mode
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index d9734b4..5981d27 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -781,10 +781,11 @@
      * <li>The fpsMin and fpsMax will be a multiple 30fps.</li>
      * <li>The fpsMin will be no less than 30fps, the fpsMax will be no less than 120fps.</li>
      * <li>At least one range will be a fixed FPS range where fpsMin == fpsMax.</li>
-     * <li>For each fixed FPS range, there will be one corresponding variable FPS range [30,
-     * fps_max]. These kinds of FPS ranges are suitable for preview-only use cases where the
-     * application doesn't want the camera device always produce higher frame rate than the display
-     * refresh rate.</li>
+     * <li>For each fixed FPS range, there will be one corresponding variable FPS range
+     * [30, fps_max] or [60, fps_max]. These kinds of FPS ranges are suitable for preview-only
+     * use cases where the application doesn't want the camera device always produce higher frame
+     * rate than the display refresh rate. Both 30fps and 60fps preview rate will not be
+     * supported for the same recording rate.</li>
      * </p>
      *
      * @return an array of supported high speed video recording FPS ranges The upper bound of
diff --git a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl
index 648edda..3cca1b3 100644
--- a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl
+++ b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl
@@ -28,9 +28,10 @@
     // Hides the overlay.
     void hideUdfpsOverlay(int sensorId);
 
-    // Good image captured. Turn off HBM. Success/Reject comes after, which is when hideUdfpsOverlay
-    // will be called.
-    void onAcquiredGood(int sensorId);
+    // Check acquiredInfo for the acquired type (BiometricFingerprintConstants#FingerprintAcquired).
+    // Check BiometricFingerprintConstants#shouldTurnOffHbm for whether the acquiredInfo
+    // should turn off HBM.
+    void onAcquired(int sensorId, int acquiredInfo);
 
     // Notifies of enrollment progress changes.
     void onEnrollmentProgress(int sensorId, int remaining);
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index af57f79..02302a2 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -40,6 +40,7 @@
 
 import com.android.internal.inputmethod.CancellationGroup;
 import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.view.IInlineSuggestionsRequestCallback;
@@ -70,7 +71,7 @@
     private static final int DO_SET_INPUT_CONTEXT = 20;
     private static final int DO_UNSET_INPUT_CONTEXT = 30;
     private static final int DO_START_INPUT = 32;
-    private static final int DO_ON_SHOULD_SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN_CHANGED = 35;
+    private static final int DO_ON_NAV_BUTTON_FLAGS_CHANGED = 35;
     private static final int DO_CREATE_SESSION = 40;
     private static final int DO_SET_SESSION_ENABLED = 45;
     private static final int DO_SHOW_SOFT_INPUT = 60;
@@ -176,7 +177,7 @@
                 try {
                     inputMethod.initializeInternal((IBinder) args.arg1,
                             (IInputMethodPrivilegedOperations) args.arg2, msg.arg1,
-                            (boolean) args.arg3, msg.arg2 != 0);
+                            (boolean) args.arg3, msg.arg2);
                 } finally {
                     args.recycle();
                 }
@@ -196,22 +197,20 @@
                 final EditorInfo info = (EditorInfo) args.arg3;
                 final CancellationGroup cancellationGroup = (CancellationGroup) args.arg4;
                 final boolean restarting = args.argi5 == 1;
-                final boolean shouldShowImeSwitcherWhenImeIsShown = args.argi6 != 0;
+                @InputMethodNavButtonFlags
+                final int navButtonFlags = args.argi6;
                 final InputConnection ic = inputContext != null
                         ? new RemoteInputConnection(mTarget, inputContext, cancellationGroup)
                         : null;
                 info.makeCompatible(mTargetSdkVersion);
                 inputMethod.dispatchStartInputWithToken(ic, info, restarting, startInputToken,
-                        shouldShowImeSwitcherWhenImeIsShown);
+                        navButtonFlags);
                 args.recycle();
                 return;
             }
-            case DO_ON_SHOULD_SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN_CHANGED: {
-                final boolean shouldShowImeSwitcherWhenImeIsShown = msg.arg1 != 0;
-                inputMethod.onShouldShowImeSwitcherWhenImeIsShownChanged(
-                        shouldShowImeSwitcherWhenImeIsShown);
+            case DO_ON_NAV_BUTTON_FLAGS_CHANGED:
+                inputMethod.onNavButtonFlagsChanged(msg.arg1);
                 return;
-            }
             case DO_CREATE_SESSION: {
                 SomeArgs args = (SomeArgs)msg.obj;
                 inputMethod.createSession(new InputMethodSessionCallbackWrapper(
@@ -301,10 +300,9 @@
     @Override
     public void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privOps,
             int configChanges, boolean stylusHwSupported,
-            boolean shouldShowImeSwitcherWhenImeIsShown) {
+            @InputMethodNavButtonFlags int navButtonFlags) {
         mCaller.executeOrSendMessage(mCaller.obtainMessageIIOOO(DO_INITIALIZE_INTERNAL,
-                configChanges, shouldShowImeSwitcherWhenImeIsShown ? 1 : 0, token, privOps,
-                stylusHwSupported));
+                configChanges, navButtonFlags, token, privOps, stylusHwSupported));
     }
 
     @BinderThread
@@ -344,23 +342,21 @@
     @BinderThread
     @Override
     public void startInput(IBinder startInputToken, IInputContext inputContext,
-            EditorInfo attribute, boolean restarting, boolean shouldShowImeSwitcherWhenImeIsShown) {
+            EditorInfo attribute, boolean restarting,
+            @InputMethodNavButtonFlags int navButtonFlags) {
         if (mCancellationGroup == null) {
             Log.e(TAG, "startInput must be called after bindInput.");
             mCancellationGroup = new CancellationGroup();
         }
         mCaller.executeOrSendMessage(mCaller.obtainMessageOOOOII(DO_START_INPUT, startInputToken,
-                inputContext, attribute, mCancellationGroup, restarting ? 1 : 0,
-                shouldShowImeSwitcherWhenImeIsShown ? 1 : 0));
+                inputContext, attribute, mCancellationGroup, restarting ? 1 : 0, navButtonFlags));
     }
 
     @BinderThread
     @Override
-    public void onShouldShowImeSwitcherWhenImeIsShownChanged(
-            boolean shouldShowImeSwitcherWhenImeIsShown) {
-        mCaller.executeOrSendMessage(mCaller.obtainMessageI(
-                DO_ON_SHOULD_SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN_CHANGED,
-                shouldShowImeSwitcherWhenImeIsShown ? 1 : 0));
+    public void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
+        mCaller.executeOrSendMessage(
+                mCaller.obtainMessageI(DO_ON_NAV_BUTTON_FLAGS_CHANGED, navButtonFlags));
     }
 
     @BinderThread
diff --git a/core/java/android/inputmethodservice/ImsConfigurationTracker.java b/core/java/android/inputmethodservice/ImsConfigurationTracker.java
index 3c78888..30ef0a2 100644
--- a/core/java/android/inputmethodservice/ImsConfigurationTracker.java
+++ b/core/java/android/inputmethodservice/ImsConfigurationTracker.java
@@ -63,8 +63,9 @@
      */
     @MainThread
     public void onBindInput(@Nullable Resources resources) {
-        Preconditions.checkState(mInitialized,
-                "onBindInput can be called only after onInitialize().");
+        if (!mInitialized) {
+            return;
+        }
         if (mLastKnownConfig == null && resources != null) {
             mLastKnownConfig = new Configuration(resources.getConfiguration());
         }
diff --git a/core/java/android/inputmethodservice/InkWindow.java b/core/java/android/inputmethodservice/InkWindow.java
index 499634a..8289c26 100644
--- a/core/java/android/inputmethodservice/InkWindow.java
+++ b/core/java/android/inputmethodservice/InkWindow.java
@@ -27,6 +27,8 @@
 import android.os.IBinder;
 import android.util.Slog;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 
 import com.android.internal.policy.PhoneWindow;
@@ -40,6 +42,9 @@
 
     private final WindowManager mWindowManager;
     private boolean mIsViewAdded;
+    private View mInkView;
+    private InkVisibilityListener mInkViewVisibilityListener;
+    private ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener;
 
     public InkWindow(@NonNull Context context) {
         super(context);
@@ -102,4 +107,77 @@
         lp.token = token;
         setAttributes(lp);
     }
+
+    @Override
+    public void addContentView(View view, ViewGroup.LayoutParams params) {
+        if (mInkView == null) {
+            mInkView = view;
+        } else if (mInkView != view) {
+            throw new IllegalStateException("Only one Child Inking view is permitted.");
+        }
+        super.addContentView(view, params);
+        initInkViewVisibilityListener();
+    }
+
+    @Override
+    public void setContentView(View view, ViewGroup.LayoutParams params) {
+        mInkView = view;
+        super.setContentView(view, params);
+        initInkViewVisibilityListener();
+    }
+
+    @Override
+    public void setContentView(View view) {
+        mInkView = view;
+        super.setContentView(view);
+        initInkViewVisibilityListener();
+    }
+
+    @Override
+    public void clearContentView() {
+        if (mGlobalLayoutListener != null && mInkView != null) {
+            mInkView.getViewTreeObserver().removeOnGlobalLayoutListener(mGlobalLayoutListener);
+        }
+        mGlobalLayoutListener = null;
+        mInkView = null;
+        super.clearContentView();
+    }
+
+    /**
+    * Listener used by InkWindow to time the dispatching of {@link MotionEvent}s to Ink view, once
+    * it is visible to user.
+    */
+    interface InkVisibilityListener {
+        void onInkViewVisible();
+    }
+
+    void setInkViewVisibilityListener(InkVisibilityListener listener) {
+        mInkViewVisibilityListener = listener;
+        initInkViewVisibilityListener();
+    }
+
+    void initInkViewVisibilityListener() {
+        if (mInkView == null || mInkViewVisibilityListener == null
+                || mGlobalLayoutListener != null) {
+            return;
+        }
+        mGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                if (mInkView.isVisibleToUser()) {
+                    if (mInkViewVisibilityListener != null) {
+                        mInkViewVisibilityListener.onInkViewVisible();
+                    }
+                    mInkView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                    mGlobalLayoutListener = null;
+                }
+            }
+        };
+        mInkView.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalLayoutListener);
+    }
+
+    boolean isInkViewVisible() {
+        return getDecorView().getVisibility() == View.VISIBLE
+                && mInkView != null && mInkView.isVisibleToUser();
+    }
 }
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index fbc0732..b46bb32 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -140,8 +140,10 @@
 import com.android.internal.inputmethod.IInputContentUriToken;
 import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
 import com.android.internal.inputmethod.ImeTracing;
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
 import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
 import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
+import com.android.internal.util.RingBuffer;
 import com.android.internal.view.IInlineSuggestionsRequestCallback;
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.InlineSuggestionsRequestInfo;
@@ -333,6 +335,17 @@
             "persist.sys.ime.can_render_gestural_nav_buttons";
 
     /**
+     * Number of {@link MotionEvent} to buffer if IME is not ready with Ink view.
+     * This number may be configured eventually based on device's touch sampling frequency.
+     */
+    private static final int MAX_EVENTS_BUFFER = 500;
+
+    /**
+     * A circular buffer of size MAX_EVENTS_BUFFER in case IME is taking too long to add ink view.
+     **/
+    private RingBuffer<MotionEvent> mPendingEvents;
+
+    /**
      * Returns whether {@link InputMethodService} is responsible for rendering the back button and
      * the IME switcher button or not when the gestural navigation is enabled.
      *
@@ -347,7 +360,7 @@
      */
     @AnyThread
     public static boolean canImeRenderGesturalNavButtons() {
-        return SystemProperties.getBoolean(PROP_CAN_RENDER_GESTURAL_NAV_BUTTONS, false);
+        return SystemProperties.getBoolean(PROP_CAN_RENDER_GESTURAL_NAV_BUTTONS, true);
     }
 
     /**
@@ -660,7 +673,7 @@
         @Override
         public final void initializeInternal(@NonNull IBinder token,
                 IInputMethodPrivilegedOperations privilegedOperations, int configChanges,
-                boolean stylusHwSupported, boolean shouldShowImeSwitcherWhenImeIsShown) {
+                boolean stylusHwSupported, @InputMethodNavButtonFlags int navButtonFlags) {
             if (mDestroyed) {
                 Log.i(TAG, "The InputMethodService has already onDestroyed()."
                     + "Ignore the initialization.");
@@ -673,8 +686,7 @@
             if (stylusHwSupported) {
                 mInkWindow = new InkWindow(mWindow.getContext());
             }
-            mNavigationBarController.setShouldShowImeSwitcherWhenImeIsShown(
-                    shouldShowImeSwitcherWhenImeIsShown);
+            mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags);
             attachToken(token);
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
@@ -784,10 +796,9 @@
         @Override
         public final void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
                 @NonNull EditorInfo editorInfo, boolean restarting,
-                @NonNull IBinder startInputToken, boolean shouldShowImeSwitcherWhenImeIsShown) {
+                @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags) {
             mPrivOps.reportStartInputAsync(startInputToken);
-            mNavigationBarController.setShouldShowImeSwitcherWhenImeIsShown(
-                    shouldShowImeSwitcherWhenImeIsShown);
+            mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags);
             if (restarting) {
                 restartInput(inputConnection, editorInfo);
             } else {
@@ -801,10 +812,8 @@
          */
         @MainThread
         @Override
-        public void onShouldShowImeSwitcherWhenImeIsShownChanged(
-                boolean shouldShowImeSwitcherWhenImeIsShown) {
-            mNavigationBarController.setShouldShowImeSwitcherWhenImeIsShown(
-                    shouldShowImeSwitcherWhenImeIsShown);
+        public void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
+            mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags);
         }
 
         /**
@@ -957,7 +966,8 @@
             mInkWindow.show();
 
             // deliver previous @param stylusEvents
-            stylusEvents.forEach(mInkWindow.getDecorView()::dispatchTouchEvent);
+            stylusEvents.forEach(InputMethodService.this::onStylusHandwritingMotionEvent);
+
             // create receiver for channel
             mHandwritingEventReceiver = new SimpleBatchedInputEventReceiver(
                     channel,
@@ -966,11 +976,11 @@
                         if (!(event instanceof MotionEvent)) {
                             return false;
                         }
-                        return mInkWindow.getDecorView().dispatchTouchEvent((MotionEvent) event);
+                        onStylusHandwritingMotionEvent((MotionEvent) event);
+                        return true;
                     });
         }
 
-
         /**
          * {@inheritDoc}
          * @hide
@@ -2360,7 +2370,8 @@
      *
      * If the IME supports handwriting for the current input, it should return {@code true},
      * ensure its inking views are attached to the {@link #getStylusHandwritingWindow()}, and handle
-     * stylus input received on the ink window via {@link #getCurrentInputConnection()}.
+     * stylus input received from {@link #onStylusHandwritingMotionEvent(MotionEvent)} on the
+     * {@link #getStylusHandwritingWindow()} via {@link #getCurrentInputConnection()}.
      * @return {@code true} if IME can honor the request, {@code false} if IME cannot at this time.
      */
     public boolean onStartStylusHandwriting() {
@@ -2369,6 +2380,33 @@
     }
 
     /**
+     * Called after {@link #onStartStylusHandwriting()} returns {@code true} for every Stylus
+     * {@link MotionEvent}.
+     * By default, this method forwards all {@link MotionEvent}s to the
+     * {@link #getStylusHandwritingWindow()} once its visible, however IME can override it to
+     * receive them sooner.
+     * @param motionEvent {@link MotionEvent} from stylus.
+     */
+    public void onStylusHandwritingMotionEvent(@NonNull MotionEvent motionEvent) {
+        if (mInkWindow.isInkViewVisible()) {
+            mInkWindow.getDecorView().dispatchTouchEvent(motionEvent);
+        } else {
+            if (mPendingEvents == null) {
+                mPendingEvents = new RingBuffer(MotionEvent.class, MAX_EVENTS_BUFFER);
+            }
+            mPendingEvents.append(motionEvent);
+            mInkWindow.setInkViewVisibilityListener(() -> {
+                if (mPendingEvents != null && !mPendingEvents.isEmpty()) {
+                    for (MotionEvent event : mPendingEvents.toArray()) {
+                        mInkWindow.getDecorView().dispatchTouchEvent(event);
+                    }
+                    mPendingEvents.clear();
+                }
+            });
+        }
+    }
+
+    /**
      * Called when the current stylus handwriting session was finished (either by the system or
      * via {@link #finishStylusHandwriting()}.
      *
diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java
index 19fa01d..0f9075b 100644
--- a/core/java/android/inputmethodservice/NavigationBarController.java
+++ b/core/java/android/inputmethodservice/NavigationBarController.java
@@ -16,7 +16,6 @@
 
 package android.inputmethodservice;
 
-import static android.content.Intent.ACTION_OVERLAY_CHANGED;
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
 
 import android.animation.ValueAnimator;
@@ -24,18 +23,12 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.StatusBarManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.inputmethodservice.navigationbar.NavigationBarFrame;
 import android.inputmethodservice.navigationbar.NavigationBarView;
-import android.os.PatternMatcher;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -49,6 +42,8 @@
 import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
 
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
+
 import java.util.Objects;
 
 /**
@@ -77,8 +72,7 @@
         default void onDestroy() {
         }
 
-        default void setShouldShowImeSwitcherWhenImeIsShown(
-                boolean shouldShowImeSwitcherWhenImeIsShown) {
+        default void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
         }
 
         default String toDebugString() {
@@ -117,8 +111,8 @@
         mImpl.onDestroy();
     }
 
-    void setShouldShowImeSwitcherWhenImeIsShown(boolean shouldShowImeSwitcherWhenImeIsShown) {
-        mImpl.setShouldShowImeSwitcherWhenImeIsShown(shouldShowImeSwitcherWhenImeIsShown);
+    void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
+        mImpl.onNavButtonFlagsChanged(navButtonFlags);
     }
 
     String toDebugString() {
@@ -144,9 +138,6 @@
         @Nullable
         Insets mLastInsets;
 
-        @Nullable
-        private BroadcastReceiver mSystemOverlayChangedReceiver;
-
         private boolean mShouldShowImeSwitcherWhenImeIsShown;
 
         @Appearance
@@ -359,14 +350,6 @@
             });
         }
 
-        private boolean imeDrawsImeNavBar() {
-            final Resources resources = mService.getResources();
-            if (resources == null) {
-                return false;
-            }
-            return resources.getBoolean(com.android.internal.R.bool.config_imeDrawsImeNavBar);
-        }
-
         @Override
         public void onSoftInputWindowCreated(@NonNull SoftInputWindow softInputWindow) {
             final Window window = softInputWindow.getWindow();
@@ -379,27 +362,6 @@
             if (mDestroyed) {
                 return;
             }
-            mImeDrawsImeNavBar = imeDrawsImeNavBar();
-            if (mSystemOverlayChangedReceiver == null) {
-                final IntentFilter intentFilter = new IntentFilter(ACTION_OVERLAY_CHANGED);
-                intentFilter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
-                intentFilter.addDataSchemeSpecificPart("android", PatternMatcher.PATTERN_LITERAL);
-                mSystemOverlayChangedReceiver = new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        if (mDestroyed) {
-                            return;
-                        }
-                        mImeDrawsImeNavBar = imeDrawsImeNavBar();
-                        if (mImeDrawsImeNavBar) {
-                            installNavigationBarFrameIfNecessary();
-                        } else {
-                            uninstallNavigationBarFrameIfNecessary();
-                        }
-                    }
-                };
-                mService.registerReceiver(mSystemOverlayChangedReceiver, intentFilter);
-            }
             installNavigationBarFrameIfNecessary();
         }
 
@@ -412,10 +374,6 @@
                 mTintAnimator.cancel();
                 mTintAnimator = null;
             }
-            if (mSystemOverlayChangedReceiver != null) {
-                mService.unregisterReceiver(mSystemOverlayChangedReceiver);
-                mSystemOverlayChangedReceiver = null;
-            }
             mDestroyed = true;
         }
 
@@ -448,28 +406,43 @@
         }
 
         @Override
-        public void setShouldShowImeSwitcherWhenImeIsShown(
-                boolean shouldShowImeSwitcherWhenImeIsShown) {
+        public void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
             if (mDestroyed) {
                 return;
             }
-            if (mShouldShowImeSwitcherWhenImeIsShown == shouldShowImeSwitcherWhenImeIsShown) {
-                return;
-            }
+
+            final boolean imeDrawsImeNavBar =
+                    (navButtonFlags & InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR) != 0;
+            final boolean shouldShowImeSwitcherWhenImeIsShown =
+                    (navButtonFlags & InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN)
+                    != 0;
+
+            mImeDrawsImeNavBar = imeDrawsImeNavBar;
+            final boolean prevShouldShowImeSwitcherWhenImeIsShown =
+                    mShouldShowImeSwitcherWhenImeIsShown;
             mShouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherWhenImeIsShown;
 
-            if (mNavigationBarFrame == null) {
-                return;
+            if (imeDrawsImeNavBar) {
+                installNavigationBarFrameIfNecessary();
+                if (mNavigationBarFrame == null) {
+                    return;
+                }
+                if (mShouldShowImeSwitcherWhenImeIsShown
+                        == prevShouldShowImeSwitcherWhenImeIsShown) {
+                    return;
+                }
+                final NavigationBarView navigationBarView = mNavigationBarFrame.findViewByPredicate(
+                        NavigationBarView.class::isInstance);
+                if (navigationBarView == null) {
+                    return;
+                }
+                final int hints = StatusBarManager.NAVIGATION_HINT_BACK_ALT
+                        | (shouldShowImeSwitcherWhenImeIsShown
+                                ? StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN : 0);
+                navigationBarView.setNavigationIconHints(hints);
+            } else {
+                uninstallNavigationBarFrameIfNecessary();
             }
-            final NavigationBarView navigationBarView =
-                    mNavigationBarFrame.findViewByPredicate(NavigationBarView.class::isInstance);
-            if (navigationBarView == null) {
-                return;
-            }
-            final int hints = StatusBarManager.NAVIGATION_HINT_BACK_ALT
-                    | (shouldShowImeSwitcherWhenImeIsShown
-                    ? StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN : 0);
-            navigationBarView.setNavigationIconHints(hints);
         }
 
         @Override
diff --git a/core/java/android/inputmethodservice/navigationbar/ButtonDispatcher.java b/core/java/android/inputmethodservice/navigationbar/ButtonDispatcher.java
index 3f26fa4..6b2db7d 100644
--- a/core/java/android/inputmethodservice/navigationbar/ButtonDispatcher.java
+++ b/core/java/android/inputmethodservice/navigationbar/ButtonDispatcher.java
@@ -67,7 +67,7 @@
         }
     };
 
-    public ButtonDispatcher(int id) {
+    ButtonDispatcher(int id) {
         mId = id;
     }
 
@@ -125,8 +125,8 @@
 
     public void setImageDrawable(KeyButtonDrawable drawable) {
         mImageDrawable = drawable;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
+        final int numViews = mViews.size();
+        for (int i = 0; i < numViews; i++) {
             if (mViews.get(i) instanceof ButtonInterface) {
                 ((ButtonInterface) mViews.get(i)).setImageDrawable(mImageDrawable);
             }
@@ -143,8 +143,8 @@
         }
 
         mVisibility = visibility;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
+        final int numViews = mViews.size();
+        for (int i = 0; i < numViews; i++) {
             mViews.get(i).setVisibility(mVisibility);
         }
     }
@@ -188,8 +188,8 @@
             int nextAlpha = (int) (alpha * 255);
             if (prevAlpha != nextAlpha) {
                 mAlpha = nextAlpha / 255f;
-                final int N = mViews.size();
-                for (int i = 0; i < N; i++) {
+                final int numViews = mViews.size();
+                for (int i = 0; i < numViews; i++) {
                     mViews.get(i).setAlpha(mAlpha);
                 }
             }
@@ -198,8 +198,8 @@
 
     public void setDarkIntensity(float darkIntensity) {
         mDarkIntensity = darkIntensity;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
+        final int numViews = mViews.size();
+        for (int i = 0; i < numViews; i++) {
             if (mViews.get(i) instanceof ButtonInterface) {
                 ((ButtonInterface) mViews.get(i)).setDarkIntensity(darkIntensity);
             }
@@ -208,8 +208,8 @@
 
     public void setDelayTouchFeedback(boolean delay) {
         mDelayTouchFeedback = delay;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
+        final int numViews = mViews.size();
+        for (int i = 0; i < numViews; i++) {
             if (mViews.get(i) instanceof ButtonInterface) {
                 ((ButtonInterface) mViews.get(i)).setDelayTouchFeedback(delay);
             }
@@ -218,55 +218,55 @@
 
     public void setOnClickListener(View.OnClickListener clickListener) {
         mClickListener = clickListener;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
+        final int numViews = mViews.size();
+        for (int i = 0; i < numViews; i++) {
             mViews.get(i).setOnClickListener(mClickListener);
         }
     }
 
     public void setOnTouchListener(View.OnTouchListener touchListener) {
         mTouchListener = touchListener;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
+        final int numViews = mViews.size();
+        for (int i = 0; i < numViews; i++) {
             mViews.get(i).setOnTouchListener(mTouchListener);
         }
     }
 
     public void setLongClickable(boolean isLongClickable) {
         mLongClickable = isLongClickable;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
+        final int numViews = mViews.size();
+        for (int i = 0; i < numViews; i++) {
             mViews.get(i).setLongClickable(mLongClickable);
         }
     }
 
     public void setOnLongClickListener(View.OnLongClickListener longClickListener) {
         mLongClickListener = longClickListener;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
+        final int numViews = mViews.size();
+        for (int i = 0; i < numViews; i++) {
             mViews.get(i).setOnLongClickListener(mLongClickListener);
         }
     }
 
     public void setOnHoverListener(View.OnHoverListener hoverListener) {
         mOnHoverListener = hoverListener;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
+        final int numViews = mViews.size();
+        for (int i = 0; i < numViews; i++) {
             mViews.get(i).setOnHoverListener(mOnHoverListener);
         }
     }
 
     public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
         mAccessibilityDelegate = delegate;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
+        final int numViews = mViews.size();
+        for (int i = 0; i < numViews; i++) {
             mViews.get(i).setAccessibilityDelegate(delegate);
         }
     }
 
     public void setTranslation(int x, int y, int z) {
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
+        final int numViews = mViews.size();
+        for (int i = 0; i < numViews; i++) {
             final View view = mViews.get(i);
             view.setTranslationX(x);
             view.setTranslationY(y);
diff --git a/core/java/android/inputmethodservice/navigationbar/DeadZone.java b/core/java/android/inputmethodservice/navigationbar/DeadZone.java
index 4adc84b..4cfd813 100644
--- a/core/java/android/inputmethodservice/navigationbar/DeadZone.java
+++ b/core/java/android/inputmethodservice/navigationbar/DeadZone.java
@@ -82,7 +82,7 @@
         }
     };
 
-    public DeadZone(NavigationBarView view) {
+    DeadZone(NavigationBarView view) {
         mNavigationBarView = view;
         onConfigurationChanged(Surface.ROTATION_0);
     }
@@ -92,13 +92,15 @@
     }
 
     private float getSize(long now) {
-        if (mSizeMax == 0)
+        if (mSizeMax == 0) {
             return 0;
+        }
         long dt = (now - mLastPokeTime);
-        if (dt > mHold + mDecay)
+        if (dt > mHold + mDecay) {
             return mSizeMin;
-        if (dt < mHold)
+        } else if (dt < mHold) {
             return mSizeMax;
+        }
         return (int) lerp(mSizeMax, mSizeMin, (float) (dt - mHold) / mDecay);
     }
 
@@ -177,8 +179,9 @@
 
     private void poke(MotionEvent event) {
         mLastPokeTime = event.getEventTime();
-        if (DEBUG)
+        if (DEBUG) {
             Log.v(TAG, "poked! size=" + getSize(mLastPokeTime));
+        }
         if (mShouldFlash) mNavigationBarView.postInvalidate();
     }
 
diff --git a/core/java/android/inputmethodservice/navigationbar/KeyButtonDrawable.java b/core/java/android/inputmethodservice/navigationbar/KeyButtonDrawable.java
index 25a443d..45c8a18 100644
--- a/core/java/android/inputmethodservice/navigationbar/KeyButtonDrawable.java
+++ b/core/java/android/inputmethodservice/navigationbar/KeyButtonDrawable.java
@@ -54,30 +54,30 @@
 final class KeyButtonDrawable extends Drawable {
 
     public static final FloatProperty<KeyButtonDrawable> KEY_DRAWABLE_ROTATE =
-        new FloatProperty<KeyButtonDrawable>("KeyButtonRotation") {
-            @Override
-            public void setValue(KeyButtonDrawable drawable, float degree) {
-                drawable.setRotation(degree);
-            }
+            new FloatProperty<KeyButtonDrawable>("KeyButtonRotation") {
+                @Override
+                public void setValue(KeyButtonDrawable drawable, float degree) {
+                    drawable.setRotation(degree);
+                }
 
-            @Override
-            public Float get(KeyButtonDrawable drawable) {
-                return drawable.getRotation();
-            }
-        };
+                @Override
+                public Float get(KeyButtonDrawable drawable) {
+                    return drawable.getRotation();
+                }
+            };
 
     public static final FloatProperty<KeyButtonDrawable> KEY_DRAWABLE_TRANSLATE_Y =
-        new FloatProperty<KeyButtonDrawable>("KeyButtonTranslateY") {
-            @Override
-            public void setValue(KeyButtonDrawable drawable, float y) {
-                drawable.setTranslationY(y);
-            }
+            new FloatProperty<KeyButtonDrawable>("KeyButtonTranslateY") {
+                @Override
+                public void setValue(KeyButtonDrawable drawable, float y) {
+                    drawable.setTranslationY(y);
+                }
 
-            @Override
-            public Float get(KeyButtonDrawable drawable) {
-                return drawable.getTranslationY();
-            }
-        };
+                @Override
+                public Float get(KeyButtonDrawable drawable) {
+                    return drawable.getTranslationY();
+                }
+            };
 
     private final Paint mIconPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
     private final Paint mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
@@ -100,7 +100,7 @@
         }
     };
 
-    public KeyButtonDrawable(Drawable d, @ColorInt int lightColor, @ColorInt int darkColor,
+    KeyButtonDrawable(Drawable d, @ColorInt int lightColor, @ColorInt int darkColor,
             boolean horizontalFlip, Color ovalBackgroundColor) {
         this(d, new ShadowDrawableState(lightColor, darkColor,
                 d instanceof AnimatedVectorDrawable, horizontalFlip, ovalBackgroundColor));
@@ -433,8 +433,8 @@
         final boolean mSupportsAnimation;
         final Color mOvalBackgroundColor;
 
-        public ShadowDrawableState(@ColorInt int lightColor, @ColorInt int darkColor,
-                boolean animated, boolean horizontalFlip, Color ovalBackgroundColor) {
+        ShadowDrawableState(@ColorInt int lightColor, @ColorInt int darkColor, boolean animated,
+                boolean horizontalFlip, Color ovalBackgroundColor) {
             mLightColor = lightColor;
             mDarkColor = darkColor;
             mSupportsAnimation = animated;
diff --git a/core/java/android/inputmethodservice/navigationbar/KeyButtonRipple.java b/core/java/android/inputmethodservice/navigationbar/KeyButtonRipple.java
index 38a63b6..cf77c898 100644
--- a/core/java/android/inputmethodservice/navigationbar/KeyButtonRipple.java
+++ b/core/java/android/inputmethodservice/navigationbar/KeyButtonRipple.java
@@ -90,7 +90,7 @@
 
     private Type mType = Type.ROUNDED_RECT;
 
-    public KeyButtonRipple(Context ctx, View targetView, @DimenRes int maxWidthResource) {
+    KeyButtonRipple(Context ctx, View targetView, @DimenRes int maxWidthResource) {
         mMaxWidthResource = maxWidthResource;
         mMaxWidth = ctx.getResources().getDimensionPixelSize(maxWidthResource);
         mTargetView = targetView;
@@ -126,7 +126,7 @@
     private void drawSoftware(Canvas canvas) {
         if (mGlowAlpha > 0f) {
             final Paint p = getRipplePaint();
-            p.setAlpha((int)(mGlowAlpha * 255f));
+            p.setAlpha((int) (mGlowAlpha * 255f));
 
             final float w = getBounds().width();
             final float h = getBounds().height();
@@ -412,7 +412,7 @@
         mDrawingHardwareGlow = true;
         setExtendStart(CanvasProperty.createFloat(getExtendSize() / 2));
         final RenderNodeAnimator startAnim = new RenderNodeAnimator(getExtendStart(),
-                getExtendSize()/2 - GLOW_MAX_SCALE_FACTOR * getRippleSize()/2);
+                getExtendSize() / 2 - GLOW_MAX_SCALE_FACTOR * getRippleSize() / 2);
         startAnim.setDuration(ANIMATION_DURATION_SCALE);
         startAnim.setInterpolator(mInterpolator);
         startAnim.addListener(mAnimatorListener);
@@ -420,7 +420,7 @@
 
         setExtendEnd(CanvasProperty.createFloat(getExtendSize() / 2));
         final RenderNodeAnimator endAnim = new RenderNodeAnimator(getExtendEnd(),
-                getExtendSize()/2 + GLOW_MAX_SCALE_FACTOR * getRippleSize()/2);
+                getExtendSize() / 2 + GLOW_MAX_SCALE_FACTOR * getRippleSize() / 2);
         endAnim.setDuration(ANIMATION_DURATION_SCALE);
         endAnim.setInterpolator(mInterpolator);
         endAnim.addListener(mAnimatorListener);
@@ -430,13 +430,13 @@
         if (isHorizontal()) {
             mTopProp = CanvasProperty.createFloat(0f);
             mBottomProp = CanvasProperty.createFloat(getBounds().height());
-            mRxProp = CanvasProperty.createFloat(getBounds().height()/2);
-            mRyProp = CanvasProperty.createFloat(getBounds().height()/2);
+            mRxProp = CanvasProperty.createFloat(getBounds().height() / 2);
+            mRyProp = CanvasProperty.createFloat(getBounds().height() / 2);
         } else {
             mLeftProp = CanvasProperty.createFloat(0f);
             mRightProp = CanvasProperty.createFloat(getBounds().width());
-            mRxProp = CanvasProperty.createFloat(getBounds().width()/2);
-            mRyProp = CanvasProperty.createFloat(getBounds().width()/2);
+            mRxProp = CanvasProperty.createFloat(getBounds().width() / 2);
+            mRyProp = CanvasProperty.createFloat(getBounds().width() / 2);
         }
 
         mGlowScale = GLOW_MAX_SCALE_FACTOR;
diff --git a/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java b/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java
index 74d30f8..cfdb6ca 100644
--- a/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java
+++ b/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java
@@ -200,8 +200,8 @@
                 postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
                 break;
             case MotionEvent.ACTION_MOVE:
-                x = (int)ev.getRawX();
-                y = (int)ev.getRawY();
+                x = (int) ev.getRawX();
+                y = (int) ev.getRawY();
 
                 float slop = getQuickStepTouchSlopPx(getContext());
                 if (Math.abs(x - mTouchDownX) > slop || Math.abs(y - mTouchDownY) > slop) {
@@ -272,12 +272,13 @@
                 : KeyButtonRipple.Type.ROUNDED_RECT);
     }
 
+    @Override
     public void playSoundEffect(int soundConstant) {
         if (!mPlaySounds) return;
         mAudioManager.playSoundEffect(soundConstant);
     }
 
-    public void sendEvent(int action, int flags) {
+    private void sendEvent(int action, int flags) {
         sendEvent(action, flags, SystemClock.uptimeMillis());
     }
 
@@ -309,8 +310,8 @@
             switch (action) {
                 case KeyEvent.ACTION_DOWN:
                     handled = ims.onKeyDown(ev.getKeyCode(), ev);
-                    mTracking = handled && ev.getRepeatCount() == 0 &&
-                            (ev.getFlags() & KeyEvent.FLAG_START_TRACKING) != 0;
+                    mTracking = handled && ev.getRepeatCount() == 0
+                            && (ev.getFlags() & KeyEvent.FLAG_START_TRACKING) != 0;
                     break;
                 case KeyEvent.ACTION_UP:
                     handled = ims.onKeyUp(ev.getKeyCode(), ev);
diff --git a/core/java/android/inputmethodservice/navigationbar/NavigationBarFrame.java b/core/java/android/inputmethodservice/navigationbar/NavigationBarFrame.java
index f01173e..a270675 100644
--- a/core/java/android/inputmethodservice/navigationbar/NavigationBarFrame.java
+++ b/core/java/android/inputmethodservice/navigationbar/NavigationBarFrame.java
@@ -59,4 +59,4 @@
         }
         return super.dispatchTouchEvent(event);
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/inputmethodservice/navigationbar/NavigationBarInflaterView.java b/core/java/android/inputmethodservice/navigationbar/NavigationBarInflaterView.java
index d488890..e93bda2 100644
--- a/core/java/android/inputmethodservice/navigationbar/NavigationBarInflaterView.java
+++ b/core/java/android/inputmethodservice/navigationbar/NavigationBarInflaterView.java
@@ -121,7 +121,7 @@
         return CONFIG_NAV_BAR_LAYOUT_HANDLE;
     }
 
-    public void setButtonDispatchers(SparseArray<ButtonDispatcher> buttonDispatchers) {
+    void setButtonDispatchers(SparseArray<ButtonDispatcher> buttonDispatchers) {
         mButtonDispatchers = buttonDispatchers;
         for (int i = 0; i < buttonDispatchers.size(); i++) {
             initiallyFill(buttonDispatchers.valueAt(i));
@@ -376,7 +376,7 @@
     }
     */
 
-    public static String extractSize(String buttonSpec) {
+    private static String extractSize(String buttonSpec) {
         if (!buttonSpec.contains(SIZE_MOD_START)) {
             return null;
         }
@@ -384,7 +384,7 @@
         return buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
     }
 
-    public static String extractButton(String buttonSpec) {
+    private static String extractButton(String buttonSpec) {
         if (!buttonSpec.contains(SIZE_MOD_START)) {
             return buttonSpec;
         }
@@ -398,9 +398,9 @@
                 mButtonDispatchers.valueAt(indexOfKey).addView(v);
             }
             if (v instanceof ViewGroup) {
-                final ViewGroup viewGroup = (ViewGroup)v;
-                final int N = viewGroup.getChildCount();
-                for (int i = 0; i < N; i++) {
+                final ViewGroup viewGroup = (ViewGroup) v;
+                final int numChildViews = viewGroup.getChildCount();
+                for (int i = 0; i < numChildViews; i++) {
                     addToDispatchers(viewGroup.getChildAt(i));
                 }
             }
diff --git a/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java b/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java
index a2d7105..510b14e 100644
--- a/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java
+++ b/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java
@@ -48,8 +48,8 @@
  * @hide
  */
 public final class NavigationBarView extends FrameLayout {
-    final static boolean DEBUG = false;
-    final static String TAG = "NavBarView";
+    private static final boolean DEBUG = false;
+    private static final String TAG = "NavBarView";
 
     // Copied from com.android.systemui.animation.Interpolators#FAST_OUT_SLOW_IN
     private static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
@@ -139,7 +139,7 @@
     }
 
     /**
-     * Applies {@param consumer} to each of the nav bar views.
+     * Applies {@code consumer} to each of the nav bar views.
      */
     public void forEachView(Consumer<View> consumer) {
         if (mHorizontal != null) {
@@ -181,7 +181,7 @@
         }
     }
 
-    public KeyButtonDrawable getBackDrawable() {
+    private KeyButtonDrawable getBackDrawable() {
         KeyButtonDrawable drawable = getDrawable(com.android.internal.R.drawable.ic_ime_nav_back);
         orientBackButton(drawable);
         return drawable;
@@ -211,7 +211,7 @@
         // Animate the back button's rotation to the new degrees and only in portrait move up the
         // back button to line up with the other buttons
         float targetY = useAltBack
-                ? - dpToPx(NAVBAR_BACK_BUTTON_IME_OFFSET, getResources())
+                ? -dpToPx(NAVBAR_BACK_BUTTON_IME_OFFSET, getResources())
                 : 0;
         ObjectAnimator navBarAnimator = ObjectAnimator.ofPropertyValuesHolder(drawable,
                 PropertyValuesHolder.ofFloat(KeyButtonDrawable.KEY_DRAWABLE_ROTATE, degrees),
@@ -233,6 +233,11 @@
         super.setLayoutDirection(layoutDirection);
     }
 
+    /**
+     * Updates the navigation icons based on {@code hints}.
+     *
+     * @param hints bit flags defined in {@link StatusBarManager}.
+     */
     public void setNavigationIconHints(int hints) {
         if (hints == mNavigationIconHints) return;
         final boolean newBackAlt = (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
@@ -250,15 +255,7 @@
         updateNavButtonIcons();
     }
 
-    public void setDisabledFlags(int disabledFlags) {
-        if (mDisabledFlags == disabledFlags) return;
-
-        mDisabledFlags = disabledFlags;
-
-        updateNavButtonIcons();
-    }
-
-    public void updateNavButtonIcons() {
+    private void updateNavButtonIcons() {
         // We have to replace or restore the back and home button icons when exiting or entering
         // carmode, respectively. Recents are not available in CarMode in nav bar so change
         // to recent icon is not required.
@@ -319,7 +316,7 @@
         mHorizontal.setVisibility(View.GONE);
     }
 
-    public void reorient() {
+    private void reorient() {
         updateCurrentView();
 
         final android.inputmethodservice.navigationbar.NavigationBarFrame frame =
@@ -372,6 +369,11 @@
         }
     }
 
+    /**
+     * Updates the dark intensity.
+     *
+     * @param intensity The intensity of darkness from {@code 0.0f} to {@code 1.0f}.
+     */
     public void setDarkIntensity(@FloatRange(from = 0.0f, to = 1.0f) float intensity) {
         for (int i = 0; i < mButtonDispatchers.size(); ++i) {
             mButtonDispatchers.valueAt(i).setDarkIntensity(intensity);
diff --git a/core/java/android/inputmethodservice/navigationbar/ReverseLinearLayout.java b/core/java/android/inputmethodservice/navigationbar/ReverseLinearLayout.java
index 68163c3..9b36cc5 100644
--- a/core/java/android/inputmethodservice/navigationbar/ReverseLinearLayout.java
+++ b/core/java/android/inputmethodservice/navigationbar/ReverseLinearLayout.java
@@ -30,9 +30,8 @@
 /**
  * Automatically reverses the order of children as they are added.
  * Also reverse the width and height values of layout params
- * @hide
  */
-public class ReverseLinearLayout extends LinearLayout {
+class ReverseLinearLayout extends LinearLayout {
 
     /** If true, the layout is reversed vs. a regular linear layout */
     private boolean mIsLayoutReverse;
@@ -40,7 +39,7 @@
     /** If true, the layout is opposite to it's natural reversity from the layout direction */
     private boolean mIsAlternativeOrder;
 
-    public ReverseLinearLayout(Context context, @Nullable AttributeSet attrs) {
+    ReverseLinearLayout(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
     }
 
@@ -129,7 +128,7 @@
 
     public static class ReverseRelativeLayout extends RelativeLayout implements Reversible {
 
-        public ReverseRelativeLayout(Context context) {
+        ReverseRelativeLayout(Context context) {
             super(context);
         }
 
diff --git a/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
index 2dd3aaa1..5c9989e 100644
--- a/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
+++ b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
@@ -27,6 +27,7 @@
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import android.annotation.NonNull;
+import android.annotation.StringDef;
 import android.annotation.SystemApi;
 import android.net.NetworkIdentity;
 import android.net.NetworkStatsCollection;
@@ -47,6 +48,8 @@
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.net.ProtocolException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -76,6 +79,15 @@
      */
     public static final String PREFIX_UID_TAG = "uid_tag";
 
+    /** @hide */
+    @StringDef(prefix = {"PREFIX_"}, value = {
+        PREFIX_XT,
+        PREFIX_UID,
+        PREFIX_UID_TAG,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Prefix {}
+
     private static final HashMap<String, String> sPrefixLegacyFileNameMap =
             new HashMap<String, String>() {{
                 put(PREFIX_XT, "netstats_xt.bin");
@@ -141,13 +153,13 @@
 
     // Get /data/system/netstats_*.bin legacy files. Does not check for existence.
     @NonNull
-    private static File getLegacyBinFileForPrefix(@NonNull String prefix) {
+    private static File getLegacyBinFileForPrefix(@NonNull @Prefix String prefix) {
         return new File(getPlatformSystemDir(), sPrefixLegacyFileNameMap.get(prefix));
     }
 
     // List /data/system/netstats/[xt|uid|uid_tag].<start>-<end> legacy files.
     @NonNull
-    private static ArrayList<File> getPlatformFileListForPrefix(@NonNull String prefix) {
+    private static ArrayList<File> getPlatformFileListForPrefix(@NonNull @Prefix String prefix) {
         final ArrayList<File> list = new ArrayList<>();
         final File platformFiles = new File(getPlatformBaseDir(), "netstats");
         if (platformFiles.exists()) {
@@ -207,7 +219,7 @@
      */
     @NonNull
     public static NetworkStatsCollection readPlatformCollection(
-            @NonNull String prefix, long bucketDuration) throws IOException {
+            @NonNull @Prefix String prefix, long bucketDuration) throws IOException {
         final NetworkStatsCollection.Builder builder =
                 new NetworkStatsCollection.Builder(bucketDuration);
 
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 0ce9c70..731d1ba 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -142,9 +142,13 @@
         mTagService = tagService;
 
         mConnectedTechnology = -1;
+        mCookie = SystemClock.elapsedRealtime();
+
+        if (tagService == null) {
+            return;
+        }
 
         try {
-            mCookie = SystemClock.elapsedRealtime();
             tagService.setTagUpToDate(mCookie);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
@@ -370,6 +374,10 @@
     /** @hide */
     @UnsupportedAppUsage
     public INfcTag getTagService() {
+        if (mTagService == null) {
+            return null;
+        }
+
         try {
             if (!mTagService.isTagUpToDate(mCookie)) {
                 String id_str = "";
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
index de76c8f..f4ca1b5 100644
--- a/core/java/android/os/BatteryConsumer.java
+++ b/core/java/android/os/BatteryConsumer.java
@@ -165,6 +165,7 @@
             PROCESS_STATE_FOREGROUND,
             PROCESS_STATE_BACKGROUND,
             PROCESS_STATE_FOREGROUND_SERVICE,
+            PROCESS_STATE_CACHED,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ProcessState {
@@ -175,8 +176,9 @@
     public static final int PROCESS_STATE_FOREGROUND = 1;
     public static final int PROCESS_STATE_BACKGROUND = 2;
     public static final int PROCESS_STATE_FOREGROUND_SERVICE = 3;
+    public static final int PROCESS_STATE_CACHED = 4;
 
-    public static final int PROCESS_STATE_COUNT = 4;
+    public static final int PROCESS_STATE_COUNT = 5;
 
     private static final String[] sProcessStateNames = new String[PROCESS_STATE_COUNT];
 
@@ -186,6 +188,7 @@
         sProcessStateNames[PROCESS_STATE_FOREGROUND] = "fg";
         sProcessStateNames[PROCESS_STATE_BACKGROUND] = "bg";
         sProcessStateNames[PROCESS_STATE_FOREGROUND_SERVICE] = "fgs";
+        sProcessStateNames[PROCESS_STATE_CACHED] = "cached";
     }
 
     private static final int[] SUPPORTED_POWER_COMPONENTS_PER_PROCESS_STATE = {
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index de1dc80..06c35b5 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -680,6 +680,8 @@
                 return BatteryConsumer.PROCESS_STATE_BACKGROUND;
             case BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE:
                 return BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE;
+            case BatteryStats.Uid.PROCESS_STATE_CACHED:
+                return BatteryConsumer.PROCESS_STATE_CACHED;
             default:
                 return BatteryConsumer.PROCESS_STATE_UNSPECIFIED;
         }
@@ -2681,7 +2683,7 @@
     public static final String[] RADIO_ACCESS_TECHNOLOGY_NAMES = {"Other", "LTE", "NR"};
 
     /**
-     * Returns the time in microseconds that the mobile radio has been active on a
+     * Returns the time in milliseconds that the mobile radio has been active on a
      * given Radio Access Technology (RAT), at a given frequency (NR RAT only), for a given
      * transmission power level.
      *
@@ -2700,6 +2702,46 @@
             @ServiceState.FrequencyRange int frequencyRange, int signalStrength,
             long elapsedRealtimeMs);
 
+    /**
+     * Returns the time in milliseconds that the mobile radio has been actively transmitting data on
+     * a given Radio Access Technology (RAT), at a given frequency (NR RAT only), for a given
+     * transmission power level.
+     *
+     * @param rat            Radio Access Technology {@see RadioAccessTechnology}
+     * @param frequencyRange frequency range {@see ServiceState.FrequencyRange}, only needed for
+     *                       RADIO_ACCESS_TECHNOLOGY_NR. Use
+     *                       {@link ServiceState.FREQUENCY_RANGE_UNKNOWN} for other Radio Access
+     *                       Technologies.
+     * @param signalStrength the cellular signal strength. {@see CellSignalStrength#getLevel()}
+     * @param elapsedRealtimeMs current elapsed realtime
+     * @return time (in milliseconds) the mobile radio spent actively transmitting data in the
+     *         specified state, while on battery. Returns {@link DURATION_UNAVAILABLE} if
+     *         data unavailable.
+     * @hide
+     */
+    public abstract long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat,
+            @ServiceState.FrequencyRange int frequencyRange, int signalStrength,
+            long elapsedRealtimeMs);
+
+    /**
+     * Returns the time in milliseconds that the mobile radio has been actively receiving data on a
+     * given Radio Access Technology (RAT), at a given frequency (NR RAT only), for a given
+     * transmission power level.
+     *
+     * @param rat            Radio Access Technology {@see RadioAccessTechnology}
+     * @param frequencyRange frequency range {@see ServiceState.FrequencyRange}, only needed for
+     *                       RADIO_ACCESS_TECHNOLOGY_NR. Use
+     *                       {@link ServiceState.FREQUENCY_RANGE_UNKNOWN} for other Radio Access
+     *                       Technologies.
+     * @param elapsedRealtimeMs current elapsed realtime
+     * @return time (in milliseconds) the mobile radio spent actively receiving data in the
+     *         specified state, while on battery. Returns {@link DURATION_UNAVAILABLE} if
+     *         data unavailable.
+     * @hide
+     */
+    public abstract long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat,
+            @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs);
+
     static final String[] WIFI_SUPPL_STATE_NAMES = {
         "invalid", "disconn", "disabled", "inactive", "scanning",
         "authenticating", "associating", "associated", "4-way-handshake",
@@ -2720,6 +2762,13 @@
     public static final long POWER_DATA_UNAVAILABLE = -1L;
 
     /**
+     * Returned value if duration data is unavailable.
+     *
+     * {@hide}
+     */
+    public static final long DURATION_UNAVAILABLE = -1L;
+
+    /**
      * Returns the battery consumption (in microcoulombs) of bluetooth, derived from on
      * device power measurement data.
      * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
@@ -4093,6 +4142,10 @@
                 "    Mmwave frequency (greater than 6GHz):\n"};
         final String signalStrengthHeader =
                 "      Signal Strength Time:\n";
+        final String txHeader =
+                "      Tx Time:\n";
+        final String rxHeader =
+                "      Rx Time: ";
         final String[] signalStrengthDescription = new String[]{
                 "        unknown:  ",
                 "        poor:     ",
@@ -4144,6 +4197,29 @@
                     sb.append(")\n");
                 }
 
+                sb.append(prefix);
+                sb.append(txHeader);
+                for (int strength = 0; strength < numSignalStrength; strength++) {
+                    final long timeMs = getActiveTxRadioDurationMs(rat, freqLvl, strength,
+                            rawRealtimeMs);
+                    if (timeMs <= 0) continue;
+                    hasFreqData = true;
+                    sb.append(prefix);
+                    sb.append(signalStrengthDescription[strength]);
+                    formatTimeMs(sb, timeMs);
+                    sb.append("(");
+                    sb.append(formatRatioLocked(timeMs, totalActiveTimesMs));
+                    sb.append(")\n");
+                }
+
+                sb.append(prefix);
+                sb.append(rxHeader);
+                final long rxTimeMs = getActiveRxRadioDurationMs(rat, freqLvl, rawRealtimeMs);
+                formatTimeMs(sb, rxTimeMs);
+                sb.append("(");
+                sb.append(formatRatioLocked(rxTimeMs, totalActiveTimesMs));
+                sb.append(")\n");
+
                 if (hasFreqData) {
                     hasData = true;
                     pw.print(sb);
@@ -5655,6 +5731,7 @@
                         .setMaxStatsAgeMs(0)
                         .includePowerModels()
                         .includeProcessStateData()
+                        .includeVirtualUids()
                         .build());
         stats.dump(pw, prefix);
 
diff --git a/core/java/android/os/BatteryUsageStatsQuery.java b/core/java/android/os/BatteryUsageStatsQuery.java
index 37bd51b..b3f4d98 100644
--- a/core/java/android/os/BatteryUsageStatsQuery.java
+++ b/core/java/android/os/BatteryUsageStatsQuery.java
@@ -42,6 +42,7 @@
             FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL,
             FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY,
             FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA,
+            FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface BatteryUsageStatsFlags {}
@@ -69,6 +70,8 @@
 
     public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA = 0x0008;
 
+    public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS = 0x0010;
+
     private static final long DEFAULT_MAX_STATS_AGE_MS = 5 * 60 * 1000;
 
     private final int mFlags;
@@ -271,6 +274,15 @@
         }
 
         /**
+         * Requests to return attribution data for virtual UIDs such as
+         * {@link Process#SDK_SANDBOX_VIRTUAL_UID}.
+         */
+        public Builder includeVirtualUids() {
+            mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS;
+            return this;
+        }
+
+        /**
          * Requests to aggregate stored snapshots between the two supplied timestamps
          * @param fromTimestamp Exclusive starting timestamp, as per System.currentTimeMillis()
          * @param toTimestamp Inclusive ending timestamp, as per System.currentTimeMillis()
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index a19b51b..cf28c16 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -989,7 +989,7 @@
      * Otherwise, this method might throw an exception or return {@code null}.
      *
      * @param key a String, or {@code null}
-     * @param clazz The type of the items inside the array
+     * @param clazz The type of the items inside the array. This is only verified when unparceling.
      * @return a Parcelable[] value, or {@code null}
      */
     @SuppressLint({"ArrayReturn", "NullableCollection"})
@@ -1053,7 +1053,8 @@
      * Otherwise, this method might throw an exception or return {@code null}.
      *
      * @param key   a String, or {@code null}
-     * @param clazz The type of the items inside the array list
+     * @param clazz The type of the items inside the array list. This is only verified when
+     *     unparceling.
      * @return an ArrayList<T> value, or {@code null}
      */
     @SuppressLint("NullableCollection")
@@ -1103,6 +1104,8 @@
      * </ul>
      *
      * @param key a String, or null
+     * @param clazz The type of the items inside the sparse array. This is only verified when
+     *     unparceling.
      * @return a SparseArray of T values, or null
      */
     @SuppressWarnings("unchecked")
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 0a7a407..ecdc803 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -478,10 +478,20 @@
     }
 
     /** {@hide} */
+    public static File getDataMiscCeSharedSdkSandboxDirectory(int userId, String packageName) {
+        return buildPath(getDataMiscCeDirectory(userId), "sdksandbox", packageName, "shared");
+    }
+
+    /** {@hide} */
     public static File getDataMiscDeDirectory(int userId) {
         return buildPath(getDataDirectory(), "misc_de", String.valueOf(userId));
     }
 
+    /** {@hide} */
+    public static File getDataMiscDeSharedSdkSandboxDirectory(int userId, String packageName) {
+        return buildPath(getDataMiscDeDirectory(userId), "sdksandbox", packageName, "shared");
+    }
+
     private static File getDataProfilesDeDirectory(int userId) {
         return buildPath(getDataDirectory(), "misc", "profiles", "cur", String.valueOf(userId));
     }
diff --git a/core/java/android/os/ExternalVibration.java b/core/java/android/os/ExternalVibration.java
index 4e0995f..db5bc70 100644
--- a/core/java/android/os/ExternalVibration.java
+++ b/core/java/android/os/ExternalVibration.java
@@ -47,7 +47,13 @@
         this(uid, pkg, attrs, controller, new Binder());
     }
 
-    private ExternalVibration(int uid, @NonNull String pkg, @NonNull AudioAttributes attrs,
+    /**
+     * Full constructor, but exposed to construct the ExternalVibration with an explicit binder
+     * token (for mocks).
+     *
+     * @hide
+     */
+    public ExternalVibration(int uid, @NonNull String pkg, @NonNull AudioAttributes attrs,
             @NonNull IExternalVibrationController controller, @NonNull IBinder token) {
         mUid = uid;
         mPkg = Preconditions.checkNotNull(pkg);
@@ -166,7 +172,7 @@
             + "pkg=" + mPkg + ", "
             + "attrs=" + mAttrs + ", "
             + "controller=" + mController
-            + "token=" + mController
+            + "token=" + mToken
             + "}";
     }
 
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 010459d..9e47a70 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -293,7 +293,10 @@
      *
      * @return Returns the result from {@link Binder#onTransact}.  A successful call
      * generally returns true; false generally means the transaction code was not
-     * understood.
+     * understood.  For a oneway call to a different process false should never be
+     * returned.  If a oneway call is made to code in the same process (usually to
+     * a C++ or Rust implementation), then there are no oneway semantics, and
+     * false can still be returned.
      */
     public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)
         throws RemoteException;
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 39ca596..3cde031 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -109,7 +109,7 @@
     boolean someUserHasAccount(in String accountName, in String accountType);
     String getProfileType(int userId);
     boolean isMediaSharedWithParent(int userId);
-    boolean isCredentialSharedWithParent(int userId);
+    boolean isCredentialSharableWithParent(int userId);
     boolean isDemoUser(int userId);
     boolean isPreCreated(int userId);
     UserInfo createProfileForUserEvenWhenDisallowedWithThrow(in String name, in String userType, int flags,
diff --git a/core/java/android/os/IpcDataCache.java b/core/java/android/os/IpcDataCache.java
new file mode 100644
index 0000000..00734c80
--- /dev/null
+++ b/core/java/android/os/IpcDataCache.java
@@ -0,0 +1,364 @@
+/*
+ * 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.os;
+
+import android.app.PropertyInvalidatedCache;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.FastPrintWriter;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Random;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * LRU cache that's invalidated when an opaque value in a property changes. Self-synchronizing,
+ * but doesn't hold a lock across data fetches on query misses.
+ *
+ * The intended use case is caching frequently-read, seldom-changed information normally retrieved
+ * across interprocess communication. Imagine that you've written a user birthday information
+ * daemon called "birthdayd" that exposes an {@code IUserBirthdayService} interface over
+ * binder. That binder interface looks something like this:
+ *
+ * <pre>
+ * parcelable Birthday {
+ *   int month;
+ *   int day;
+ * }
+ * interface IUserBirthdayService {
+ *   Birthday getUserBirthday(int userId);
+ * }
+ * </pre>
+ *
+ * Suppose the service implementation itself looks like this...
+ *
+ * <pre>
+ * public class UserBirthdayServiceImpl implements IUserBirthdayService {
+ *   private final HashMap&lt;Integer, Birthday%&gt; mUidToBirthday;
+ *   {@literal @}Override
+ *   public synchronized Birthday getUserBirthday(int userId) {
+ *     return mUidToBirthday.get(userId);
+ *   }
+ *   private synchronized void updateBirthdays(Map&lt;Integer, Birthday%&gt; uidToBirthday) {
+ *     mUidToBirthday.clear();
+ *     mUidToBirthday.putAll(uidToBirthday);
+ *   }
+ * }
+ * </pre>
+ *
+ * ... and we have a client in frameworks (loaded into every app process) that looks like this:
+ *
+ * <pre>
+ * public class ActivityThread {
+ *   ...
+ *   public Birthday getUserBirthday(int userId) {
+ *     return GetService("birthdayd").getUserBirthday(userId);
+ *   }
+ *   ...
+ * }
+ * </pre>
+ *
+ * With this code, every time an app calls {@code getUserBirthday(uid)}, we make a binder call to
+ * the birthdayd process and consult its database of birthdays. If we query user birthdays
+ * frequently, we do a lot of work that we don't have to do, since user birthdays change
+ * infrequently.
+ *
+ * IpcDataCache is part of a pattern for optimizing this kind of information-querying code. Using
+ * {@code IpcDataCache}, you'd write the client this way:
+ *
+ * <pre>
+ * public class ActivityThread {
+ *   ...
+ *   private final IpcDataCache.QueryHandler&lt;Integer, Birthday&gt; mBirthdayQuery =
+ *       new IpcDataCache.QueryHandler&lt;Integer, Birthday&gt;() {
+ *           {@literal @}Override
+ *           public Birthday apply(Integer) {
+ *              return GetService("birthdayd").getUserBirthday(userId);
+ *           }
+ *       };
+ *   private static final int BDAY_CACHE_MAX = 8;  // Maximum birthdays to cache
+ *   private static final String BDAY_API = "getUserBirthday";
+ *   private final IpcDataCache&lt;Integer, Birthday%&gt; mBirthdayCache = new
+ *     IpcDataCache&lt;Integer, Birthday%&gt;(
+ *             BDAY_CACHE_MAX, MODULE_SYSTEM, BDAY_API,  BDAY_API, mBirthdayQuery);
+ *
+ *   public void disableUserBirthdayCache() {
+ *     mBirthdayCache.disableForCurrentProcess();
+ *   }
+ *   public void invalidateUserBirthdayCache() {
+ *     mBirthdayCache.invalidateCache();
+ *   }
+ *   public Birthday getUserBirthday(int userId) {
+ *     return mBirthdayCache.query(userId);
+ *   }
+ *   ...
+ * }
+ * </pre>
+ *
+ * With this cache, clients perform a binder call to birthdayd if asking for a user's birthday
+ * for the first time; on subsequent queries, we return the already-known Birthday object.
+ *
+ * The second parameter to the IpcDataCache constructor is a string that identifies the "module"
+ * that owns the cache. There are some well-known modules (such as {@code MODULE_SYSTEM} but any
+ * string is permitted.  The third parameters is the name of the API being cached; this, too, can
+ * any value.  The fourth is the name of the cache.  The cache is usually named after th API.
+ * Some things you must know about the three strings:
+ * <list>
+ * <ul> The system property that controls the cache is named {@code cache_key.<module>.<api>}.
+ * Usually, the SELinux rules permit a process to write a system property (and therefore
+ * invalidate a cache) based on the wildcard {@code cache_key.<module>.*}.  This means that
+ * although the cache can be constructed with any module string, whatever string is chosen must be
+ * consistent with the SELinux configuration.
+ * <ul> The API name can be any string of alphanumeric characters.  All caches with the same API
+ * are invalidated at the same time.  If a server supports several caches and all are invalidated
+ * in common, then it is most efficient to assign the same API string to every cache.
+ * <ul> The cache name can be any string.  In debug output, the name is used to distiguish between
+ * caches with the same API name.  The cache name is also used when disabling caches in the
+ * current process.  So, invalidation is based on the module+api but disabling (which is generally
+ * a once-per-process operation) is based on the cache name.
+ * </list>
+ *
+ * User birthdays do occasionally change, so we have to modify the server to invalidate this
+ * cache when necessary. That invalidation code looks like this:
+ *
+ * <pre>
+ * public class UserBirthdayServiceImpl {
+ *   ...
+ *   public UserBirthdayServiceImpl() {
+ *     ...
+ *     ActivityThread.currentActivityThread().disableUserBirthdayCache();
+ *     ActivityThread.currentActivityThread().invalidateUserBirthdayCache();
+ *   }
+ *
+ *   private synchronized void updateBirthdays(Map&lt;Integer, Birthday%&gt; uidToBirthday) {
+ *     mUidToBirthday.clear();
+ *     mUidToBirthday.putAll(uidToBirthday);
+ *     ActivityThread.currentActivityThread().invalidateUserBirthdayCache();
+ *   }
+ *   ...
+ * }
+ * </pre>
+ *
+ * The call to {@code IpcDataCache.invalidateCache()} guarantees that all clients will re-fetch
+ * birthdays from binder during consequent calls to
+ * {@code ActivityThread.getUserBirthday()}. Because the invalidate call happens with the lock
+ * held, we maintain consistency between different client views of the birthday state. The use of
+ * IpcDataCache in this idiomatic way introduces no new race conditions.
+ *
+ * IpcDataCache has a few other features for doing things like incremental enhancement of cached
+ * values and invalidation of multiple caches (that all share the same property key) at once.
+ *
+ * {@code BDAY_CACHE_KEY} is the name of a property that we set to an opaque unique value each
+ * time we update the cache. SELinux configuration must allow everyone to read this property
+ * and it must allow any process that needs to invalidate the cache (here, birthdayd) to write
+ * the property. (These properties conventionally begin with the "cache_key." prefix.)
+ *
+ * The {@code UserBirthdayServiceImpl} constructor calls {@code disableUserBirthdayCache()} so
+ * that calls to {@code getUserBirthday} from inside birthdayd don't go through the cache. In this
+ * local case, there's no IPC, so use of the cache is (depending on exact circumstance)
+ * unnecessary.
+ *
+ * There may be queries for which it is more efficient to bypass the cache than to cache the
+ * result.  This would be true, for example, if some queries would require frequent cache
+ * invalidation while other queries require infrequent invalidation.  To expand on the birthday
+ * example, suppose that there is a userId that signifies "the next birthday".  When passed this
+ * userId, the server returns the next birthday among all users - this value changes as time
+ * advances.  The userId value can be cached, but the cache must be invalidated whenever a
+ * birthday occurs, and this invalidates all birthdays.  If there is a large number of users,
+ * invalidation will happen so often that the cache provides no value.
+ *
+ * The class provides a bypass mechanism to handle this situation.
+ * <pre>
+ * public class ActivityThread {
+ *   ...
+ *   private final IpcDataCache.QueryHandler&lt;Integer, Birthday&gt; mBirthdayQuery =
+ *       new IpcDataCache.QueryHandler&lt;Integer, Birthday&gt;() {
+ *           {@literal @}Override
+ *           public Birthday apply(Integer) {
+ *              return GetService("birthdayd").getUserBirthday(userId);
+ *           }
+ *           {@literal @}Override
+ *           public boolean shouldBypassQuery(Integer userId) {
+ *               return userId == NEXT_BIRTHDAY;
+ *           }
+ *       };
+ *   ...
+ * }
+ * </pre>
+ *
+ * If the {@code shouldBypassQuery()} method returns true then the cache is not used for that
+ * particular query.  The {@code shouldBypassQuery()} method is not abstract and the default
+ * implementation returns false.
+ *
+ * For security, there is a allowlist of processes that are allowed to invalidate a cache.  The
+ * allowlist includes normal runtime processes but does not include test processes.  Test
+ * processes must call {@code IpcDataCache.disableForTestMode()} to disable all cache activity in
+ * that process.
+ *
+ * Caching can be disabled completely by initializing {@code sEnabled} to false and rebuilding.
+ *
+ * To test a binder cache, create one or more tests that exercise the binder method.  This should
+ * be done twice: once with production code and once with a special image that sets {@code DEBUG}
+ * and {@code VERIFY} true.  In the latter case, verify that no cache inconsistencies are
+ * reported.  If a cache inconsistency is reported, however, it might be a false positive.  This
+ * happens if the server side data can be read and written non-atomically with respect to cache
+ * invalidation.
+ *
+ * @param <Query> The class used to index cache entries: must be hashable and comparable
+ * @param <Result> The class holding cache entries; use a boxed primitive if possible
+ * @hide
+ */
+@TestApi
+@SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+public class IpcDataCache<Query, Result> extends PropertyInvalidatedCache<Query, Result> {
+    /**
+     * {@inheritDoc}
+     * @hide
+     */
+    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+    @TestApi
+    public static abstract class QueryHandler<Q,R>
+            extends PropertyInvalidatedCache.QueryHandler<Q,R> {
+        /**
+         * Compute a result given a query.  The semantics are those of Functor.
+         */
+        public abstract @Nullable R apply(@NonNull Q query);
+
+        /**
+         * Return true if a query should not use the cache.  The default implementation
+         * always uses the cache.
+         */
+        public boolean shouldBypassCache(@NonNull Q query) {
+            return false;
+        }
+    };
+
+    /**
+     * The module used for unit tests and cts tests.  It is expected that no process in
+     * the system has permissions to write properties with this module.
+     * @hide
+     */
+    @TestApi
+    public static final String MODULE_TEST = PropertyInvalidatedCache.MODULE_TEST;
+
+    /**
+     * The module used for system server/framework caches.  This is not visible outside
+     * the system processes.
+     * @hide
+     */
+    @TestApi
+    public static final String MODULE_SYSTEM = PropertyInvalidatedCache.MODULE_SYSTEM;
+
+    /**
+     * The module used for bluetooth caches.
+     * @hide
+     */
+    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+    @TestApi
+    public static final String MODULE_BLUETOOTH = PropertyInvalidatedCache.MODULE_BLUETOOTH;
+
+    /**
+     * Make a new property invalidated cache.  The key is computed from the module and api
+     * parameters.
+     *
+     * @param maxEntries Maximum number of entries to cache; LRU discard
+     * @param module The module under which the cache key should be placed.
+     * @param api The api this cache front-ends.  The api must be a Java identifier but
+     * need not be an actual api.
+     * @param cacheName Name of this cache in debug and dumpsys
+     * @param computer The code to compute values that are not in the cache.
+     * @hide
+     */
+    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+    @TestApi
+    public IpcDataCache(int maxEntries, @NonNull String module, @NonNull String api,
+            @NonNull String cacheName, @NonNull QueryHandler<Query, Result> computer) {
+        super(maxEntries, module, api, cacheName, computer);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @hide
+     */
+    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+    @TestApi
+    @Override
+    public void disableForCurrentProcess() {
+        super.disableForCurrentProcess();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @hide
+     */
+    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+    @TestApi
+    public static void disableForCurrentProcess(@NonNull String cacheName) {
+        PropertyInvalidatedCache.disableForCurrentProcess(cacheName);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @hide
+     */
+    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+    @TestApi
+    @Override
+    public @Nullable Result query(@NonNull Query query) {
+        return super.query(query);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @hide
+     */
+    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+    @TestApi
+    @Override
+    public void invalidateCache() {
+        super.invalidateCache();
+    }
+
+    /**
+     * Invalidate caches in all processes that are keyed for the module and api.
+     * @hide
+     */
+    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
+    @TestApi
+    public static void invalidateCache(@NonNull String module, @NonNull String api) {
+        PropertyInvalidatedCache.invalidateCache(module, api);
+    }
+}
diff --git a/core/java/android/os/ParcelableHolder.java b/core/java/android/os/ParcelableHolder.java
index 368ee2d..a739ba3 100644
--- a/core/java/android/os/ParcelableHolder.java
+++ b/core/java/android/os/ParcelableHolder.java
@@ -179,7 +179,11 @@
      * Read ParcelableHolder from a parcel.
      */
     public void readFromParcel(@NonNull Parcel parcel) {
-        this.mStability = parcel.readInt();
+        int wireStability = parcel.readInt();
+        if (this.mStability != wireStability) {
+            throw new IllegalArgumentException("Expected stability " + this.mStability
+                                               + " but got " + wireStability);
+        }
 
         mParcelable = null;
 
diff --git a/core/java/android/os/PowerComponents.java b/core/java/android/os/PowerComponents.java
index 6051712..522807b 100644
--- a/core/java/android/os/PowerComponents.java
+++ b/core/java/android/os/PowerComponents.java
@@ -292,6 +292,10 @@
                 procState = BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsageSlice
                         .FOREGROUND_SERVICE;
                 break;
+            case BatteryConsumer.PROCESS_STATE_CACHED:
+                procState = BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsageSlice
+                        .CACHED;
+                break;
             default:
                 throw new IllegalArgumentException("Unknown process state: " + processState);
         }
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 9428ac9..e06e732 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -257,6 +257,14 @@
     public static final int UWB_UID = 1083;
 
     /**
+     * Defines a virtual UID that is used to aggregate data related to SDK sandbox UIDs.
+     * {@see SdkSandboxManager}
+     * @hide
+     */
+    @TestApi
+    public static final int SDK_SANDBOX_VIRTUAL_UID = 1090;
+
+    /**
      * GID that corresponds to the INTERNET permission.
      * Must match the value of AID_INET.
      * @hide
@@ -920,7 +928,7 @@
      */
     @SystemApi(client = MODULE_LIBRARIES)
     @TestApi
-    public static final int sdkSandboxToAppUid(int uid) {
+    public static final int getAppUidForSdkSandboxUid(int uid) {
         return uid - (FIRST_SDK_SANDBOX_UID - FIRST_APPLICATION_UID);
     }
 
diff --git a/core/java/android/os/UidBatteryConsumer.java b/core/java/android/os/UidBatteryConsumer.java
index a1ff923..91d231e 100644
--- a/core/java/android/os/UidBatteryConsumer.java
+++ b/core/java/android/os/UidBatteryConsumer.java
@@ -119,6 +119,8 @@
                     skipEmptyComponents);
             appendProcessStateData(sb, BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE,
                     skipEmptyComponents);
+            appendProcessStateData(sb, BatteryConsumer.PROCESS_STATE_CACHED,
+                    skipEmptyComponents);
             pw.print(sb);
         }
 
@@ -202,20 +204,24 @@
         private static final String PACKAGE_NAME_UNINITIALIZED = "";
         private final BatteryStats.Uid mBatteryStatsUid;
         private final int mUid;
+        private final boolean mIsVirtualUid;
         private String mPackageWithHighestDrain = PACKAGE_NAME_UNINITIALIZED;
         private boolean mExcludeFromBatteryUsageStats;
 
         public Builder(BatteryConsumerData data, @NonNull BatteryStats.Uid batteryStatsUid) {
-            super(data, CONSUMER_TYPE_UID);
-            mBatteryStatsUid = batteryStatsUid;
-            mUid = batteryStatsUid.getUid();
-            data.putLong(COLUMN_INDEX_UID, mUid);
+            this(data, batteryStatsUid, batteryStatsUid.getUid());
         }
 
         public Builder(BatteryConsumerData data, int uid) {
+            this(data, null, uid);
+        }
+
+        private Builder(BatteryConsumerData data, @Nullable BatteryStats.Uid batteryStatsUid,
+                int uid) {
             super(data, CONSUMER_TYPE_UID);
-            mBatteryStatsUid = null;
+            mBatteryStatsUid = batteryStatsUid;
             mUid = uid;
+            mIsVirtualUid = mUid == Process.SDK_SANDBOX_VIRTUAL_UID;
             data.putLong(COLUMN_INDEX_UID, mUid);
         }
 
@@ -232,6 +238,10 @@
             return mUid;
         }
 
+        public boolean isVirtualUid() {
+            return mIsVirtualUid;
+        }
+
         /**
          * Sets the name of the package owned by this UID that consumed the highest amount
          * of power since BatteryStats reset.
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a715c69..2448a05 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1703,12 +1703,40 @@
 
     /**
      * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that
-     * an error occurred that prevented the user from being removed or set as ephemeral.
+     * an unknown error occurred that prevented the user from being removed or set as ephemeral.
      *
      * @hide
      */
     @SystemApi
-    public static final int REMOVE_RESULT_ERROR = 3;
+    public static final int REMOVE_RESULT_ERROR_UNKNOWN = -1;
+
+    /**
+     * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that
+     * the user could not be removed due to a {@link #DISALLOW_REMOVE_MANAGED_PROFILE} or
+     * {@link #DISALLOW_REMOVE_USER} user restriction.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int REMOVE_RESULT_ERROR_USER_RESTRICTION = -2;
+
+    /**
+     * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that
+     * user being removed does not exist.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int REMOVE_RESULT_ERROR_USER_NOT_FOUND = -3;
+
+    /**
+     * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that
+     * user being removed is a {@link UserHandle#SYSTEM} user which can't be removed.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int REMOVE_RESULT_ERROR_SYSTEM_USER = -4;
 
     /**
      * Possible response codes from {@link #removeUserWhenPossible(UserHandle, boolean)}.
@@ -1719,7 +1747,10 @@
             REMOVE_RESULT_REMOVED,
             REMOVE_RESULT_DEFERRED,
             REMOVE_RESULT_ALREADY_BEING_REMOVED,
-            REMOVE_RESULT_ERROR,
+            REMOVE_RESULT_ERROR_USER_RESTRICTION,
+            REMOVE_RESULT_ERROR_USER_NOT_FOUND,
+            REMOVE_RESULT_ERROR_SYSTEM_USER,
+            REMOVE_RESULT_ERROR_UNKNOWN,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface RemoveResult {}
@@ -4763,7 +4794,7 @@
     }
 
     /**
-     * Returns {@code true} if the user shares lock settings credential with its parent user
+     * Returns whether the user can have shared lockscreen credential with its parent user.
      *
      * This API only works for {@link UserManager#isProfile() profiles}
      * and will always return false for any other user type.
@@ -4776,9 +4807,9 @@
                     Manifest.permission.MANAGE_USERS,
                     Manifest.permission.INTERACT_ACROSS_USERS})
     @SuppressAutoDoc
-    public boolean isCredentialSharedWithParent() {
+    public boolean isCredentialSharableWithParent() {
         try {
-            return mService.isCredentialSharedWithParent(mUserId);
+            return mService.isCredentialSharableWithParent(mUserId);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -4846,8 +4877,10 @@
      * the {@link #DISALLOW_REMOVE_USER} or {@link #DISALLOW_REMOVE_MANAGED_PROFILE} restriction
      *
      * @return the {@link RemoveResult} code: {@link #REMOVE_RESULT_REMOVED},
-     * {@link #REMOVE_RESULT_DEFERRED}, {@link #REMOVE_RESULT_ALREADY_BEING_REMOVED}, or
-     * {@link #REMOVE_RESULT_ERROR}.
+     * {@link #REMOVE_RESULT_DEFERRED}, {@link #REMOVE_RESULT_ALREADY_BEING_REMOVED},
+     * {@link #REMOVE_RESULT_ERROR_USER_RESTRICTION}, {@link #REMOVE_RESULT_ERROR_USER_NOT_FOUND},
+     * {@link #REMOVE_RESULT_ERROR_SYSTEM_USER}, or {@link #REMOVE_RESULT_ERROR_UNKNOWN}. All error
+     * codes have negative values.
      *
      * @hide
      */
@@ -4864,6 +4897,19 @@
     }
 
     /**
+     * Check if {@link #removeUserWhenPossible} returned a success code which means that the user
+     * has been removed or is slated for removal.
+     *
+     * @param result is {@link #RemoveResult} code return by {@link #removeUserWhenPossible}.
+     * @return {@code true} if it is a success code.
+     * @hide
+     */
+    @SystemApi
+    public static boolean isRemoveResultSuccessful(@RemoveResult int result) {
+        return result >= 0;
+    }
+
+    /**
      * Updates the user's name.
      *
      * @param userId the user's integer id
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 722cdbc..c021c07 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -54,13 +54,13 @@
      */
     void shutdown(IStorageShutdownObserver observer) = 19;
     /**
-     * Mounts an Opaque Binary Blob (OBB) with the specified decryption key and
-     * only allows the calling process's UID access to the contents.
-     * StorageManagerService will call back to the supplied IObbActionListener to inform
-     * it of the terminal state of the call.
+     * Mounts an Opaque Binary Blob (OBB). Only allows the calling process's UID
+     * access to the contents. StorageManagerService will call back to the
+     * supplied IObbActionListener to inform it of the terminal state of the
+     * call.
      */
-    void mountObb(in String rawPath, in String canonicalPath, in String key,
-            IObbActionListener token, int nonce, in ObbInfo obbInfo) = 21;
+    void mountObb(in String rawPath, in String canonicalPath, IObbActionListener token,
+            int nonce, in ObbInfo obbInfo) = 21;
     /**
      * Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
      * any program using it will be forcibly killed to unmount the image.
@@ -78,37 +78,10 @@
      */
     String getMountedObbPath(in String rawPath) = 24;
     /**
-     * Decrypts any encrypted volumes.
-     */
-    int decryptStorage(in String password) = 26;
-    /**
-     * Encrypts storage.
-     */
-    int encryptStorage(int type, in String password) = 27;
-    /**
-     * Changes the encryption password.
-     */
-    int changeEncryptionPassword(int type, in String password) = 28;
-    /**
      * Returns list of all mountable volumes for the specified userId
      */
     StorageVolume[] getVolumeList(int userId, in String callingPackage, int flags) = 29;
     /**
-     * Determines the encryption state of the volume.
-     * @return a numerical value. See {@code ENCRYPTION_STATE_*} for possible
-     * values.
-     * Note that this has been replaced in most cases by the APIs in
-     * StorageManager (see isEncryptable and below)
-     * This is still useful to get the error state when encryption has failed
-     * and CryptKeeper needs to throw up a screen advising the user what to do
-     */
-    int getEncryptionState() = 31;
-    /**
-     * Verify the encryption password against the stored volume.  This method
-     * may only be called by the system process.
-     */
-    int verifyEncryptionPassword(in String password) = 32;
-    /**
      * Ensure that all directories along given path exist, creating parent
      * directories as needed. Validates that given path is absolute and that it
      * contains no relative "." or ".." paths or symlinks. Also ensures that
@@ -117,32 +90,6 @@
      */
     void mkdirs(in String callingPkg, in String path) = 34;
     /**
-     * Determines the type of the encryption password
-     * @return PasswordType
-     */
-    int getPasswordType() = 35;
-    /**
-     * Get password from vold
-     * @return password or empty string
-     */
-    String getPassword() = 36;
-    /**
-     * Securely clear password from vold
-     */
-    oneway void clearPassword() = 37;
-    /**
-     * Set a field in the crypto header.
-     * @param field field to set
-     * @param contents contents to set in field
-     */
-    oneway void setField(in String field, in String contents) = 38;
-    /**
-     * Gets a field from the crypto header.
-     * @param field field to get
-     * @return contents of field
-     */
-    String getField(in String field) = 39;
-    /**
      * Report the time of the last maintenance operation such as fstrim.
      * @return Timestamp of the last maintenance operation, in the
      *     System.currentTimeMillis() time base
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 48e2827..9971cbc 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -83,7 +83,6 @@
 import android.provider.DeviceConfig;
 import android.provider.MediaStore;
 import android.provider.Settings;
-import android.sysprop.VoldProperties;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -273,12 +272,15 @@
     public static final int FLAG_STORAGE_CE = IInstalld.FLAG_STORAGE_CE;
     /** {@hide} */
     public static final int FLAG_STORAGE_EXTERNAL = IInstalld.FLAG_STORAGE_EXTERNAL;
+    /** @hide */
+    public static final int FLAG_STORAGE_SDK = IInstalld.FLAG_STORAGE_SDK;
 
     /** {@hide} */
     @IntDef(prefix = "FLAG_STORAGE_",  value = {
             FLAG_STORAGE_DE,
             FLAG_STORAGE_CE,
-            FLAG_STORAGE_EXTERNAL
+            FLAG_STORAGE_EXTERNAL,
+            FLAG_STORAGE_SDK,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface StorageFlags {}
@@ -677,9 +679,7 @@
     }
 
     /**
-     * Mount an Opaque Binary Blob (OBB) file. If a <code>key</code> is
-     * specified, it is supplied to the mounting process to be used in any
-     * encryption used in the OBB.
+     * Mount an Opaque Binary Blob (OBB) file.
      * <p>
      * The OBB will remain mounted for as long as the StorageManager reference
      * is held by the application. As soon as this reference is lost, the OBBs
@@ -692,19 +692,22 @@
      * application's OBB that shares its UID.
      *
      * @param rawPath the path to the OBB file
-     * @param key secret used to encrypt the OBB; may be <code>null</code> if no
-     *            encryption was used on the OBB.
+     * @param key must be <code>null</code>. Previously, some Android device
+     *            implementations accepted a non-<code>null</code> key to mount
+     *            an encrypted OBB file. However, this never worked reliably and
+     *            is no longer supported.
      * @param listener will receive the success or failure of the operation
      * @return whether the mount call was successfully queued or not
      */
     public boolean mountObb(String rawPath, String key, OnObbStateChangeListener listener) {
         Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
+        Preconditions.checkArgument(key == null, "mounting encrypted OBBs is no longer supported");
         Preconditions.checkNotNull(listener, "listener cannot be null");
 
         try {
             final String canonicalPath = new File(rawPath).getCanonicalPath();
             final int nonce = mObbActionListener.addListener(listener);
-            mStorageManager.mountObb(rawPath, canonicalPath, key, mObbActionListener, nonce,
+            mStorageManager.mountObb(rawPath, canonicalPath, mObbActionListener, nonce,
                     getObbInfo(canonicalPath));
             return true;
         } catch (IOException e) {
@@ -1735,10 +1738,7 @@
      *         false not encrypted or file encrypted
      */
     public static boolean isBlockEncrypted() {
-        if (!isEncrypted()) {
-            return false;
-        }
-        return RoSystemProperties.CRYPTO_BLOCK_ENCRYPTED;
+        return false;
     }
 
     /** {@hide}
@@ -1748,18 +1748,7 @@
      *         false not encrypted, file encrypted or default block encrypted
      */
     public static boolean isNonDefaultBlockEncrypted() {
-        if (!isBlockEncrypted()) {
-            return false;
-        }
-
-        try {
-            IStorageManager storageManager = IStorageManager.Stub.asInterface(
-                    ServiceManager.getService("mount"));
-            return storageManager.getPasswordType() != CRYPT_TYPE_DEFAULT;
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error getting encryption type");
-            return false;
-        }
+        return false;
     }
 
     /** {@hide}
@@ -1773,8 +1762,7 @@
      * framework, so no service needs to check for changes during their lifespan
      */
     public static boolean isBlockEncrypting() {
-        final String state = VoldProperties.encrypt_progress().orElse("");
-        return !"".equalsIgnoreCase(state);
+        return false;
     }
 
     /** {@hide}
@@ -1789,8 +1777,7 @@
      * framework, so no service needs to check for changes during their lifespan
      */
     public static boolean inCryptKeeperBounce() {
-        final String status = VoldProperties.decrypt().orElse("");
-        return "trigger_restart_min_framework".equals(status);
+        return false;
     }
 
     /** {@hide} */
@@ -3057,14 +3044,4 @@
     public static final int CRYPT_TYPE_PATTERN = IVold.PASSWORD_TYPE_PATTERN;
     /** @hide */
     public static final int CRYPT_TYPE_PIN = IVold.PASSWORD_TYPE_PIN;
-
-    // Constants for the data available via StorageManagerService.getField.
-    /** @hide */
-    public static final String SYSTEM_LOCALE_KEY = "SystemLocale";
-    /** @hide */
-    public static final String OWNER_INFO_KEY = "OwnerInfo";
-    /** @hide */
-    public static final String PATTERN_VISIBLE_KEY = "PatternVisible";
-    /** @hide */
-    public static final String PASSWORD_VISIBLE_KEY = "PasswordVisible";
 }
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 052e4d0..4731504 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -74,6 +74,13 @@
     public static final String NAMESPACE_ACTIVITY_MANAGER = "activity_manager";
 
     /**
+     * Namespace for activity manager, specific to the "component alias" feature. We needed a
+     * different namespace in order to avoid phonetype from resetting it.
+     * @hide
+     */
+    public static final String NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS = "activity_manager_ca";
+
+    /**
      * Namespace for all activity manager related features that are used at the native level.
      * These features are applied at reboot.
      *
@@ -322,6 +329,13 @@
     public static final String NAMESPACE_NNAPI_NATIVE = "nnapi_native";
 
     /**
+     * Namespace for all OnDevicePersonalization related feature.
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_ON_DEVICE_PERSONALIZATION = "on_device_personalization";
+
+    /**
      * Namespace for features related to the Package Manager Service.
      *
      * @hide
@@ -586,6 +600,13 @@
     public static final String NAMESPACE_SELECTION_TOOLBAR = "selection_toolbar";
 
     /**
+     * Definitions for voice interaction related functions.
+     *
+     * @hide
+     */
+    public static final String NAMESPACE_VOICE_INTERACTION = "voice_interaction";
+
+    /**
      * List of namespaces which can be read without READ_DEVICE_CONFIG permission
      *
      * @hide
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f2137b3..a6ad5e5 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -85,8 +85,10 @@
 import android.util.Log;
 import android.util.MemoryIntArray;
 import android.view.Display;
+import android.view.MotionEvent;
 import android.view.Window;
 import android.view.WindowManager.LayoutParams;
+import android.widget.Editor;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
@@ -10727,14 +10729,6 @@
                 "communal_mode_trusted_networks";
 
         /**
-         * Setting to allow Fast Pair scans to be enabled.
-         * @hide
-         */
-        @SystemApi
-        @Readable
-        public static final String FAST_PAIR_SCAN_ENABLED = "fast_pair_scan_enabled";
-
-        /**
          * Setting to store denylisted system languages by the CEC {@code <Set Menu Language>}
          * confirmation dialog.
          *
@@ -15518,6 +15512,17 @@
         public static final String AUTOFILL_MAX_VISIBLE_DATASETS = "autofill_max_visible_datasets";
 
         /**
+         * Toggle for enabling stylus handwriting. When enabled, current Input method receives
+         * stylus {@link MotionEvent}s if an {@link Editor} is focused.
+         *
+         * @hide
+         */
+        @TestApi
+        @Readable
+        @SuppressLint("NoSettingsProvider")
+        public static final String STYLUS_HANDWRITING_ENABLED = "stylus_handwriting_enabled";
+
+        /**
          * Exemptions to the hidden API blacklist.
          *
          * @hide
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 8670759..001707d 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -1341,7 +1341,9 @@
                     public void onViewDetachedFromWindow(View v) {
                         if (mActivity == null || !mActivity.isChangingConfigurations()) {
                             // Only stop the dream if the view is not detached by relaunching
-                            // activity for configuration changes.
+                            // activity for configuration changes. It is important to also clear
+                            // the window reference in order to fully release the DreamActivity.
+                            mWindow = null;
                             mActivity = null;
                             finish();
                         }
diff --git a/core/java/android/service/dreams/OWNERS b/core/java/android/service/dreams/OWNERS
index f831805..489a5f6 100644
--- a/core/java/android/service/dreams/OWNERS
+++ b/core/java/android/service/dreams/OWNERS
@@ -1,3 +1,8 @@
 # Bug component: 78010
 
+brycelee@google.com
 dsandler@google.com
+galinap@google.com
+jjaggi@google.com
+michaelwr@google.com
+santoscordon@google.com
diff --git a/core/java/android/service/games/GameScreenshotResult.java b/core/java/android/service/games/GameScreenshotResult.java
index ae76e08..5490aef 100644
--- a/core/java/android/service/games/GameScreenshotResult.java
+++ b/core/java/android/service/games/GameScreenshotResult.java
@@ -18,8 +18,6 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.graphics.Bitmap;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -30,9 +28,7 @@
 /**
  * Result object for calls to {@link IGameSessionController#takeScreenshot}.
  *
- * It includes a status (see {@link #getStatus}) and, if the status is
- * {@link #GAME_SCREENSHOT_SUCCESS} an {@link android.graphics.Bitmap} result (see {@link
- * #getBitmap}).
+ * It includes a status only (see {@link #getStatus}).
  *
  * @hide
  */
@@ -54,8 +50,7 @@
 
     /**
      * Indicates that the result of a call to {@link IGameSessionController#takeScreenshot} was
-     * successful and an {@link android.graphics.Bitmap} result should be available by calling
-     * {@link #getBitmap}.
+     * successful.
      *
      * @hide
      */
@@ -81,9 +76,7 @@
             new Parcelable.Creator<GameScreenshotResult>() {
                 @Override
                 public GameScreenshotResult createFromParcel(Parcel source) {
-                    return new GameScreenshotResult(
-                            source.readInt(),
-                            source.readParcelable(null, Bitmap.class));
+                    return new GameScreenshotResult(source.readInt());
                 }
 
                 @Override
@@ -95,14 +88,11 @@
     @GameScreenshotStatus
     private final int mStatus;
 
-    @Nullable
-    private final Bitmap mBitmap;
-
     /**
-     * Creates a successful {@link GameScreenshotResult} with the provided bitmap.
+     * Creates a successful {@link GameScreenshotResult}.
      */
-    public static GameScreenshotResult createSuccessResult(@NonNull Bitmap bitmap) {
-        return new GameScreenshotResult(GAME_SCREENSHOT_SUCCESS, bitmap);
+    public static GameScreenshotResult createSuccessResult() {
+        return new GameScreenshotResult(GAME_SCREENSHOT_SUCCESS);
     }
 
     /**
@@ -110,12 +100,11 @@
      * {@link #GAME_SCREENSHOT_ERROR_INTERNAL_ERROR} status.
      */
     public static GameScreenshotResult createInternalErrorResult() {
-        return new GameScreenshotResult(GAME_SCREENSHOT_ERROR_INTERNAL_ERROR, null);
+        return new GameScreenshotResult(GAME_SCREENSHOT_ERROR_INTERNAL_ERROR);
     }
 
-    private GameScreenshotResult(@GameScreenshotStatus int status, @Nullable Bitmap bitmap) {
+    private GameScreenshotResult(@GameScreenshotStatus int status) {
         this.mStatus = status;
-        this.mBitmap = bitmap;
     }
 
     @Override
@@ -126,7 +115,6 @@
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeInt(mStatus);
-        dest.writeParcelable(mBitmap, flags);
     }
 
     @GameScreenshotStatus
@@ -134,29 +122,12 @@
         return mStatus;
     }
 
-    /**
-     * Gets the {@link Bitmap} result from a successful screenshot attempt.
-     *
-     * @return The bitmap.
-     * @throws IllegalStateException if this method is called when {@link #getStatus} does not
-     *                               return {@link #GAME_SCREENSHOT_SUCCESS}.
-     */
-    @NonNull
-    public Bitmap getBitmap() {
-        if (mBitmap == null) {
-            throw new IllegalStateException("Bitmap not available for failed screenshot result");
-        }
-        return mBitmap;
-    }
-
     @Override
     public String toString() {
         return "GameScreenshotResult{"
                 + "mStatus="
                 + mStatus
-                + ", has bitmap='"
-                + mBitmap != null ? "yes" : "no"
-                + "\'}";
+                + "}";
     }
 
     @Override
@@ -170,12 +141,11 @@
         }
 
         GameScreenshotResult that = (GameScreenshotResult) o;
-        return mStatus == that.mStatus
-                && Objects.equals(mBitmap, that.mBitmap);
+        return mStatus == that.mStatus;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mStatus, mBitmap);
+        return Objects.hash(mStatus);
     }
 }
diff --git a/core/java/android/service/games/GameSession.java b/core/java/android/service/games/GameSession.java
index 468e087c..1548f52 100644
--- a/core/java/android/service/games/GameSession.java
+++ b/core/java/android/service/games/GameSession.java
@@ -29,7 +29,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
-import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.Bundle;
@@ -367,7 +366,7 @@
     }
 
     /**
-     * Interface for returning screenshot outcome from calls to {@link #takeScreenshot}.
+     * Interface for handling result of {@link #takeScreenshot}.
      */
     public interface ScreenshotCallback {
 
@@ -402,18 +401,16 @@
 
         /**
          * Called when taking the screenshot succeeded.
-         *
-         * @param bitmap The screenshot.
          */
-        void onSuccess(@NonNull Bitmap bitmap);
+        void onSuccess();
     }
 
     /**
      * Takes a screenshot of the associated game. For this call to succeed, the device screen
      * must be turned on and the game task must be visible.
      *
-     * If the callback is called with {@link ScreenshotCallback#onSuccess}, the provided {@link
-     * Bitmap} may be used.
+     * If the callback is called with {@link ScreenshotCallback#onSuccess}, the screenshot is
+     * taken successfully.
      *
      * If the callback is called with {@link ScreenshotCallback#onFailure}, the provided status
      * code should be checked.
@@ -460,7 +457,7 @@
         @GameScreenshotResult.GameScreenshotStatus int status = result.getStatus();
         switch (status) {
             case GameScreenshotResult.GAME_SCREENSHOT_SUCCESS:
-                callback.onSuccess(result.getBitmap());
+                callback.onSuccess();
                 break;
             case GameScreenshotResult.GAME_SCREENSHOT_ERROR_INTERNAL_ERROR:
                 Slog.w(TAG, "Error taking screenshot");
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index b507328..0829d28 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -15,18 +15,19 @@
  */
 package android.service.quicksettings;
 
-import android.Manifest;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.app.Dialog;
 import android.app.Service;
+import android.app.StatusBarManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.drawable.Icon;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -147,13 +148,6 @@
             "android.service.quicksettings.TOGGLEABLE_TILE";
 
     /**
-     * Used to notify SysUI that Listening has be requested.
-     * @hide
-     */
-    public static final String ACTION_REQUEST_LISTENING =
-            "android.service.quicksettings.action.REQUEST_LISTENING";
-
-    /**
      * @hide
      */
     public static final String EXTRA_SERVICE = "service";
@@ -482,14 +476,24 @@
      *
      * This method is only applicable to tiles that have {@link #META_DATA_ACTIVE_TILE} defined
      * as true on their TileService Manifest declaration, and will do nothing otherwise.
+     *
+     * For apps targeting {@link Build.VERSION_CODES#TIRAMISU} or later, this call may throw
+     * the following exceptions if the request is not valid:
+     * <ul>
+     *     <li> {@link NullPointerException} if {@code component} is {@code null}.</li>
+     *     <li> {@link SecurityException} if the package of {@code component} does not match
+     *     the calling package or if the calling user cannot act on behalf of the user from the
+     *     {@code context}.</li>
+     *     <li> {@link IllegalArgumentException} if the user of the {@code context} is not the
+     *     current user.</li>
+     * </ul>
      */
     public static final void requestListeningState(Context context, ComponentName component) {
-        final ComponentName sysuiComponent = ComponentName.unflattenFromString(
-                context.getResources().getString(
-                        com.android.internal.R.string.config_systemUIServiceComponent));
-        Intent intent = new Intent(ACTION_REQUEST_LISTENING);
-        intent.putExtra(Intent.EXTRA_COMPONENT_NAME, component);
-        intent.setPackage(sysuiComponent.getPackageName());
-        context.sendBroadcast(intent, Manifest.permission.BIND_QUICK_SETTINGS_TILE);
+        StatusBarManager sbm = context.getSystemService(StatusBarManager.class);
+        if (sbm == null) {
+            Log.e(TAG, "No StatusBarManager service found");
+            return;
+        }
+        sbm.requestTileServiceListeningState(component);
     }
 }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index a2938a8..ef792d4 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -252,6 +252,7 @@
         final InsetsVisibilities mRequestedVisibilities = new InsetsVisibilities();
         final InsetsSourceControl[] mTempControls = new InsetsSourceControl[0];
         final MergedConfiguration mMergedConfiguration = new MergedConfiguration();
+        final Bundle mSyncSeqIdBundle = new Bundle();
         private final Point mSurfaceSize = new Point();
         private final Point mLastSurfaceSize = new Point();
         private final Matrix mTmpMatrix = new Matrix();
@@ -391,7 +392,7 @@
             @Override
             public void resized(ClientWindowFrames frames, boolean reportDraw,
                     MergedConfiguration mergedConfiguration, boolean forceLayout,
-                    boolean alwaysConsumeSystemBars, int displayId) {
+                    boolean alwaysConsumeSystemBars, int displayId, int syncSeqId) {
                 Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED,
                         reportDraw ? 1 : 0,
                         mergedConfiguration);
@@ -1151,7 +1152,7 @@
                     final int relayoutResult = mSession.relayout(
                             mWindow, mLayout, mWidth, mHeight,
                             View.VISIBLE, 0, mWinFrames, mMergedConfiguration, mSurfaceControl,
-                            mInsetsState, mTempControls);
+                            mInsetsState, mTempControls, mSyncSeqIdBundle);
 
                     final int transformHint = SurfaceControl.rotationToBufferTransform(
                             (mDisplayInstallOrientation + mDisplay.getRotation()) % 4);
@@ -1338,7 +1339,8 @@
                         mSurfaceCreated = true;
                         if (redrawNeeded) {
                             resetWindowPages();
-                            mSession.finishDrawing(mWindow, null /* postDrawTransaction */);
+                            mSession.finishDrawing(mWindow, null /* postDrawTransaction */,
+                                                   Integer.MAX_VALUE);
                             processLocalColors(mPendingXOffset, mPendingXOffsetStep);
                             notifyColorsChanged();
                         }
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index c1fcd66..f844592 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -27,6 +27,7 @@
 import android.os.Build;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.service.carrier.CarrierService;
 import android.telephony.Annotation.CallState;
 import android.telephony.Annotation.DataActivityType;
 import android.telephony.Annotation.DisconnectCauses;
@@ -36,6 +37,7 @@
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SimActivationState;
 import android.telephony.Annotation.SrvccState;
+import android.telephony.TelephonyManager.CarrierPrivilegesCallback;
 import android.telephony.TelephonyManager.CarrierPrivilegesListener;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsReasonInfo;
@@ -44,17 +46,19 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.listeners.ListenerExecutor;
-import com.android.internal.telephony.ICarrierPrivilegesListener;
+import com.android.internal.telephony.ICarrierPrivilegesCallback;
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
 import com.android.internal.telephony.ITelephonyRegistry;
 
 import java.lang.ref.WeakReference;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.WeakHashMap;
 import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
 
 /**
  * A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update
@@ -1260,34 +1264,78 @@
                 pkgName, attributionTag, callback, new int[0], notifyNow);
     }
 
-    private static class CarrierPrivilegesListenerWrapper extends ICarrierPrivilegesListener.Stub
+    // TODO(b/216549778): Remove listener logic once all clients switch to CarrierPrivilegesCallback
+    private static class CarrierPrivilegesCallbackWrapper extends ICarrierPrivilegesCallback.Stub
             implements ListenerExecutor {
-        private final WeakReference<CarrierPrivilegesListener> mListener;
-        private final Executor mExecutor;
+        // Either mListener or mCallback may be null, never both
+        @Nullable private final WeakReference<CarrierPrivilegesListener> mListener;
+        @Nullable private final WeakReference<CarrierPrivilegesCallback> mCallback;
+        @NonNull private final Executor mExecutor;
 
-        CarrierPrivilegesListenerWrapper(CarrierPrivilegesListener listener, Executor executor) {
+        CarrierPrivilegesCallbackWrapper(
+                @NonNull CarrierPrivilegesCallback callback, @NonNull Executor executor) {
+            mListener = null;
+            mCallback = new WeakReference<>(callback);
+            mExecutor = executor;
+        }
+
+        CarrierPrivilegesCallbackWrapper(
+                @NonNull CarrierPrivilegesListener listener, @NonNull Executor executor) {
             mListener = new WeakReference<>(listener);
+            mCallback = null;
             mExecutor = executor;
         }
 
         @Override
         public void onCarrierPrivilegesChanged(
-                List<String> privilegedPackageNames, int[] privilegedUids) {
-            Binder.withCleanCallingIdentity(
-                    () ->
-                            executeSafely(
-                                    mExecutor,
-                                    mListener::get,
-                                    cpl ->
-                                            cpl.onCarrierPrivilegesChanged(
-                                                    privilegedPackageNames, privilegedUids)));
+                @NonNull List<String> privilegedPackageNames, @NonNull int[] privilegedUids) {
+            if (mListener != null) {
+                Binder.withCleanCallingIdentity(
+                        () ->
+                                executeSafely(
+                                        mExecutor,
+                                        mListener::get,
+                                        cpl ->
+                                                cpl.onCarrierPrivilegesChanged(
+                                                        privilegedPackageNames, privilegedUids)));
+            }
+
+            if (mCallback != null) {
+                // AIDL interface does not support Set, keep the List/Array and translate them here
+                Set<String> privilegedPkgNamesSet = Set.copyOf(privilegedPackageNames);
+                Set<Integer> privilegedUidsSet = Arrays.stream(privilegedUids).boxed().collect(
+                        Collectors.toSet());
+                Binder.withCleanCallingIdentity(
+                        () ->
+                                executeSafely(
+                                        mExecutor,
+                                        mCallback::get,
+                                        cpc ->
+                                                cpc.onCarrierPrivilegesChanged(
+                                                        privilegedPkgNamesSet, privilegedUidsSet)));
+            }
+        }
+
+        @Override
+        public void onCarrierServiceChanged(@Nullable String packageName, int uid) {
+            if (mCallback != null) {
+                Binder.withCleanCallingIdentity(
+                        () ->
+                                executeSafely(
+                                        mExecutor,
+                                        mCallback::get,
+                                        cpc -> cpc.onCarrierServiceChanged(packageName, uid)));
+            }
         }
     }
 
-    @GuardedBy("sCarrierPrivilegeListeners")
-    private static final WeakHashMap<
-                    CarrierPrivilegesListener, WeakReference<CarrierPrivilegesListenerWrapper>>
-            sCarrierPrivilegeListeners = new WeakHashMap<>();
+    // TODO(b/216549778): Change the map key to CarrierPrivilegesCallback once all clients switch to
+    // CarrierPrivilegesCallback. Before that, the key is either CarrierPrivilegesCallback or
+    // CarrierPrivilegesListener, no logic actually depends on the type.
+    @NonNull
+    @GuardedBy("sCarrierPrivilegeCallbacks")
+    private static final WeakHashMap<Object,  WeakReference<CarrierPrivilegesCallbackWrapper>>
+            sCarrierPrivilegeCallbacks = new WeakHashMap<>();
 
     /**
      * Registers a {@link CarrierPrivilegesListener} on the given {@code logicalSlotIndex} to
@@ -1297,7 +1345,11 @@
      * @param logicalSlotIndex The SIM slot to listen on
      * @param executor The executor where {@code listener} will be invoked
      * @param listener The callback to register
+     *
+     * @deprecated Use {@link #addCarrierPrivilegesCallback} instead. This API will be removed
+     * prior to API finalization.
      */
+    @Deprecated
     public void addCarrierPrivilegesListener(
             int logicalSlotIndex,
             @NonNull @CallbackExecutor Executor executor,
@@ -1305,18 +1357,18 @@
         if (listener == null || executor == null) {
             throw new IllegalArgumentException("listener and executor must be non-null");
         }
-        synchronized (sCarrierPrivilegeListeners) {
-            WeakReference<CarrierPrivilegesListenerWrapper> existing =
-                    sCarrierPrivilegeListeners.get(listener);
+        synchronized (sCarrierPrivilegeCallbacks) {
+            WeakReference<CarrierPrivilegesCallbackWrapper> existing =
+                    sCarrierPrivilegeCallbacks.get(listener);
             if (existing != null && existing.get() != null) {
                 Log.d(TAG, "addCarrierPrivilegesListener: listener already registered");
                 return;
             }
-            CarrierPrivilegesListenerWrapper wrapper =
-                    new CarrierPrivilegesListenerWrapper(listener, executor);
-            sCarrierPrivilegeListeners.put(listener, new WeakReference<>(wrapper));
+            CarrierPrivilegesCallbackWrapper wrapper =
+                    new CarrierPrivilegesCallbackWrapper(listener, executor);
+            sCarrierPrivilegeCallbacks.put(listener, new WeakReference<>(wrapper));
             try {
-                sRegistry.addCarrierPrivilegesListener(
+                sRegistry.addCarrierPrivilegesCallback(
                         logicalSlotIndex,
                         wrapper,
                         mContext.getOpPackageName(),
@@ -1331,19 +1383,84 @@
      * Unregisters a {@link CarrierPrivilegesListener}.
      *
      * @param listener The callback to unregister
+     *
+     * @deprecated Use {@link #removeCarrierPrivilegesCallback} instead. The callback will prior
+     * to API finalization.
      */
+    @Deprecated
     public void removeCarrierPrivilegesListener(@NonNull CarrierPrivilegesListener listener) {
         if (listener == null) {
             throw new IllegalArgumentException("listener must be non-null");
         }
-        synchronized (sCarrierPrivilegeListeners) {
-            WeakReference<CarrierPrivilegesListenerWrapper> ref =
-                    sCarrierPrivilegeListeners.remove(listener);
+        synchronized (sCarrierPrivilegeCallbacks) {
+            WeakReference<CarrierPrivilegesCallbackWrapper> ref =
+                    sCarrierPrivilegeCallbacks.remove(listener);
             if (ref == null) return;
-            CarrierPrivilegesListenerWrapper wrapper = ref.get();
+            CarrierPrivilegesCallbackWrapper wrapper = ref.get();
             if (wrapper == null) return;
             try {
-                sRegistry.removeCarrierPrivilegesListener(wrapper, mContext.getOpPackageName());
+                sRegistry.removeCarrierPrivilegesCallback(wrapper, mContext.getOpPackageName());
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Registers a {@link CarrierPrivilegesCallback} on the given {@code logicalSlotIndex} to
+     * receive callbacks when the set of packages with carrier privileges changes. The callback will
+     * immediately be called with the latest state.
+     *
+     * @param logicalSlotIndex The SIM slot to listen on
+     * @param executor The executor where {@code listener} will be invoked
+     * @param callback The callback to register
+     */
+    public void addCarrierPrivilegesCallback(
+            int logicalSlotIndex,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull CarrierPrivilegesCallback callback) {
+        if (callback == null || executor == null) {
+            throw new IllegalArgumentException("callback and executor must be non-null");
+        }
+        synchronized (sCarrierPrivilegeCallbacks) {
+            WeakReference<CarrierPrivilegesCallbackWrapper> existing =
+                    sCarrierPrivilegeCallbacks.get(callback);
+            if (existing != null && existing.get() != null) {
+                Log.d(TAG, "addCarrierPrivilegesCallback: callback already registered");
+                return;
+            }
+            CarrierPrivilegesCallbackWrapper wrapper =
+                    new CarrierPrivilegesCallbackWrapper(callback, executor);
+            sCarrierPrivilegeCallbacks.put(callback, new WeakReference<>(wrapper));
+            try {
+                sRegistry.addCarrierPrivilegesCallback(
+                        logicalSlotIndex,
+                        wrapper,
+                        mContext.getOpPackageName(),
+                        mContext.getAttributionTag());
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Unregisters a {@link CarrierPrivilegesCallback}.
+     *
+     * @param callback The callback to unregister
+     */
+    public void removeCarrierPrivilegesCallback(@NonNull CarrierPrivilegesCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("listener must be non-null");
+        }
+        synchronized (sCarrierPrivilegeCallbacks) {
+            WeakReference<CarrierPrivilegesCallbackWrapper> ref =
+                    sCarrierPrivilegeCallbacks.remove(callback);
+            if (ref == null) return;
+            CarrierPrivilegesCallbackWrapper wrapper = ref.get();
+            if (wrapper == null) return;
+            try {
+                sRegistry.removeCarrierPrivilegesCallback(wrapper, mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1359,15 +1476,33 @@
      */
     public void notifyCarrierPrivilegesChanged(
             int logicalSlotIndex,
-            @NonNull List<String> privilegedPackageNames,
-            @NonNull int[] privilegedUids) {
+            @NonNull Set<String> privilegedPackageNames,
+            @NonNull Set<Integer> privilegedUids) {
         if (privilegedPackageNames == null || privilegedUids == null) {
             throw new IllegalArgumentException(
                     "privilegedPackageNames and privilegedUids must be non-null");
         }
         try {
-            sRegistry.notifyCarrierPrivilegesChanged(
-                    logicalSlotIndex, privilegedPackageNames, privilegedUids);
+            // AIDL doesn't support Set yet. Convert Set to List/Array
+            List<String> pkgList = List.copyOf(privilegedPackageNames);
+            int[] uids = privilegedUids.stream().mapToInt(Number::intValue).toArray();
+            sRegistry.notifyCarrierPrivilegesChanged(logicalSlotIndex, pkgList, uids);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notify listeners that the {@link CarrierService} for current user has changed.
+     *
+     * @param logicalSlotIndex the SIM slot the change occurred on
+     * @param packageName the package name of the changed {@link CarrierService}
+     * @param uid the UID of the changed {@link CarrierService}
+     */
+    public void notifyCarrierServiceChanged(int logicalSlotIndex, @Nullable String packageName,
+            int uid) {
+        try {
+            sRegistry.notifyCarrierServiceChanged(logicalSlotIndex, packageName, uid);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/text/PrecomputedText.java b/core/java/android/text/PrecomputedText.java
index 9307e56..f31a690 100644
--- a/core/java/android/text/PrecomputedText.java
+++ b/core/java/android/text/PrecomputedText.java
@@ -99,7 +99,7 @@
         private final @Layout.HyphenationFrequency int mHyphenationFrequency;
 
         // The line break configuration for calculating text wrapping.
-        private final @Nullable LineBreakConfig mLineBreakConfig;
+        private final @NonNull LineBreakConfig mLineBreakConfig;
 
         /**
          * A builder for creating {@link Params}.
@@ -119,7 +119,7 @@
                     Layout.HYPHENATION_FREQUENCY_NORMAL;
 
             // The line break configuration for calculating text wrapping.
-            private @Nullable LineBreakConfig mLineBreakConfig;
+            private @NonNull LineBreakConfig mLineBreakConfig = LineBreakConfig.NONE;
 
             /**
              * Builder constructor.
@@ -212,7 +212,7 @@
         // For the external developers, use Builder instead.
         /** @hide */
         public Params(@NonNull TextPaint paint,
-                @Nullable LineBreakConfig lineBreakConfig,
+                @NonNull LineBreakConfig lineBreakConfig,
                 @NonNull TextDirectionHeuristic textDir,
                 @Layout.BreakStrategy int strategy,
                 @Layout.HyphenationFrequency int frequency) {
@@ -260,11 +260,12 @@
         }
 
         /**
-         * Return the line break configuration for this text.
+         * Returns the {@link LineBreakConfig} for this text.
          *
-         * @return the current line break configuration, null if no line break configuration is set.
+         * @return the current line break configuration. The {@link LineBreakConfig} with default
+         * values will be returned if no line break configuration is set.
          */
-        public @Nullable LineBreakConfig getLineBreakConfig() {
+        public @NonNull LineBreakConfig getLineBreakConfig() {
             return mLineBreakConfig;
         }
 
@@ -297,9 +298,9 @@
         /** @hide */
         public @CheckResultUsableResult int checkResultUsable(@NonNull TextPaint paint,
                 @NonNull TextDirectionHeuristic textDir, @Layout.BreakStrategy int strategy,
-                @Layout.HyphenationFrequency int frequency, @Nullable LineBreakConfig lbConfig) {
+                @Layout.HyphenationFrequency int frequency, @NonNull LineBreakConfig lbConfig) {
             if (mBreakStrategy == strategy && mHyphenationFrequency == frequency
-                    && isLineBreakEquals(mLineBreakConfig, lbConfig)
+                    && mLineBreakConfig.equals(lbConfig)
                     && mPaint.equalsForTextMeasurement(paint)) {
                 return mTextDir == textDir ? USABLE : NEED_RECOMPUTE;
             } else {
@@ -308,29 +309,6 @@
         }
 
         /**
-         * Check the two LineBreakConfig instances are equal.
-         * This method assumes they are equal if one parameter is null and the other parameter has
-         * a LineBreakStyle value of LineBreakConfig.LINE_BREAK_STYLE_NONE.
-         *
-         * @param o1 the first LineBreakConfig instance.
-         * @param o2 the second LineBreakConfig instance.
-         * @return true if the two LineBreakConfig instances are equal.
-         */
-        private boolean isLineBreakEquals(LineBreakConfig o1, LineBreakConfig o2) {
-            if (Objects.equals(o1, o2)) {
-                return true;
-            }
-            if (o1 == null && (o2 != null
-                    && o2.getLineBreakStyle() == LineBreakConfig.LINE_BREAK_STYLE_NONE)) {
-                return true;
-            } else if (o2 == null && (o1 != null
-                    && o1.getLineBreakStyle() == LineBreakConfig.LINE_BREAK_STYLE_NONE)) {
-                return true;
-            }
-            return false;
-        }
-
-        /**
          * Check if the same text layout.
          *
          * @return true if this and the given param result in the same text layout
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index b10fc37..2f85d2b6 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -112,6 +112,7 @@
             b.mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE;
             b.mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE;
             b.mJustificationMode = Layout.JUSTIFICATION_MODE_NONE;
+            b.mLineBreakConfig = LineBreakConfig.NONE;
             return b;
         }
 
@@ -410,7 +411,8 @@
          *
          * @param lineBreakConfig the line break configuration for text wrapping.
          * @return this builder, useful for chaining.
-         * @see android.widget.TextView#setLineBreakConfig
+         * @see android.widget.TextView#setLineBreakStyle
+         * @see android.widget.TextView#setLineBreakWordStyle
          */
         @NonNull
         public Builder setLineBreakConfig(@NonNull LineBreakConfig lineBreakConfig) {
@@ -454,7 +456,7 @@
         @Nullable private int[] mRightIndents;
         private int mJustificationMode;
         private boolean mAddLastLineLineSpacing;
-        private LineBreakConfig mLineBreakConfig;
+        private LineBreakConfig mLineBreakConfig = LineBreakConfig.NONE;
 
         private final Paint.FontMetricsInt mFontMetricsInt = new Paint.FontMetricsInt();
 
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 4541f3a..34e7ea7 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -71,8 +71,8 @@
      * Hide back key in the Settings two pane design.
      * @hide
      */
-    public static final String SETTINGS_HIDE_SECONDARY_PAGE_BACK_BUTTON_IN_TWO_PANE =
-            "settings_hide_secondary_page_back_button_in_two_pane";
+    public static final String SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE =
+            "settings_hide_second_layer_page_navigate_up_button_in_two_pane";
 
     private static final Map<String, String> DEFAULT_FLAGS;
 
@@ -96,10 +96,10 @@
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_SECURITY_HUB, "true");
         DEFAULT_FLAGS.put(SETTINGS_SUPPORT_LARGE_SCREEN, "true");
         DEFAULT_FLAGS.put("settings_search_always_expand", "true");
-        DEFAULT_FLAGS.put(SETTINGS_APP_LANGUAGE_SELECTION, "true");
+        DEFAULT_FLAGS.put(SETTINGS_APP_LANGUAGE_SELECTION, "false");
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true");
         DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "false");
-        DEFAULT_FLAGS.put(SETTINGS_HIDE_SECONDARY_PAGE_BACK_BUTTON_IN_TWO_PANE, "true");
+        DEFAULT_FLAGS.put(SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE, "true");
     }
 
     private static final Set<String> PERSISTENT_FLAGS;
@@ -109,7 +109,7 @@
         PERSISTENT_FLAGS.add(SETTINGS_SUPPORT_LARGE_SCREEN);
         PERSISTENT_FLAGS.add(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);
         PERSISTENT_FLAGS.add(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME);
-        PERSISTENT_FLAGS.add(SETTINGS_HIDE_SECONDARY_PAGE_BACK_BUTTON_IN_TWO_PANE);
+        PERSISTENT_FLAGS.add(SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE);
     }
 
     /**
diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java
index c1413be..190adbd 100644
--- a/core/java/android/view/HandwritingInitiator.java
+++ b/core/java/android/view/HandwritingInitiator.java
@@ -249,19 +249,19 @@
             return;
         }
 
-        Rect handwritingArea = getViewHandwritingArea(connectedView);
-        if (handwritingArea != null) {
-            if (contains(handwritingArea, mState.mStylusDownX, mState.mStylusDownY)) {
-                startHandwriting(connectedView);
-            }
+        final Rect handwritingArea = getViewHandwritingArea(connectedView);
+        if (contains(handwritingArea, mState.mStylusDownX, mState.mStylusDownY)) {
+            startHandwriting(connectedView);
+        } else {
+            reset();
         }
-        reset();
     }
 
     /** For test only. */
     @VisibleForTesting
     public void startHandwriting(@NonNull View view) {
         mImm.startStylusHandwriting(view);
+        reset();
     }
 
     /**
@@ -287,7 +287,7 @@
         final View connectedView = getConnectedView();
         if (connectedView != null && connectedView.isAutoHandwritingEnabled()) {
             final Rect handwritingArea = getViewHandwritingArea(connectedView);
-            if (handwritingArea != null && contains(handwritingArea, x, y)) {
+            if (contains(handwritingArea, x, y)) {
                 return connectedView;
             }
         }
@@ -298,8 +298,7 @@
         for (HandwritableViewInfo viewInfo : handwritableViewInfos) {
             final View view = viewInfo.getView();
             if (!view.isAutoHandwritingEnabled()) continue;
-            final Rect rect = viewInfo.getHandwritingArea();
-            if (rect != null && contains(rect, x, y)) {
+            if (contains(viewInfo.getHandwritingArea(), x, y)) {
                 return viewInfo.getView();
             }
         }
@@ -315,12 +314,15 @@
     private static Rect getViewHandwritingArea(@NonNull View view) {
         final ViewParent viewParent = view.getParent();
         if (viewParent != null && view.isAttachedToWindow() && view.isAggregatedVisible()) {
-            Rect handwritingArea = view.getHandwritingArea();
-            if (handwritingArea == null) {
-                handwritingArea = new Rect(0, 0, view.getWidth(), view.getHeight());
+            final Rect localHandwritingArea = view.getHandwritingArea();
+            final Rect globalHandwritingArea = new Rect();
+            if (localHandwritingArea != null) {
+                globalHandwritingArea.set(localHandwritingArea);
+            } else {
+                globalHandwritingArea.set(0, 0, view.getWidth(), view.getHeight());
             }
-            if (viewParent.getChildVisibleRect(view, handwritingArea, null)) {
-                return handwritingArea;
+            if (viewParent.getChildVisibleRect(view, globalHandwritingArea, null)) {
+                return globalHandwritingArea;
             }
         }
         return null;
@@ -329,7 +331,8 @@
     /**
      * Return true if the (x, y) is inside by the given {@link Rect}.
      */
-    private boolean contains(@NonNull Rect rect, float x, float y) {
+    private boolean contains(@Nullable Rect rect, float x, float y) {
+        if (rect == null) return false;
         return x >= rect.left && x < rect.right && y >= rect.top && y < rect.bottom;
     }
 
@@ -481,17 +484,18 @@
             if (!mIsDirty) {
                 return true;
             }
-            final Rect localRect = view.getHandwritingArea();
-            if (localRect == null) {
+            final Rect handwritingArea = view.getHandwritingArea();
+            if (handwritingArea == null) {
                 return false;
             }
 
             ViewParent parent = view.getParent();
             if (parent != null) {
-                final Rect newRect = new Rect(localRect);
-                if (parent.getChildVisibleRect(view, newRect, null /* offset */)) {
-                    mHandwritingArea = newRect;
-                } else {
+                if (mHandwritingArea == null) {
+                    mHandwritingArea = new Rect();
+                }
+                mHandwritingArea.set(handwritingArea);
+                if (!parent.getChildVisibleRect(view, mHandwritingArea, null /* offset */)) {
                     mHandwritingArea = null;
                 }
             }
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 12421ed..1f6cee6 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -55,7 +55,8 @@
 
     void resized(in ClientWindowFrames frames, boolean reportDraw,
             in MergedConfiguration newMergedConfiguration,
-            boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId);
+            boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId,
+            int syncSeqId);
 
     /**
      * Called when the window insets configuration has changed.
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 3f29e3f..a35a195 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -201,7 +201,12 @@
     boolean isKeyguardSecure(int userId);
     void dismissKeyguard(IKeyguardDismissCallback callback, CharSequence message);
 
+    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+            + ".permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)")
     void addKeyguardLockedStateListener(in IKeyguardLockedStateListener listener);
+
+    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+            + ".permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)")
     void removeKeyguardLockedStateListener(in IKeyguardLockedStateListener listener);
 
     // Requires INTERACT_ACROSS_USERS_FULL permission
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 5c7c844..fd86900 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -104,7 +104,8 @@
             int requestedWidth, int requestedHeight, int viewVisibility,
             int flags, out ClientWindowFrames outFrames,
             out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl,
-            out InsetsState insetsState, out InsetsSourceControl[] activeControls);
+            out InsetsState insetsState, out InsetsSourceControl[] activeControls,
+            out Bundle bundle);
 
     /*
      * Notify the window manager that an application is relaunching and
@@ -142,7 +143,8 @@
      * is null if there is no sync required.
      */
     @UnsupportedAppUsage
-    oneway void finishDrawing(IWindow window, in SurfaceControl.Transaction postDrawTransaction);
+    oneway void finishDrawing(IWindow window, in SurfaceControl.Transaction postDrawTransaction,
+            int seqId);
 
     @UnsupportedAppUsage
     oneway void setInTouchMode(boolean showFocus);
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index 2b579d0..ef0c19c 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -16,20 +16,57 @@
 
 package android.view;
 
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.graphics.Matrix;
 import android.graphics.Region;
 import android.gui.TouchOcclusionMode;
 import android.os.IBinder;
+import android.os.InputConfig;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
 
 /**
- * Functions as a handle for a window that can receive input.
- * Enables the native input dispatcher to refer indirectly to the window manager's window state.
+ * Functions as a handle for a window that can receive input, and allows for the behavior of the
+ * input window to be configured.
  * @hide
  */
 public final class InputWindowHandle {
+
+    /**
+     * An internal annotation for all the {@link android.os.InputConfig} flags that can be
+     * specified to {@link #inputConfig} to control the behavior of an input window. Only the
+     * flags listed here are valid for use in Java.
+     *
+     * The default flag value is 0, which is what we expect for a normal application window. Adding
+     * a flag indicates that the window's behavior deviates from that of a normal application
+     * window.
+     *
+     * The flags are defined as an AIDL enum to keep it in sync with native code.
+     * {@link android.os.InputConfig} flags that are not listed here should not be used in Java, and
+     * are only meant to be used in native code.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, value = {
+            InputConfig.DEFAULT,
+            InputConfig.NO_INPUT_CHANNEL,
+            InputConfig.NOT_FOCUSABLE,
+            InputConfig.NOT_TOUCHABLE,
+            InputConfig.PREVENT_SPLITTING,
+            InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER,
+            InputConfig.IS_WALLPAPER,
+            InputConfig.PAUSE_DISPATCHING,
+            InputConfig.TRUSTED_OVERLAY,
+            InputConfig.WATCH_OUTSIDE_TOUCH,
+            InputConfig.SLIPPERY,
+            InputConfig.DISABLE_USER_ACTIVITY,
+            InputConfig.SPY,
+            InputConfig.INTERCEPTS_STYLUS,
+    })
+    public @interface InputConfigFlags {}
+
     // Pointer to the native input window handle.
     // This field is lazily initialized via JNI.
     @SuppressWarnings("unused")
@@ -56,7 +93,8 @@
     // The window name.
     public String name;
 
-    // Window layout params attributes.  (WindowManager.LayoutParams)
+    // Window layout params attributes. (WindowManager.LayoutParams)
+    // These values do not affect any input configurations. Use {@link #inputConfig} instead.
     public int layoutParamsFlags;
     public int layoutParamsType;
 
@@ -78,20 +116,9 @@
     // Window touchable region.
     public final Region touchableRegion = new Region();
 
-    // Window is visible.
-    public boolean visible;
-
-    // Window can be focused.
-    public boolean focusable;
-
-    // Window has wallpaper.  (window is the current wallpaper target)
-    public boolean hasWallpaper;
-
-    // Input event dispatching is paused.
-    public boolean paused;
-
-    // Window is trusted overlay.
-    public boolean trustedOverlay;
+    // Flags that specify the behavior of this input window. See {@link #InputConfigFlags}.
+    @InputConfigFlags
+    public int inputConfig;
 
     // What effect this window has on touch occlusion if it lets touches pass through
     // By default windows will block touches if they are untrusted and from a different UID due to
@@ -105,25 +132,21 @@
     // Owner package of the window
     public String packageName;
 
-    // Window input features.
-    public int inputFeatures;
-
-    // Display this input is on.
+    // Display this input window is on.
     public int displayId;
 
     /**
-     * Crops the touchable region to the bounds of the surface provided.
+     * Crops the {@link #touchableRegion} to the bounds of the surface provided.
      *
-     * This can be used in cases where the window is not
-     * {@link android.view.WindowManager#FLAG_NOT_TOUCH_MODAL} but should be constrained to the
-     * bounds of a parent window. That is the window should receive touch events outside its
-     * window but be limited to its stack bounds, such as in the case of split screen.
+     * This can be used in cases where the window should be constrained to the bounds of a parent
+     * window. That is, the window should receive touch events outside its window frame, but be
+     * limited to its stack bounds, such as in the case of split screen.
      */
     public WeakReference<SurfaceControl> touchableRegionSurfaceControl = new WeakReference<>(null);
 
     /**
-     * Replace {@link touchableRegion} with the bounds of {@link touchableRegionSurfaceControl}. If
-     * the handle is {@code null}, the bounds of the surface associated with this window is used
+     * Replace {@link #touchableRegion} with the bounds of {@link #touchableRegionSurfaceControl}.
+     * If the handle is {@code null}, the bounds of the surface associated with this window is used
      * as the touchable region.
      */
     public boolean replaceTouchableRegionWithCrop;
@@ -147,7 +170,6 @@
                 .append(", frame=[").append(frameLeft).append(",").append(frameTop).append(",")
                         .append(frameRight).append(",").append(frameBottom).append("]")
                 .append(", touchableRegion=").append(touchableRegion)
-                .append(", visible=").append(visible)
                 .append(", scaleFactor=").append(scaleFactor)
                 .append(", transform=").append(transform)
                 .append(", windowToken=").append(windowToken)
@@ -165,11 +187,11 @@
     }
 
     /**
-     * Set the window touchable region to the bounds of {@link touchableRegionBounds} ignoring any
-     * touchable region provided.
+     * Set the window's touchable region to the bounds of {@link #touchableRegionSurfaceControl}
+     * and ignore the value of {@link #touchableRegion}.
      *
-     * @param bounds surface to set the touchable region to. Set to {@code null} to set the bounds
-     * to the current surface.
+     * @param bounds surface to set the touchable region to. Set to {@code null} to set the
+     *               touchable region as the current surface bounds.
      */
     public void replaceTouchableRegionWithCrop(@Nullable SurfaceControl bounds) {
         setTouchableRegionCrop(bounds);
@@ -195,4 +217,17 @@
         window = IWindow.Stub.asInterface(windowToken);
         return window;
     }
+
+    /**
+     * Set the provided inputConfig flag values.
+     * @param inputConfig the flag values to change
+     * @param value the provided flag values are set when true, and cleared when false
+     */
+    public void setInputConfig(@InputConfigFlags int inputConfig, boolean value) {
+        if (value) {
+            this.inputConfig |= inputConfig;
+            return;
+        }
+        this.inputConfig &= ~inputConfig;
+    }
 }
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 71c1b7c..a4841f6 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -23,6 +23,7 @@
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.toInternalType;
 import static android.view.InsetsState.toPublicType;
+import static android.view.ViewRootImpl.CAPTION_ON_SHELL;
 import static android.view.WindowInsets.Type.all;
 import static android.view.WindowInsets.Type.ime;
 
@@ -682,9 +683,15 @@
 
     @VisibleForTesting
     public boolean onStateChanged(InsetsState state) {
-        boolean stateChanged = !mState.equals(state, true /* excludingCaptionInsets */,
-                        false /* excludeInvisibleIme */)
-                || !captionInsetsUnchanged();
+        boolean stateChanged = false;
+        if (!CAPTION_ON_SHELL) {
+            stateChanged = !mState.equals(state, true /* excludingCaptionInsets */,
+                    false /* excludeInvisibleIme */)
+                    || captionInsetsUnchanged();
+        } else {
+            stateChanged = !mState.equals(state, false /* excludingCaptionInsets */,
+                    false /* excludeInvisibleIme */);
+        }
         if (!stateChanged && mLastDispatchedState.equals(state)) {
             return false;
         }
@@ -758,16 +765,20 @@
     }
 
     private boolean captionInsetsUnchanged() {
+        if (CAPTION_ON_SHELL) {
+            return false;
+        }
         if (mState.peekSource(ITYPE_CAPTION_BAR) == null
                 && mCaptionInsetsHeight == 0) {
-            return true;
+            return false;
         }
         if (mState.peekSource(ITYPE_CAPTION_BAR) != null
                 && mCaptionInsetsHeight
                 == mState.peekSource(ITYPE_CAPTION_BAR).getFrame().height()) {
-            return true;
+            return false;
         }
-        return false;
+
+        return true;
     }
 
     private void startResizingAnimationIfNeeded(InsetsState fromState) {
@@ -1582,11 +1593,15 @@
 
     @Override
     public void setCaptionInsetsHeight(int height) {
+        // This method is to be removed once the caption is moved to the shell.
+        if (CAPTION_ON_SHELL) {
+            return;
+        }
         if (mCaptionInsetsHeight != height) {
             mCaptionInsetsHeight = height;
             if (mCaptionInsetsHeight != 0) {
-                mState.getSource(ITYPE_CAPTION_BAR).setFrame(new Rect(mFrame.left, mFrame.top,
-                        mFrame.right, mFrame.top + mCaptionInsetsHeight));
+                mState.getSource(ITYPE_CAPTION_BAR).setFrame(mFrame.left, mFrame.top,
+                        mFrame.right, mFrame.top + mCaptionInsetsHeight);
             } else {
                 mState.removeSource(ITYPE_CAPTION_BAR);
             }
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 0ef5854..cc93adc 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1877,7 +1877,7 @@
             float x, float y, float pressure, float size, int metaState,
             float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
         return obtain(downTime, eventTime, action, x, y, pressure, size, metaState,
-                xPrecision, yPrecision, deviceId, edgeFlags, InputDevice.SOURCE_UNKNOWN,
+                xPrecision, yPrecision, deviceId, edgeFlags, InputDevice.SOURCE_CLASS_POINTER,
                 DEFAULT_DISPLAY);
     }
 
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 64f5668..f3c65ea 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -64,6 +64,7 @@
 import android.view.Surface.OutOfResourcesException;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
 import com.android.internal.util.VirtualRefBasePtr;
 
 import dalvik.system.CloseGuard;
@@ -2961,6 +2962,8 @@
         @NonNull
         public Transaction setScale(@NonNull SurfaceControl sc, float scaleX, float scaleY) {
             checkPreconditions(sc);
+            Preconditions.checkArgument(scaleX >= 0, "Negative value passed in for scaleX");
+            Preconditions.checkArgument(scaleY >= 0, "Negative value passed in for scaleY");
             nativeSetScale(mNativeObject, sc.mNativeObject, scaleX, scaleY);
             return this;
         }
@@ -3205,6 +3208,7 @@
         public @NonNull Transaction setCrop(@NonNull SurfaceControl sc, @Nullable Rect crop) {
             checkPreconditions(sc);
             if (crop != null) {
+                Preconditions.checkArgument(crop.isValid(), "Crop isn't valid.");
                 nativeSetWindowCrop(mNativeObject, sc.mNativeObject,
                         crop.left, crop.top, crop.right, crop.bottom);
             } else {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c222991..1b8dc70 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12016,7 +12016,6 @@
 
     /**
      * Return the handwriting areas set on this view, in its local coordinates.
-     * Notice: the caller of this method should not modify the Rect returned.
      * @see #setHandwritingArea(Rect)
      *
      * @hide
@@ -12025,7 +12024,7 @@
     public Rect getHandwritingArea() {
         final ListenerInfo info = mListenerInfo;
         if (info != null) {
-            return info.mHandwritingArea;
+            return new Rect(info.mHandwritingArea);
         }
         return null;
     }
@@ -15617,7 +15616,7 @@
      * @param event the KeyEvent object that defines the button action
      */
     public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (event.hasNoModifiers() && KeyEvent.isConfirmKey(keyCode)) {
+        if (KeyEvent.isConfirmKey(keyCode) && event.hasNoModifiers()) {
             if ((mViewFlags & ENABLED_MASK) == DISABLED) {
                 return true;
             }
@@ -15674,7 +15673,7 @@
      * @param event   The KeyEvent object that defines the button action.
      */
     public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (event.hasNoModifiers() && KeyEvent.isConfirmKey(keyCode)) {
+        if (KeyEvent.isConfirmKey(keyCode) && event.hasNoModifiers()) {
             if ((mViewFlags & ENABLED_MASK) == DISABLED) {
                 return true;
             }
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 5775944..ebc409e 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -1104,6 +1104,7 @@
      *         clear, or -1 if Views should not set themselves as preferred to keep clear.
      * @hide
      */
+    @TestApi
     public int getPreferKeepClearForFocusDelay() {
         return mPreferKeepClearForFocusDelay;
     }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bde761e..cdbf8b4 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -277,6 +277,12 @@
     private static final boolean ENABLE_INPUT_LATENCY_TRACKING = true;
 
     /**
+     * Whether the caption is drawn by the shell.
+     * @hide
+     */
+    public static final boolean CAPTION_ON_SHELL = false;
+
+    /**
      * Set this system property to true to force the view hierarchy to render
      * at 60 Hz. This can be used to measure the potential framerate.
      */
@@ -546,7 +552,6 @@
 
     private final Rect mVisRect = new Rect(); // used to retrieve visible rect of focused view.
     private final Rect mTempRect = new Rect();
-    private final Rect mTempRect2 = new Rect();
 
     private final WindowLayout mWindowLayout = new WindowLayout();
 
@@ -824,6 +829,24 @@
 
     private int mLastTransformHint = Integer.MIN_VALUE;
 
+    /**
+     * A temporary object used so relayoutWindow can return the latest SyncSeqId
+     * system. The SyncSeqId system was designed to work without synchronous relayout
+     * window, and actually synchronous relayout window presents a problem.  We could have
+     * a sequence like this:
+     *    1. We send MSG_RESIZED to the client with a new syncSeqId to begin a new sync
+     *    2. Due to scheduling the client executes performTraversals before calling MSG_RESIZED
+     *    3. Coincidentally for some random reason it also calls relayout
+     *    4. It observes the new state from relayout, and so the next frame will contain the state
+     * However it hasn't received the seqId yet, and so under the designed operation of
+     * seqId flowing through MSG_RESIZED, the next frame wouldn't be synced. Since it
+     * contains our target sync state, we need to sync it! This problem won't come up once
+     * we get rid of synchronous relayout, until then, we use this bundle to channel the
+     * integer back over relayout.
+     */
+    private Bundle mRelayoutBundle = new Bundle();
+    private int mSyncSeqId;
+
     private String mTag = TAG;
 
     public ViewRootImpl(Context context, Display display) {
@@ -867,6 +890,7 @@
         mDensity = context.getResources().getDisplayMetrics().densityDpi;
         mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
         mFallbackEventHandler = new PhoneFallbackEventHandler(context);
+        // TODO(b/222696368): remove getSfInstance usage and use vsyncId for transactions
         mChoreographer = useSfChoreographer
                 ? Choreographer.getSfInstance() : Choreographer.getInstance();
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
@@ -1198,8 +1222,7 @@
                         displayCutoutSafe, winConfig.getBounds(), winConfig.getWindowingMode(),
                         UNSPECIFIED_LENGTH, UNSPECIFIED_LENGTH,
                         mInsetsController.getRequestedVisibilities(),
-                        getAttachedWindowFrame(), 1f /* compactScale */,
-                        mTmpFrames.displayFrame, mTempRect2, mTmpFrames.frame);
+                        getAttachedWindowFrame(), 1f /* compactScale */, mTmpFrames);
                 setFrame(mTmpFrames.frame);
                 registerBackCallbackOnWindow();
                 if (!WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) {
@@ -1704,6 +1727,7 @@
         mPendingBackDropFrame.set(backdropFrame);
         mForceNextWindowRelayout = forceNextWindowRelayout;
         mPendingAlwaysConsumeSystemBars = args.argi2 != 0;
+        mSyncSeqId = args.argi4;
 
         if (msg == MSG_RESIZED_REPORT) {
             reportNextDraw();
@@ -1771,6 +1795,7 @@
         updateInternalDisplay(displayId, mView.getResources());
         mImeFocusController.onMovedToDisplay();
         mAttachInfo.mDisplayState = mDisplay.getState();
+        mDisplayInstallOrientation = mDisplay.getInstallOrientation();
         // Internal state updated, now notify the view hierarchy.
         mView.dispatchMovedToDisplay(mDisplay, config);
     }
@@ -2561,6 +2586,9 @@
     }
 
     private boolean updateCaptionInsets() {
+        if (CAPTION_ON_SHELL) {
+            return false;
+        }
         if (!(mView instanceof DecorView)) return false;
         final int captionInsetsHeight = ((DecorView) mView).getCaptionInsetsHeight();
         final Rect captionFrame = new Rect();
@@ -3439,6 +3467,12 @@
                     mReportNextDraw = false;
                     pendingDrawFinished();
                 }
+
+                // Make sure the consumer is not waiting if the view root was just made invisible.
+                if (mBLASTDrawConsumer != null) {
+                    mBLASTDrawConsumer.accept(null);
+                    mBLASTDrawConsumer = null;
+                }
             }
         }
 
@@ -4111,7 +4145,7 @@
         mDrawsNeededToReport = 0;
 
         try {
-            mWindowSession.finishDrawing(mWindow, mSurfaceChangedTransaction);
+            mWindowSession.finishDrawing(mWindow, mSurfaceChangedTransaction, Integer.MAX_VALUE);
         } catch (RemoteException e) {
             Log.e(mTag, "Unable to report draw finished", e);
             mSurfaceChangedTransaction.apply();
@@ -8054,7 +8088,7 @@
                 requestedWidth, requestedHeight, viewVisibility,
                 insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
                 mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
-                mTempControls);
+                mTempControls, mRelayoutBundle);
 
         final int transformHint = SurfaceControl.rotationToBufferTransform(
                 (mDisplayInstallOrientation + mDisplay.getRotation()) % 4);
@@ -8480,7 +8514,7 @@
                             if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
                                     & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
                                 mWindowSession.finishDrawing(
-                                        mWindow, null /* postDrawTransaction */);
+                                    mWindow, null /* postDrawTransaction */, Integer.MAX_VALUE);
                             }
                         } catch (RemoteException e) {
                         }
@@ -8554,7 +8588,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private void dispatchResized(ClientWindowFrames frames, boolean reportDraw,
             MergedConfiguration mergedConfiguration, boolean forceLayout,
-            boolean alwaysConsumeSystemBars, int displayId) {
+                                 boolean alwaysConsumeSystemBars, int displayId, int seqId) {
         final Rect frame = frames.frame;
         final Rect backDropFrame = frames.backdropFrame;
         if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString()
@@ -8585,6 +8619,7 @@
         args.argi1 = forceLayout ? 1 : 0;
         args.argi2 = alwaysConsumeSystemBars ? 1 : 0;
         args.argi3 = displayId;
+        args.argi4 = seqId;
         msg.obj = args;
         mHandler.sendMessage(msg);
     }
@@ -9969,11 +10004,11 @@
         @Override
         public void resized(ClientWindowFrames frames, boolean reportDraw,
                 MergedConfiguration mergedConfiguration, boolean forceLayout,
-                boolean alwaysConsumeSystemBars, int displayId) {
+                boolean alwaysConsumeSystemBars, int displayId, int seqId) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchResized(frames, reportDraw, mergedConfiguration, forceLayout,
-                        alwaysConsumeSystemBars, displayId);
+                        alwaysConsumeSystemBars, displayId, seqId);
             }
         }
 
diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java
index ad9f21b..a3b1313 100644
--- a/core/java/android/view/WindowLayout.java
+++ b/core/java/android/view/WindowLayout.java
@@ -42,6 +42,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.Log;
+import android.window.ClientWindowFrames;
 
 /**
  * Computes window frames.
@@ -56,15 +57,17 @@
     private final Rect mTempDisplayCutoutSafeExceptMaybeBarsRect = new Rect();
     private final Rect mTempRect = new Rect();
 
-    public boolean computeFrames(WindowManager.LayoutParams attrs, InsetsState state,
+    public void computeFrames(WindowManager.LayoutParams attrs, InsetsState state,
             Rect displayCutoutSafe, Rect windowBounds, @WindowingMode int windowingMode,
             int requestedWidth, int requestedHeight, InsetsVisibilities requestedVisibilities,
-            Rect attachedWindowFrame, float compatScale, Rect outDisplayFrame, Rect outParentFrame,
-            Rect outFrame) {
+            Rect attachedWindowFrame, float compatScale, ClientWindowFrames outFrames) {
         final int type = attrs.type;
         final int fl = attrs.flags;
         final int pfl = attrs.privateFlags;
         final boolean layoutInScreen = (fl & FLAG_LAYOUT_IN_SCREEN) == FLAG_LAYOUT_IN_SCREEN;
+        final Rect outDisplayFrame = outFrames.displayFrame;
+        final Rect outParentFrame = outFrames.parentFrame;
+        final Rect outFrame = outFrames.frame;
 
         // Compute bounds restricted by insets
         final Insets insets = state.calculateInsets(windowBounds, attrs.getFitInsetsTypes(),
@@ -95,7 +98,7 @@
         final DisplayCutout cutout = state.getDisplayCutout();
         final Rect displayCutoutSafeExceptMaybeBars = mTempDisplayCutoutSafeExceptMaybeBarsRect;
         displayCutoutSafeExceptMaybeBars.set(displayCutoutSafe);
-        boolean clippedByDisplayCutout = false;
+        outFrames.isParentFrameClippedByDisplayCutout = false;
         if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS && !cutout.isEmpty()) {
             // Ensure that windows with a non-ALWAYS display cutout mode are laid out in
             // the cutout safe zone.
@@ -158,7 +161,7 @@
             if (!attachedInParent && !floatingInScreenWindow) {
                 mTempRect.set(outParentFrame);
                 outParentFrame.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
-                clippedByDisplayCutout = !mTempRect.equals(outParentFrame);
+                outFrames.isParentFrameClippedByDisplayCutout = !mTempRect.equals(outParentFrame);
             }
             outDisplayFrame.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
         }
@@ -287,9 +290,7 @@
         }
 
         if (DEBUG) Log.d(TAG, "computeWindowFrames " + attrs.getTitle()
-                + " outFrame=" + outFrame.toShortString()
-                + " outParentFrame=" + outParentFrame.toShortString()
-                + " outDisplayFrame=" + outDisplayFrame.toShortString()
+                + " outFrames=" + outFrames
                 + " windowBounds=" + windowBounds.toShortString()
                 + " attachedWindowFrame=" + (attachedWindowFrame != null
                         ? attachedWindowFrame.toShortString()
@@ -302,8 +303,6 @@
                 + " attrs=" + attrs
                 + " state=" + state
                 + " requestedVisibilities=" + requestedVisibilities);
-
-        return clippedByDisplayCutout;
     }
 
     public static void computeSurfaceSize(WindowManager.LayoutParams attrs, Rect maxBounds,
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index dbfae46..45169ef 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -106,7 +106,6 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.IInputConstants;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -3360,8 +3359,7 @@
          *
          * @hide
          */
-        public static final int INPUT_FEATURE_NO_INPUT_CHANNEL =
-                IInputConstants.InputFeature.NO_INPUT_CHANNEL;
+        public static final int INPUT_FEATURE_NO_INPUT_CHANNEL = 1 << 0;
 
         /**
          * When this window has focus, does not call user activity for all input events so
@@ -3374,58 +3372,43 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY =
-                IInputConstants.InputFeature.DISABLE_USER_ACTIVITY;
+        public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY = 1 << 1;
 
         /**
          * An input spy window. This window will receive all pointer events within its touchable
-         * area, but will will not stop events from being sent to other windows below it in z-order.
+         * area, but will not stop events from being sent to other windows below it in z-order.
          * An input event will be dispatched to all spy windows above the top non-spy window at the
          * event's coordinates.
-         * @hide
-         */
-        public static final int INPUT_FEATURE_SPY =
-                IInputConstants.InputFeature.SPY;
-
-        /**
-         * When used with the window flag {@link #FLAG_NOT_TOUCHABLE}, this window will continue
-         * to receive events from a stylus device within its touchable region. All other pointer
-         * events, such as from a mouse or touchscreen, will be dispatched to the windows behind it.
-         *
-         * This input feature has no effect when the window flag {@link #FLAG_NOT_TOUCHABLE} is
-         * not set.
-         *
-         * The window must be a trusted overlay to use this input feature.
-         *
-         * @see #FLAG_NOT_TOUCHABLE
          *
          * @hide
          */
-        public static final int INPUT_FEATURE_INTERCEPTS_STYLUS =
-                IInputConstants.InputFeature.INTERCEPTS_STYLUS;
+        @RequiresPermission(permission.MONITOR_INPUT)
+        public static final int INPUT_FEATURE_SPY = 1 << 2;
 
         /**
          * An internal annotation for flags that can be specified to {@link #inputFeatures}.
          *
+         * NOTE: These are not the same as {@link android.os.InputConfig} flags.
+         *
          * @hide
          */
         @Retention(RetentionPolicy.SOURCE)
-        @IntDef(flag = true, prefix = { "INPUT_FEATURE_" }, value = {
-            INPUT_FEATURE_NO_INPUT_CHANNEL,
-            INPUT_FEATURE_DISABLE_USER_ACTIVITY,
-            INPUT_FEATURE_SPY,
-            INPUT_FEATURE_INTERCEPTS_STYLUS,
+        @IntDef(flag = true, prefix = {"INPUT_FEATURE_"}, value = {
+                INPUT_FEATURE_NO_INPUT_CHANNEL,
+                INPUT_FEATURE_DISABLE_USER_ACTIVITY,
+                INPUT_FEATURE_SPY,
         })
-        public @interface InputFeatureFlags {}
+        public @interface InputFeatureFlags {
+        }
 
         /**
-         * Control special features of the input subsystem.
+         * Control a set of features of the input subsystem that are exposed to the app process.
          *
-         * @see #INPUT_FEATURE_NO_INPUT_CHANNEL
-         * @see #INPUT_FEATURE_DISABLE_USER_ACTIVITY
-         * @see #INPUT_FEATURE_SPY
-         * @see #INPUT_FEATURE_INTERCEPTS_STYLUS
+         * WARNING: Do NOT use {@link android.os.InputConfig} flags! This must be set to flag values
+         * included in {@link InputFeatureFlags}.
+         *
          * @hide
+         * @see InputFeatureFlags
          */
         @InputFeatureFlags
         @UnsupportedAppUsage
@@ -4845,10 +4828,6 @@
                 inputFeatures &= ~INPUT_FEATURE_SPY;
                 features.add("INPUT_FEATURE_SPY");
             }
-            if ((inputFeatures & INPUT_FEATURE_INTERCEPTS_STYLUS) != 0) {
-                inputFeatures &= ~INPUT_FEATURE_INTERCEPTS_STYLUS;
-                features.add("INPUT_FEATURE_INTERCEPTS_STYLUS");
-            }
             if (inputFeatures != 0) {
                 features.add(Integer.toHexString(inputFeatures));
             }
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index a270c92..ad151df 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -22,6 +22,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
@@ -217,9 +218,13 @@
             throw new IllegalArgumentException(
                     "Invalid window token (never added or removed already)");
         }
+        removeSurface(state.mSurfaceControl);
+    }
 
+    /** Separate from {@link #remove} so that subclasses can put removal on a sync transaction. */
+    protected void removeSurface(SurfaceControl sc) {
         try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) {
-            t.remove(state.mSurfaceControl).apply();
+            t.remove(sc).apply();
         }
     }
 
@@ -277,7 +282,7 @@
             int requestedWidth, int requestedHeight, int viewFlags, int flags,
             ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
             SurfaceControl outSurfaceControl, InsetsState outInsetsState,
-            InsetsSourceControl[] outActiveControls) {
+            InsetsSourceControl[] outActiveControls, Bundle outSyncSeqIdBundle) {
         final State state;
         synchronized (this) {
             state = mStateForWindow.get(window.asBinder());
@@ -354,7 +359,7 @@
 
     @Override
     public void finishDrawing(android.view.IWindow window,
-            android.view.SurfaceControl.Transaction postDrawTransaction) {
+            android.view.SurfaceControl.Transaction postDrawTransaction, int seqId) {
         synchronized (this) {
             final ResizeCompleteCallback c =
                 mResizeCompletionForWindow.get(window.asBinder());
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index aeef76c..0008aa6 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -4487,8 +4487,8 @@
             case R.id.accessibilityActionDragDrop:
                 return "ACTION_DROP";
             default: {
-                if (action == R.id.accessibilityActionShowSuggestions) {
-                    return "ACTION_SHOW_SUGGESTIONS";
+                if (action == R.id.accessibilityActionShowTextSuggestions) {
+                    return "ACTION_SHOW_TEXT_SUGGESTIONS";
                 }
                 return "ACTION_UNKNOWN";
             }
@@ -5189,34 +5189,10 @@
                 new AccessibilityAction(R.id.accessibilityActionDragCancel);
 
         /**
-         * Action to perform a left swipe.
-         */
-        @NonNull public static final AccessibilityAction ACTION_SWIPE_LEFT =
-                new AccessibilityAction(R.id.accessibilityActionSwipeLeft);
-
-        /**
-         * Action to perform a right swipe.
-         */
-        @NonNull public static final AccessibilityAction ACTION_SWIPE_RIGHT =
-            new AccessibilityAction(R.id.accessibilityActionSwipeRight);
-
-        /**
-         * Action to perform an up swipe.
-         */
-        @NonNull public static final AccessibilityAction ACTION_SWIPE_UP =
-            new AccessibilityAction(R.id.accessibilityActionSwipeUp);
-
-        /**
-         * Action to perform a down swipe.
-         */
-        @NonNull public static final AccessibilityAction ACTION_SWIPE_DOWN =
-            new AccessibilityAction(R.id.accessibilityActionSwipeDown);
-
-        /**
          * Action to show suggestions for editable text.
          */
-        @NonNull public static final AccessibilityAction ACTION_SHOW_SUGGESTIONS =
-                new AccessibilityAction(R.id.accessibilityActionShowSuggestions);
+        @NonNull public static final AccessibilityAction ACTION_SHOW_TEXT_SUGGESTIONS =
+                new AccessibilityAction(R.id.accessibilityActionShowTextSuggestions);
 
         private final int mActionId;
         private final CharSequence mLabel;
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index a8cc114..3c5007b 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -3121,17 +3121,19 @@
     }
 
     /**
-     * If autofill suggestions for a dialog-style UI are available for {@code view}, shows a dialog
-     * allowing the user to select a suggestion and returns {@code true}.
+     * If autofill suggestions for a
+     * <a href="{@docRoot}reference/android/service/autofill/Dataset.html#FillDialogUI">
+     * dialog-style UI</a> are available for {@code view}, shows a dialog allowing the user to
+     * select a suggestion and returns {@code true}.
      * <p>
      * The dialog may not be available if the autofill service does not support it, or if the
      * autofill request has not returned a response yet.
      * <p>
-     * It is recommended to call this method the first time a user focuses on an autofill-able form,
-     * and to avoid showing the input method if the dialog is shown. If this method returns
-     * {@code false}, you should then instead show the input method (assuming that is how the
-     * view normally handles the focus event). If the user re-focuses on the view, you should not
-     * call this method again so as to not disrupt usage of the input method.
+     * It is recommended apps to call this method the first time a user focuses on
+     * an autofill-able form, and to avoid showing the input method if the dialog is shown. If
+     * this method returns {@code false}, you should then instead show the input method (assuming
+     * that is how the view normally handles the focus event). If the user re-focuses on the view,
+     * you should not call this method again so as to not disrupt usage of the input method.
      *
      * @param view the view for which to show autofill suggestions. This is typically a view
      *             receiving a focus event. The autofill suggestions shown will include content for
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index 69ad739..fd336a2 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -31,6 +31,7 @@
 import android.view.View;
 
 import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
 import com.android.internal.view.IInlineSuggestionsRequestCallback;
 import com.android.internal.view.InlineSuggestionsRequestInfo;
 
@@ -105,14 +106,13 @@
      *                             current IME.
      * @param configChanges {@link InputMethodInfo#getConfigChanges()} declared by IME.
      * @param stylusHwSupported {@link InputMethodInfo#supportsStylusHandwriting()} declared by IME.
-     * @param shouldShowImeSwitcherWhenImeIsShown {@code true} If the IME switcher is expected to be
-     *                                            shown while the IME is shown.
+     * @param navButtonFlags The initial state of {@link InputMethodNavButtonFlags}.
      * @hide
      */
     @MainThread
     default void initializeInternal(IBinder token,
             IInputMethodPrivilegedOperations privilegedOperations, int configChanges,
-            boolean stylusHwSupported, boolean shouldShowImeSwitcherWhenImeIsShown) {
+            boolean stylusHwSupported, @InputMethodNavButtonFlags int navButtonFlags) {
         attachToken(token);
     }
 
@@ -231,8 +231,7 @@
      *                        the next {@link #startInput(InputConnection, EditorInfo, IBinder)} as
      *                        long as your implementation of {@link InputMethod} relies on such
      *                        IPCs
-     * @param shouldShowImeSwitcherWhenImeIsShown {@code true} If the IME switcher is expected to be
-     *                                            shown while the IME is shown.
+     * @param navButtonFlags {@link InputMethodNavButtonFlags} in the initial state of this session.
      * @see #startInput(InputConnection, EditorInfo)
      * @see #restartInput(InputConnection, EditorInfo)
      * @see EditorInfo
@@ -241,7 +240,7 @@
     @MainThread
     default void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
             @NonNull EditorInfo editorInfo, boolean restarting,
-            @NonNull IBinder startInputToken, boolean shouldShowImeSwitcherWhenImeIsShown) {
+            @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags) {
         if (restarting) {
             restartInput(inputConnection, editorInfo);
         } else {
@@ -250,15 +249,13 @@
     }
 
     /**
-     * Notifies that whether the IME should show the IME switcher or not is being changed.
+     * Notifies that {@link InputMethodNavButtonFlags} have been updated.
      *
-     * @param shouldShowImeSwitcherWhenImeIsShown {@code true} If the IME switcher is expected to be
-     *                                            shown while the IME is shown.
+     * @param navButtonFlags The new {@link InputMethodNavButtonFlags}.
      * @hide
      */
     @MainThread
-    default void onShouldShowImeSwitcherWhenImeIsShownChanged(
-            boolean shouldShowImeSwitcherWhenImeIsShown) {
+    default void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
     }
 
     /**
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index f7a6fb9..da20e33 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1919,10 +1919,17 @@
         if (fallbackImm != null) {
             fallbackImm.startStylusHandwriting(view);
         }
+        Objects.requireNonNull(view);
+
+        if (Settings.Global.getInt(view.getContext().getContentResolver(),
+                Settings.Global.STYLUS_HANDWRITING_ENABLED, 0) == 0) {
+            Log.d(TAG, "Ignoring startStylusHandwriting(view) as stylus handwriting is disabled");
+            return;
+        }
 
         checkFocus();
         synchronized (mH) {
-            if (view == null || !hasServedByInputMethodLocked(view)) {
+            if (!hasServedByInputMethodLocked(view)) {
                 Log.w(TAG,
                         "Ignoring startStylusHandwriting() as view=" + view + " is not served.");
                 return;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 3a7a544..7f8a68d 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -4595,7 +4595,7 @@
 
             if (includeEditorBounds) {
                 final RectF bounds = new RectF();
-                mTextView.getBoundsOnScreen(bounds, false /* clipToParent */);
+                bounds.set(0 /* left */, 0 /* top */, mTextView.getWidth(), mTextView.getHeight());
                 EditorBoundsInfo.Builder boundsBuilder = new EditorBoundsInfo.Builder();
                 //TODO(b/210039666): add Handwriting bounds once they're available.
                 builder.setEditorBoundsInfo(
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index b00a382..fbad38f 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -6681,7 +6681,13 @@
                 opts = ActivityOptions.makeBasic();
                 opts.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             }
-            opts.setLaunchDisplayId(view.getDisplay().getDisplayId());
+            if (view.getDisplay() != null) {
+                opts.setLaunchDisplayId(view.getDisplay().getDisplayId());
+            } else {
+                // TODO(b/218409359): Remove once bug is fixed.
+                Log.w(LOG_TAG, "getLaunchOptions: view.getDisplay() is null!",
+                        new Exception());
+            }
             return Pair.create(intent, opts);
         }
     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index c207af5..3c8fcb9 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -788,7 +788,8 @@
     private Layout mLayout;
     private boolean mLocalesChanged = false;
     private int mTextSizeUnit = -1;
-    private LineBreakConfig mLineBreakConfig = new LineBreakConfig();
+    private int mLineBreakStyle = DEFAULT_LINE_BREAK_STYLE;
+    private int mLineBreakWordStyle = DEFAULT_LINE_BREAK_WORD_STYLE;
 
     // This is used to reflect the current user preference for changing font weight and making text
     // more bold.
@@ -1457,13 +1458,12 @@
                     break;
 
                 case com.android.internal.R.styleable.TextView_lineBreakStyle:
-                    mLineBreakConfig.setLineBreakStyle(
-                            a.getInt(attr, LineBreakConfig.LINE_BREAK_STYLE_NONE));
+                    mLineBreakStyle = a.getInt(attr, LineBreakConfig.LINE_BREAK_STYLE_NONE);
                     break;
 
                 case com.android.internal.R.styleable.TextView_lineBreakWordStyle:
-                    mLineBreakConfig.setLineBreakWordStyle(
-                            a.getInt(attr, LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE));
+                    mLineBreakWordStyle = a.getInt(attr,
+                            LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE);
                     break;
 
                 case com.android.internal.R.styleable.TextView_autoSizeTextType:
@@ -4301,13 +4301,12 @@
             @LineBreakConfig.LineBreakStyle int lineBreakStyle,
             @LineBreakConfig.LineBreakWordStyle int lineBreakWordStyle) {
         boolean updated = false;
-        if (isLineBreakStyleSpecified && mLineBreakConfig.getLineBreakStyle() != lineBreakStyle) {
-            mLineBreakConfig.setLineBreakStyle(lineBreakStyle);
+        if (isLineBreakStyleSpecified && mLineBreakStyle != lineBreakStyle) {
+            mLineBreakStyle = lineBreakStyle;
             updated = true;
         }
-        if (isLineBreakWordStyleSpecified
-                && mLineBreakConfig.getLineBreakWordStyle() != lineBreakWordStyle) {
-            mLineBreakConfig.setLineBreakWordStyle(lineBreakWordStyle);
+        if (isLineBreakWordStyleSpecified && mLineBreakWordStyle != lineBreakWordStyle) {
+            mLineBreakWordStyle = lineBreakWordStyle;
             updated = true;
         }
         if (updated && mLayout != null) {
@@ -4871,50 +4870,72 @@
     }
 
     /**
-     * Sets line break configuration indicates which strategy needs to be used when calculating the
-     * text wrapping.
-     * <P>
-     * There are two types of line break rules that can be configured at the same time. One is
-     * line break style(lb) and the other is line break word style(lw). The line break style
-     * affects rule-based breaking. The line break word style affects dictionary-based breaking
-     * and provide phrase-based breaking opportunities. There are several types for the
-     * line break style:
+     * Set the line break style for text wrapping.
+     *
+     * The line break style to indicates the line break strategies can be used when
+     * calculating the text wrapping. The line break style affects rule-based breaking. It
+     * specifies the strictness of line-breaking rules.
+     * There are several types for the line break style:
      * {@link LineBreakConfig#LINE_BREAK_STYLE_LOOSE},
      * {@link LineBreakConfig#LINE_BREAK_STYLE_NORMAL} and
-     * {@link LineBreakConfig#LINE_BREAK_STYLE_STRICT}.
-     * The type for the line break word style is
-     * {@link LineBreakConfig#LINE_BREAK_WORD_STYLE_PHRASE}.
-     * The default values of the line break style and the line break word style are
-     * {@link LineBreakConfig#LINE_BREAK_STYLE_NONE} and
-     * {@link LineBreakConfig#LINE_BREAK_WORD_STYLE_NONE} respectively, indicating that no line
-     * breaking rules are specified.
-     * See <a href="https://drafts.csswg.org/css-text/#line-break-property">
+     * {@link LineBreakConfig#LINE_BREAK_STYLE_STRICT}. The default values of the line break style
+     * is {@link LineBreakConfig#LINE_BREAK_STYLE_NONE}, indicating no breaking rule is specified.
+     * See <a href="https://www.w3.org/TR/css-text-3/#line-break-property">
      *         the line-break property</a>
      *
-     * @param lineBreakConfig the line break config for text wrapping.
+     * @param lineBreakStyle the line break style for the text.
      */
-    public void setLineBreakConfig(@NonNull LineBreakConfig lineBreakConfig) {
-        Objects.requireNonNull(lineBreakConfig);
-        if (mLineBreakConfig.equals(lineBreakConfig)) {
-            return;
-        }
-        mLineBreakConfig.set(lineBreakConfig);
-        if (mLayout != null) {
-            nullLayouts();
-            requestLayout();
-            invalidate();
+    public void setLineBreakStyle(@LineBreakConfig.LineBreakStyle int lineBreakStyle) {
+        if (mLineBreakStyle != lineBreakStyle) {
+            mLineBreakStyle = lineBreakStyle;
+            if (mLayout != null) {
+                nullLayouts();
+                requestLayout();
+                invalidate();
+            }
         }
     }
 
     /**
-     * Get the current line break configuration for text wrapping.
+     * Set the line break word style for text wrapping.
      *
-     * @return the current line break configuration to be used for text wrapping.
+     * The line break word style affects dictionary-based breaking and provide phrase-based
+     * breaking opportunities. The type for the line break word style is
+     * {@link LineBreakConfig#LINE_BREAK_WORD_STYLE_PHRASE}. The default values of the line break
+     * word style is {@link LineBreakConfig#LINE_BREAK_WORD_STYLE_NONE}, indicating no breaking rule
+     * is specified.
+     * See <a href="https://www.w3.org/TR/css-text-3/#word-break-property">
+     *         the word-break property</a>
+     *
+     * @param lineBreakWordStyle the line break word style for the tet
      */
-    public @NonNull LineBreakConfig getLineBreakConfig() {
-        LineBreakConfig lbConfig = new LineBreakConfig();
-        lbConfig.set(mLineBreakConfig);
-        return lbConfig;
+    public void setLineBreakWordStyle(@LineBreakConfig.LineBreakWordStyle int lineBreakWordStyle) {
+        if (mLineBreakWordStyle != lineBreakWordStyle) {
+            mLineBreakWordStyle = lineBreakWordStyle;
+            if (mLayout != null) {
+                nullLayouts();
+                requestLayout();
+                invalidate();
+            }
+        }
+    }
+
+    /**
+     * Get the current line break style for text wrapping.
+     *
+     * @return the current line break style to be used for text wrapping.
+     */
+    public @LineBreakConfig.LineBreakStyle int getLineBreakStyle() {
+        return mLineBreakStyle;
+    }
+
+    /**
+     * Get the current line word break style for text wrapping.
+     *
+     * @return the current line break word style to be used for text wrapping.
+     */
+    public @LineBreakConfig.LineBreakWordStyle int getLineBreakWordStyle() {
+        return mLineBreakWordStyle;
     }
 
     /**
@@ -4924,7 +4945,8 @@
      * @see PrecomputedText
      */
     public @NonNull PrecomputedText.Params getTextMetricsParams() {
-        return new PrecomputedText.Params(new TextPaint(mTextPaint), mLineBreakConfig,
+        return new PrecomputedText.Params(new TextPaint(mTextPaint),
+                LineBreakConfig.getLineBreakConfig(mLineBreakStyle, mLineBreakWordStyle),
                 getTextDirectionHeuristic(),
                 mBreakStrategy, mHyphenationFrequency);
     }
@@ -4941,13 +4963,9 @@
         mTextDir = params.getTextDirection();
         mBreakStrategy = params.getBreakStrategy();
         mHyphenationFrequency = params.getHyphenationFrequency();
-        if (params.getLineBreakConfig() != null) {
-            mLineBreakConfig.set(params.getLineBreakConfig());
-        } else {
-            // Set default value if the line break config in the PrecomputedText.Params is null.
-            mLineBreakConfig.setLineBreakStyle(DEFAULT_LINE_BREAK_STYLE);
-            mLineBreakConfig.setLineBreakWordStyle(DEFAULT_LINE_BREAK_WORD_STYLE);
-        }
+        LineBreakConfig lineBreakConfig = params.getLineBreakConfig();
+        mLineBreakStyle = lineBreakConfig.getLineBreakStyle();
+        mLineBreakWordStyle = lineBreakConfig.getLineBreakWordStyle();
         if (mLayout != null) {
             nullLayouts();
             requestLayout();
@@ -6486,7 +6504,8 @@
             }
             final @PrecomputedText.Params.CheckResultUsableResult int checkResult =
                     precomputed.getParams().checkResultUsable(getPaint(), mTextDir, mBreakStrategy,
-                            mHyphenationFrequency, mLineBreakConfig);
+                            mHyphenationFrequency, LineBreakConfig.getLineBreakConfig(
+                                    mLineBreakStyle, mLineBreakWordStyle));
             switch (checkResult) {
                 case PrecomputedText.Params.UNUSABLE:
                     throw new IllegalArgumentException(
@@ -9383,7 +9402,8 @@
                         .setHyphenationFrequency(mHyphenationFrequency)
                         .setJustificationMode(mJustificationMode)
                         .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE)
-                        .setLineBreakConfig(mLineBreakConfig);
+                        .setLineBreakConfig(LineBreakConfig.getLineBreakConfig(
+                                mLineBreakStyle, mLineBreakWordStyle));
                 if (shouldEllipsize) {
                     builder.setEllipsize(mEllipsize)
                             .setEllipsizedWidth(ellipsisWidth);
@@ -9498,7 +9518,8 @@
                     .setHyphenationFrequency(mHyphenationFrequency)
                     .setJustificationMode(mJustificationMode)
                     .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE)
-                    .setLineBreakConfig(mLineBreakConfig);
+                    .setLineBreakConfig(LineBreakConfig.getLineBreakConfig(
+                            mLineBreakStyle, mLineBreakWordStyle));
             if (shouldEllipsize) {
                 builder.setEllipsize(effectiveEllipsize)
                         .setEllipsizedWidth(ellipsisWidth);
@@ -9866,7 +9887,8 @@
                 .setJustificationMode(getJustificationMode())
                 .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE)
                 .setTextDirection(getTextDirectionHeuristic())
-                .setLineBreakConfig(mLineBreakConfig);
+                .setLineBreakConfig(LineBreakConfig.getLineBreakConfig(
+                        mLineBreakStyle, mLineBreakWordStyle));
 
         final StaticLayout layout = layoutBuilder.build();
 
@@ -12313,7 +12335,8 @@
                 info.addAction(AccessibilityNodeInfo.ACTION_CUT);
             }
             if (canReplace()) {
-                info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SHOW_SUGGESTIONS);
+                info.addAction(
+                        AccessibilityNodeInfo.AccessibilityAction.ACTION_SHOW_TEXT_SUGGESTIONS);
             }
             if (canShare()) {
                 info.addAction(new AccessibilityNodeInfo.AccessibilityAction(
@@ -12634,7 +12657,7 @@
             default: {
                 // New ids have static blocks to assign values, so they can't be used in a case
                 // block.
-                if (action == R.id.accessibilityActionShowSuggestions) {
+                if (action == R.id.accessibilityActionShowTextSuggestions) {
                     return isFocused() && canReplace() && onTextContextMenuItem(ID_REPLACE);
                 }
                 return super.performAccessibilityActionInternal(action, arguments);
diff --git a/core/java/android/window/ClientWindowFrames.java b/core/java/android/window/ClientWindowFrames.java
index acf9882..5b915cc 100644
--- a/core/java/android/window/ClientWindowFrames.java
+++ b/core/java/android/window/ClientWindowFrames.java
@@ -27,47 +27,55 @@
  */
 public class ClientWindowFrames implements Parcelable {
     /** The actual window bounds. */
-    public final @NonNull Rect frame;
+    public final @NonNull Rect frame = new Rect();
 
     /**
      * The container frame that is usually the same as display size. It may exclude the area of
      * insets if the window layout parameter has specified fit-insets-sides.
      */
-    public final @NonNull Rect displayFrame;
+    public final @NonNull Rect displayFrame = new Rect();
+
+    /**
+     * The frame to be referenced while applying gravity and MATCH_PARENT.
+     */
+    public final @NonNull Rect parentFrame = new Rect();
 
     /** The background area while the window is resizing. */
-    public final @NonNull Rect backdropFrame;
+    public final @NonNull Rect backdropFrame = new Rect();
+
+    public boolean isParentFrameClippedByDisplayCutout;
 
     public ClientWindowFrames() {
-        frame = new Rect();
-        displayFrame = new Rect();
-        backdropFrame = new Rect();
     }
 
     public ClientWindowFrames(ClientWindowFrames other) {
-        frame = new Rect(other.frame);
-        displayFrame = new Rect(other.displayFrame);
-        backdropFrame = new Rect(other.backdropFrame);
+        frame.set(other.frame);
+        displayFrame.set(other.displayFrame);
+        parentFrame.set(other.parentFrame);
+        backdropFrame.set(other.backdropFrame);
+        isParentFrameClippedByDisplayCutout = other.isParentFrameClippedByDisplayCutout;
     }
 
     private ClientWindowFrames(Parcel in) {
-        frame = Rect.CREATOR.createFromParcel(in);
-        displayFrame = Rect.CREATOR.createFromParcel(in);
-        backdropFrame = Rect.CREATOR.createFromParcel(in);
+        readFromParcel(in);
     }
 
     /** Needed for AIDL out parameters. */
     public void readFromParcel(Parcel in) {
         frame.readFromParcel(in);
         displayFrame.readFromParcel(in);
+        parentFrame.readFromParcel(in);
         backdropFrame.readFromParcel(in);
+        isParentFrameClippedByDisplayCutout = in.readBoolean();
     }
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         frame.writeToParcel(dest, flags);
         displayFrame.writeToParcel(dest, flags);
+        parentFrame.writeToParcel(dest, flags);
         backdropFrame.writeToParcel(dest, flags);
+        dest.writeBoolean(isParentFrameClippedByDisplayCutout);
     }
 
     @Override
@@ -75,7 +83,9 @@
         final StringBuilder sb = new StringBuilder(32);
         return "ClientWindowFrames{frame=" + frame.toShortString(sb)
                 + " display=" + displayFrame.toShortString(sb)
-                + " backdrop=" + backdropFrame.toShortString(sb) + "}";
+                + " parentFrame=" + parentFrame.toShortString(sb)
+                + " backdrop=" + backdropFrame.toShortString(sb)
+                + " parentClippedByDisplayCutout=" + isParentFrameClippedByDisplayCutout + "}";
     }
 
     @Override
diff --git a/core/java/android/window/DisplayWindowPolicyController.java b/core/java/android/window/DisplayWindowPolicyController.java
index 3359a41..1270d87 100644
--- a/core/java/android/window/DisplayWindowPolicyController.java
+++ b/core/java/android/window/DisplayWindowPolicyController.java
@@ -17,12 +17,14 @@
 package android.window;
 
 import android.annotation.NonNull;
+import android.app.WindowConfiguration;
 import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
 import android.util.ArraySet;
 
 import java.io.PrintWriter;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Abstract class to control the policies of the windows that can be displayed on the virtual
@@ -46,6 +48,22 @@
     private int mSystemWindowFlags;
 
     /**
+     * The set of windowing mode that are supported in this display.
+     * @see android.app.WindowConfiguration.WindowingMode
+     */
+    private final Set<Integer> mSupportedWindowingModes = new ArraySet<>();
+
+    /**
+     * A controller to control the policies of the windows that can be displayed on the virtual
+     * display.
+     */
+    public DisplayWindowPolicyController() {
+        synchronized (mSupportedWindowingModes) {
+            mSupportedWindowingModes.add(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
+        }
+    }
+
+    /**
      * Returns {@code true} if the given window flags contain the flags that we're interested in.
      */
     public final boolean isInterestedWindowFlags(int windowFlags, int systemWindowFlags) {
@@ -62,9 +80,34 @@
     }
 
     /**
-     * Returns {@code true} if the given activities can be displayed on this virtual display.
+     * Returns {@code true} if the given windowing mode is supported in this display.
      */
-    public abstract boolean canContainActivities(@NonNull List<ActivityInfo> activities);
+    public final boolean isWindowingModeSupported(
+            @WindowConfiguration.WindowingMode int windowingMode) {
+        synchronized (mSupportedWindowingModes) {
+            return mSupportedWindowingModes.contains(windowingMode);
+        }
+    }
+
+    /**
+     * Sets the windowing modes are supported in this display.
+     *
+     * @param supportedWindowingModes The set of
+     * {@link android.app.WindowConfiguration.WindowingMode}.
+     */
+    public final void setSupportedWindowingModes(Set<Integer> supportedWindowingModes) {
+        synchronized (mSupportedWindowingModes) {
+            mSupportedWindowingModes.clear();
+            mSupportedWindowingModes.addAll(supportedWindowingModes);
+        }
+    }
+
+    /**
+     * Returns {@code true} if the given activities can be displayed on this virtual display and
+     * the windowing mode is supported.
+     */
+    public abstract boolean canContainActivities(@NonNull List<ActivityInfo> activities,
+            @WindowConfiguration.WindowingMode int windowingMode);
 
     /**
      * Called when an Activity window is layouted with the new changes where contains the
diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl
index 022d05d..172456e4 100644
--- a/core/java/android/window/ITaskOrganizerController.aidl
+++ b/core/java/android/window/ITaskOrganizerController.aidl
@@ -52,7 +52,7 @@
     /** Gets all root tasks on a display (ordered from top-to-bottom) */
     List<ActivityManager.RunningTaskInfo> getRootTasks(int displayId, in int[] activityTypes);
 
-    /** Get the root task which contains the current ime target */
+    /** Get the {@link WindowContainerToken} of the task which contains the current ime target */
     WindowContainerToken getImeTarget(int display);
 
     /**
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index 3ec18db..8d88f80 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -199,7 +199,7 @@
         }
     }
 
-    /** Get the root task which contains the current ime target */
+    /** Get the {@link WindowContainerToken} of the task which contains the current ime target */
     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
     @Nullable
     public WindowContainerToken getImeTarget(int display) {
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 5f82fb0..d046cef 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -28,6 +28,7 @@
 import android.view.IWindow;
 import android.view.IWindowSession;
 
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.TreeMap;
@@ -52,7 +53,7 @@
     private static final String TAG = "WindowOnBackDispatcher";
     private static final String BACK_PREDICTABILITY_PROP = "persist.debug.back_predictability";
     private static final boolean IS_BACK_PREDICTABILITY_ENABLED = SystemProperties
-            .getInt(BACK_PREDICTABILITY_PROP, 0) > 0;
+            .getInt(BACK_PREDICTABILITY_PROP, 1) > 0;
 
     /** Convenience hashmap to quickly decide if a callback has been added. */
     private final HashMap<OnBackInvokedCallback, Integer> mAllCallbacks = new HashMap<>();
@@ -185,35 +186,58 @@
     }
 
     private static class OnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub {
-        private final OnBackInvokedCallback mCallback;
+        private final WeakReference<OnBackInvokedCallback> mCallback;
 
         OnBackInvokedCallbackWrapper(@NonNull OnBackInvokedCallback callback) {
-            mCallback = callback;
-        }
-
-        @NonNull
-        public OnBackInvokedCallback getCallback() {
-            return mCallback;
+            mCallback = new WeakReference<>(callback);
         }
 
         @Override
         public void onBackStarted() {
-            Handler.getMain().post(() -> mCallback.onBackStarted());
+            Handler.getMain().post(() -> {
+                final OnBackInvokedCallback callback = mCallback.get();
+                if (callback == null) {
+                    return;
+                }
+
+                callback.onBackStarted();
+            });
         }
 
         @Override
         public void onBackProgressed(BackEvent backEvent) {
-            Handler.getMain().post(() -> mCallback.onBackProgressed(backEvent));
+            Handler.getMain().post(() -> {
+                final OnBackInvokedCallback callback = mCallback.get();
+                if (callback == null) {
+                    return;
+                }
+
+                callback.onBackProgressed(backEvent);
+            });
         }
 
         @Override
         public void onBackCancelled() {
-            Handler.getMain().post(() -> mCallback.onBackCancelled());
+            Handler.getMain().post(() -> {
+                final OnBackInvokedCallback callback = mCallback.get();
+                if (callback == null) {
+                    return;
+                }
+
+                callback.onBackCancelled();
+            });
         }
 
         @Override
         public void onBackInvoked() throws RemoteException {
-            Handler.getMain().post(() -> mCallback.onBackInvoked());
+            Handler.getMain().post(() -> {
+                final OnBackInvokedCallback callback = mCallback.get();
+                if (callback == null) {
+                    return;
+                }
+
+                callback.onBackInvoked();
+            });
         }
     }
 
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index e336e96..fd5eac8 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1603,6 +1603,11 @@
         List<DisplayResolveInfo> otherProfileList =
                 mMultiProfilePagerAdapter.getInactiveListAdapter().mDisplayList;
 
+        if (sameProfileList.isEmpty()) {
+            Log.d(TAG, "No targets in the current profile");
+            return false;
+        }
+
         if (otherProfileList.size() != 1) {
             Log.d(TAG, "Found " + otherProfileList.size() + " resolvers in the other profile");
             return false;
diff --git a/core/java/com/android/internal/graphics/SfVsyncFrameCallbackProvider.java b/core/java/com/android/internal/graphics/SfVsyncFrameCallbackProvider.java
index 45555bf..dbbe4b9 100644
--- a/core/java/com/android/internal/graphics/SfVsyncFrameCallbackProvider.java
+++ b/core/java/com/android/internal/graphics/SfVsyncFrameCallbackProvider.java
@@ -24,6 +24,7 @@
  *
  * @hide
  */
+// TODO(b/222698397): remove getSfInstance/this class usage and use vsyncId for transactions
 public final class SfVsyncFrameCallbackProvider implements AnimationFrameCallbackProvider {
 
     private final Choreographer mChoreographer;
diff --git a/core/java/com/android/internal/infra/ServiceConnector.java b/core/java/com/android/internal/infra/ServiceConnector.java
index 9e07f97..cb16267 100644
--- a/core/java/com/android/internal/infra/ServiceConnector.java
+++ b/core/java/com/android/internal/infra/ServiceConnector.java
@@ -31,6 +31,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
+import android.util.Slog;
 
 import java.io.PrintWriter;
 import java.util.ArrayDeque;
@@ -562,10 +563,21 @@
         void unbindJobThread() {
             cancelTimeout();
             I service = mService;
+            // TODO(b/224695239): This is actually checking wasConnected. Rename and/or fix
+            // implementation based on what this should actually be checking. At least the first
+            // check for calling unbind is the correct behavior, though.
             boolean wasBound = service != null;
+            if (wasBound || mBinding) {
+                try {
+                    mContext.unbindService(mServiceConnection);
+                } catch (IllegalArgumentException e) {  // TODO(b/224697137): Fix the race condition
+                                                        // that requires catching this (crashes if
+                                                        // service isn't currently bound).
+                    Slog.e(LOG_TAG, "Failed to unbind: " + e);
+                }
+            }
             if (wasBound) {
                 dispatchOnServiceConnectionStatusChanged(service, false);
-                mContext.unbindService(mServiceConnection);
                 service.asBinder().unlinkToDeath(this, 0);
                 mService = null;
             }
diff --git a/core/java/com/android/internal/inputmethod/InputMethodNavButtonFlags.java b/core/java/com/android/internal/inputmethod/InputMethodNavButtonFlags.java
new file mode 100644
index 0000000..728a429
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/InputMethodNavButtonFlags.java
@@ -0,0 +1,49 @@
+/*
+ * 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.internal.inputmethod;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+
+/**
+ * A set of flags notified from {@link com.android.server.inputmethod.InputMethodManagerService} to
+ * {@link android.inputmethodservice.InputMethodService} regarding how
+ * {@link android.inputmethodservice.NavigationBarController} should behave.
+ *
+ * <p>These flags will take effect when and only when
+ * {@link android.inputmethodservice.InputMethodService#canImeRenderGesturalNavButtons} returns
+ * {@code true}.</p>
+ */
+@Retention(SOURCE)
+@IntDef(flag = true, value = {
+        InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR,
+        InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN,
+})
+public @interface InputMethodNavButtonFlags {
+    /**
+     * When set, the IME process needs to render and handle the navigation bar buttons such as the
+     * back button and the IME switcher button.
+     */
+    int IME_DRAWS_IME_NAV_BAR = 1;
+    /**
+     * When set, the IME switcher icon needs to be shown on the navigation bar.
+     */
+    int SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN = 2;
+}
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 3746bfd..5947e66 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -62,6 +62,10 @@
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLASHSCREEN_AVD;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLASHSCREEN_EXIT_ANIM;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_SCREEN_FOR_STATUS;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_NEXT_FLOW;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__UNFOLD_ANIM;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_SWITCH;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__WALLPAPER_TRANSITION;
@@ -176,6 +180,10 @@
     public static final int CUJ_ONE_HANDED_ENTER_TRANSITION = 42;
     public static final int CUJ_ONE_HANDED_EXIT_TRANSITION = 43;
     public static final int CUJ_UNFOLD_ANIM = 44;
+    public static final int CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS = 45;
+    public static final int CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS = 46;
+    public static final int CUJ_SUW_LOADING_TO_NEXT_FLOW = 47;
+    public static final int CUJ_SUW_LOADING_SCREEN_FOR_STATUS = 48;
 
     private static final int NO_STATSD_LOGGING = -1;
 
@@ -229,6 +237,10 @@
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_ENTER_TRANSITION,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_EXIT_TRANSITION,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__UNFOLD_ANIM,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_NEXT_FLOW,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_SCREEN_FOR_STATUS,
     };
 
     private static volatile InteractionJankMonitor sInstance;
@@ -294,6 +306,10 @@
             CUJ_ONE_HANDED_ENTER_TRANSITION,
             CUJ_ONE_HANDED_EXIT_TRANSITION,
             CUJ_UNFOLD_ANIM,
+            CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS,
+            CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS,
+            CUJ_SUW_LOADING_TO_NEXT_FLOW,
+            CUJ_SUW_LOADING_SCREEN_FOR_STATUS
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CujType {
@@ -701,6 +717,14 @@
                 return "ONE_HANDED_EXIT_TRANSITION";
             case CUJ_UNFOLD_ANIM:
                 return "UNFOLD_ANIM";
+            case CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS:
+                return "SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS";
+            case CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS:
+                return "SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS";
+            case CUJ_SUW_LOADING_TO_NEXT_FLOW:
+                return "SUW_LOADING_TO_NEXT_FLOW";
+            case CUJ_SUW_LOADING_SCREEN_FOR_STATUS:
+                return "SUW_LOADING_SCREEN_FOR_STATUS";
         }
         return "UNKNOWN";
     }
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index ec95baa..2784da0 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -106,6 +106,7 @@
     public boolean allowIPv6;
     public boolean isMetered = true;
     public boolean requiresInternetValidation = false;
+    public boolean excludeLocalRoutes = false;
     public Network[] underlyingNetworks;
     public ProxyInfo proxyInfo;
 
@@ -133,6 +134,7 @@
         allowIPv6 = other.allowIPv6;
         isMetered = other.isMetered;
         requiresInternetValidation = other.requiresInternetValidation;
+        excludeLocalRoutes = other.excludeLocalRoutes;
         underlyingNetworks = other.underlyingNetworks != null ? Arrays.copyOf(
                 other.underlyingNetworks, other.underlyingNetworks.length) : null;
         proxyInfo = other.proxyInfo;
@@ -192,6 +194,7 @@
         out.writeInt(allowIPv6 ? 1 : 0);
         out.writeInt(isMetered ? 1 : 0);
         out.writeInt(requiresInternetValidation ? 1 : 0);
+        out.writeInt(excludeLocalRoutes ? 1 : 0);
         out.writeTypedArray(underlyingNetworks, flags);
         out.writeParcelable(proxyInfo, flags);
     }
@@ -220,6 +223,7 @@
             config.allowIPv6 = in.readInt() != 0;
             config.isMetered = in.readInt() != 0;
             config.requiresInternetValidation = in.readInt() != 0;
+            config.excludeLocalRoutes = in.readInt() != 0;
             config.underlyingNetworks = in.createTypedArray(Network.CREATOR);
             config.proxyInfo = in.readParcelable(null, android.net.ProxyInfo.class);
             return config;
@@ -253,7 +257,8 @@
                 .append(", allowIPv4=").append(allowIPv4)
                 .append(", allowIPv6=").append(allowIPv6)
                 .append(", isMetered=").append(isMetered)
-                .append(", requiresInternetValidation").append(requiresInternetValidation)
+                .append(", requiresInternetValidation=").append(requiresInternetValidation)
+                .append(", excludeLocalRoutes=").append(excludeLocalRoutes)
                 .append(", underlyingNetworks=").append(Arrays.toString(underlyingNetworks))
                 .append(", proxyInfo=").append(proxyInfo)
                 .append("}")
diff --git a/core/java/com/android/internal/os/AudioPowerCalculator.java b/core/java/com/android/internal/os/AudioPowerCalculator.java
index f9310b0..ebf0ca2 100644
--- a/core/java/com/android/internal/os/AudioPowerCalculator.java
+++ b/core/java/com/android/internal/os/AudioPowerCalculator.java
@@ -78,7 +78,9 @@
         final double powerMah = mPowerEstimator.calculatePower(durationMs);
         app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO, durationMs)
                 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO, powerMah);
-        total.durationMs += durationMs;
-        total.powerMah += powerMah;
+        if (!app.isVirtualUid()) {
+            total.durationMs += durationMs;
+            total.powerMah += powerMah;
+        }
     }
 }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 70b9639..3b46f62 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -166,7 +166,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    static final int VERSION = 206;
+    static final int VERSION = 207;
 
     // The maximum number of names wakelocks we will keep track of
     // per uid; once the limit is reached, we batch the remaining wakelocks
@@ -546,9 +546,9 @@
                 final LongArrayMultiStateCounter onBatteryScreenOffCounter =
                         u.getProcStateScreenOffTimeCounter().getCounter();
 
-                if (uid == parentUid) {
-                    mKernelSingleUidTimeReader.addDelta(uid, onBatteryCounter, timestampMs);
-                    mKernelSingleUidTimeReader.addDelta(uid, onBatteryScreenOffCounter,
+                if (uid == parentUid || Process.isSdkSandboxUid(uid)) {
+                    mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryCounter, timestampMs);
+                    mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryScreenOffCounter,
                             timestampMs);
                 } else {
                     Uid.ChildUid childUid = u.getChildUid(uid);
@@ -964,6 +964,16 @@
          * Timers for each combination of frequency range and signal strength.
          */
         public final StopwatchTimer[][] perStateTimers;
+        /**
+         * Counters tracking the time (in milliseconds) spent transmitting data in a given state.
+         */
+        @Nullable
+        private LongSamplingCounter[][] mPerStateTxDurationMs = null;
+        /**
+         * Counters tracking the time (in milliseconds) spent receiving data in at given frequency.
+         */
+        @Nullable
+        private LongSamplingCounter[] mPerFrequencyRxDurationMs = null;
 
         RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase) {
             perStateTimers =
@@ -1024,15 +1034,198 @@
         }
 
         /**
-         * Reset display timers.
+         * Returns the duration in milliseconds spent in a given state since the last mark.
+         */
+        public long getTimeSinceMark(@ServiceState.FrequencyRange int frequencyRange,
+                int signalStrength, long elapsedRealtimeMs) {
+            return perStateTimers[frequencyRange][signalStrength].getTimeSinceMarkLocked(
+                    elapsedRealtimeMs * 1000) / 1000;
+        }
+
+        /**
+         * Set mark for all timers.
+         */
+        public void setMark(long elapsedRealtimeMs) {
+            final int size = perStateTimers.length;
+            for (int i = 0; i < size; i++) {
+                for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) {
+                    perStateTimers[i][j].setMark(elapsedRealtimeMs);
+                }
+            }
+        }
+
+        /**
+         * Returns numbers of frequencies tracked for this RAT.
+         */
+        public int getFrequencyRangeCount() {
+            return perStateTimers.length;
+        }
+
+        /**
+         * Add TX time for a given state.
+         */
+        public void incrementTxDuration(@ServiceState.FrequencyRange int frequencyRange,
+                int signalStrength, long durationMs) {
+            getTxDurationCounter(frequencyRange, signalStrength, true).addCountLocked(durationMs);
+        }
+
+        /**
+         * Add TX time for a given frequency.
+         */
+        public void incrementRxDuration(@ServiceState.FrequencyRange int frequencyRange,
+                long durationMs) {
+            getRxDurationCounter(frequencyRange, true).addCountLocked(durationMs);
+        }
+
+        /**
+         * Reset radio access technology timers and counts.
          */
         public void reset(long elapsedRealtimeUs) {
             final int size = perStateTimers.length;
             for (int i = 0; i < size; i++) {
                 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) {
                     perStateTimers[i][j].reset(false, elapsedRealtimeUs);
+                    if (mPerStateTxDurationMs == null) continue;
+                    mPerStateTxDurationMs[i][j].reset(false, elapsedRealtimeUs);
+                }
+                if (mPerFrequencyRxDurationMs == null) continue;
+                mPerFrequencyRxDurationMs[i].reset(false, elapsedRealtimeUs);
+            }
+        }
+
+        /**
+         * Write data to summary parcel
+         */
+        public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) {
+            final int freqCount = perStateTimers.length;
+            out.writeInt(freqCount);
+            out.writeInt(CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS);
+            for (int i = 0; i < freqCount; i++) {
+                for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) {
+                    perStateTimers[i][j].writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
                 }
             }
+
+            if (mPerStateTxDurationMs == null) {
+                out.writeInt(0);
+            } else {
+                out.writeInt(1);
+                for (int i = 0; i < freqCount; i++) {
+                    for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) {
+                        mPerStateTxDurationMs[i][j].writeSummaryFromParcelLocked(out);
+                    }
+                }
+            }
+
+            if (mPerFrequencyRxDurationMs == null) {
+                out.writeInt(0);
+            } else {
+                out.writeInt(1);
+                for (int i = 0; i < freqCount; i++) {
+                    mPerFrequencyRxDurationMs[i].writeSummaryFromParcelLocked(out);
+                }
+            }
+        }
+
+        /**
+         * Read data from summary parcel
+         */
+        public void readSummaryFromParcel(Parcel in) {
+            final int oldFreqCount = in.readInt();
+            final int oldSignalStrengthCount = in.readInt();
+            final int currFreqCount = perStateTimers.length;
+            final int currSignalStrengthCount = CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS;
+
+            for (int freq = 0; freq < oldFreqCount; freq++) {
+                for (int strength = 0; strength < oldSignalStrengthCount; strength++) {
+                    if (freq >= currFreqCount || strength >= currSignalStrengthCount) {
+                        // Mismatch with the summary parcel. Consume the data but don't use it.
+                        final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null,
+                                new TimeBase());
+                        // Consume perStateTimers data.
+                        temp.readSummaryFromParcelLocked(in);
+                    } else {
+                        perStateTimers[freq][strength].readSummaryFromParcelLocked(in);
+                    }
+                }
+            }
+
+            if (in.readInt() == 1) {
+                for (int freq = 0; freq < oldFreqCount; freq++) {
+                    for (int strength = 0; strength < oldSignalStrengthCount; strength++) {
+                        if (freq >= currFreqCount || strength >= currSignalStrengthCount) {
+                            // Mismatch with the summary parcel. Consume the data but don't use it.
+                            final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null,
+                                    new TimeBase());
+                            // Consume mPerStateTxDurationMs data.
+                            temp.readSummaryFromParcelLocked(in);
+                        }
+                        getTxDurationCounter(freq, strength, true).readSummaryFromParcelLocked(in);
+                    }
+                }
+            }
+
+            if (in.readInt() == 1) {
+                for (int freq = 0; freq < oldFreqCount; freq++) {
+                    if (freq >= currFreqCount) {
+                        // Mismatch with the summary parcel. Consume the data but don't use it.
+                        final StopwatchTimer
+                                temp = new StopwatchTimer(null, null, -1, null, new TimeBase());
+                        // Consume mPerFrequencyRxDurationMs data.
+                        temp.readSummaryFromParcelLocked(in);
+                        continue;
+                    }
+                    getRxDurationCounter(freq, true).readSummaryFromParcelLocked(in);
+                }
+            }
+        }
+
+        private LongSamplingCounter getTxDurationCounter(
+                @ServiceState.FrequencyRange int frequencyRange, int signalStrength, boolean make) {
+            if (mPerStateTxDurationMs == null) {
+                if (!make) return null;
+
+                final int freqCount = getFrequencyRangeCount();
+                final int signalStrengthCount = perStateTimers[0].length;
+                final TimeBase timeBase = perStateTimers[0][0].mTimeBase;
+                mPerStateTxDurationMs = new LongSamplingCounter[freqCount][signalStrengthCount];
+                for (int freq = 0; freq < freqCount; freq++) {
+                    for (int strength = 0; strength < signalStrengthCount; strength++) {
+                        mPerStateTxDurationMs[freq][strength] = new LongSamplingCounter(timeBase);
+                    }
+                }
+            }
+            if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) {
+                Slog.w(TAG, "Unexpected frequency range (" + frequencyRange
+                        + ") requested in getTxDurationCounter");
+                return null;
+            }
+            if (signalStrength < 0 || signalStrength >= perStateTimers[0].length) {
+                Slog.w(TAG, "Unexpected signal strength (" + signalStrength
+                        + ") requested in getTxDurationCounter");
+                return null;
+            }
+            return mPerStateTxDurationMs[frequencyRange][signalStrength];
+        }
+
+        private LongSamplingCounter getRxDurationCounter(
+                @ServiceState.FrequencyRange int frequencyRange, boolean make) {
+            if (mPerFrequencyRxDurationMs == null) {
+                if (!make) return null;
+
+                final int freqCount = getFrequencyRangeCount();
+                final TimeBase timeBase = perStateTimers[0][0].mTimeBase;
+                mPerFrequencyRxDurationMs = new LongSamplingCounter[freqCount];
+                for (int freq = 0; freq < freqCount; freq++) {
+                    mPerFrequencyRxDurationMs[freq] = new LongSamplingCounter(timeBase);
+                }
+            }
+            if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) {
+                Slog.w(TAG, "Unexpected frequency range (" + frequencyRange
+                        + ") requested in getRxDurationCounter");
+                return null;
+            }
+            return mPerFrequencyRxDurationMs[frequencyRange];
         }
     }
 
@@ -1929,18 +2122,26 @@
         private final TimeBase mTimeBase;
         private final LongMultiStateCounter mCounter;
 
-        private TimeMultiStateCounter(TimeBase timeBase, Parcel in, long timestampMs) {
+        private TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs) {
+            this(timeBase, new LongMultiStateCounter(stateCount), timestampMs);
+        }
+
+        private TimeMultiStateCounter(TimeBase timeBase, LongMultiStateCounter counter,
+                long timestampMs) {
             mTimeBase = timeBase;
-            mCounter = LongMultiStateCounter.CREATOR.createFromParcel(in);
+            mCounter = counter;
             mCounter.setEnabled(mTimeBase.isRunning(), timestampMs);
             timeBase.add(this);
         }
 
-        private TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs) {
-            mTimeBase = timeBase;
-            mCounter = new LongMultiStateCounter(stateCount);
-            mCounter.setEnabled(mTimeBase.isRunning(), timestampMs);
-            timeBase.add(this);
+        @Nullable
+        private static TimeMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase,
+                int stateCount, long timestampMs) {
+            LongMultiStateCounter counter = LongMultiStateCounter.CREATOR.createFromParcel(in);
+            if (counter.getStateCount() != stateCount) {
+                return null;
+            }
+            return new TimeMultiStateCounter(timeBase, counter, timestampMs);
         }
 
         private void writeToParcel(Parcel out) {
@@ -3510,11 +3711,8 @@
 
         private TimeMultiStateCounter readTimeMultiStateCounter(Parcel in, TimeBase timeBase) {
             if (in.readBoolean()) {
-                final TimeMultiStateCounter counter =
-                        new TimeMultiStateCounter(timeBase, in, mClock.elapsedRealtime());
-                if (counter.getStateCount() == BatteryConsumer.PROCESS_STATE_COUNT) {
-                    return counter;
-                }
+                return TimeMultiStateCounter.readFromParcel(in, timeBase,
+                        BatteryConsumer.PROCESS_STATE_COUNT, mClock.elapsedRealtime());
             }
             return null;
         }
@@ -3537,9 +3735,10 @@
                 // invalid.
                 TimeMultiStateCounter[] counters = new TimeMultiStateCounter[numCounters];
                 for (int i = 0; i < numCounters; i++) {
-                    final TimeMultiStateCounter counter =
-                            new TimeMultiStateCounter(timeBase, in, mClock.elapsedRealtime());
-                    if (counter.getStateCount() == BatteryConsumer.PROCESS_STATE_COUNT) {
+                    final TimeMultiStateCounter counter = TimeMultiStateCounter.readFromParcel(in,
+                            timeBase, BatteryConsumer.PROCESS_STATE_COUNT,
+                            mClock.elapsedRealtime());
+                    if (counter != null) {
                         counters[i] = counter;
                     } else {
                         valid = false;
@@ -4560,7 +4759,10 @@
         mIsolatedUidRefCounts.put(uid, refCount + 1);
     }
 
-    public int mapUid(int uid) {
+    private int mapUid(int uid) {
+        if (Process.isSdkSandboxUid(uid)) {
+            return Process.getAppUidForSdkSandboxUid(uid);
+        }
         int isolated = mIsolatedUids.get(uid, -1);
         return isolated > 0 ? isolated : uid;
     }
@@ -4656,16 +4858,18 @@
             long elapsedRealtimeMs, long uptimeMs) {
         int parentUid = mapUid(uid);
         if (uid != parentUid) {
-            // Isolated UIDs process state is already rolled up into parent, so no need to track
-            // Otherwise the parent's process state will get downgraded incorrectly
-            return;
+            if (Process.isIsolated(uid)) {
+                // Isolated UIDs process state is already rolled up into parent, so no need to track
+                // Otherwise the parent's process state will get downgraded incorrectly
+                return;
+            }
         }
         // TODO(b/155216561): It is possible for isolated uids to be in a higher
         // state than its parent uid. We should track the highest state within the union of host
         // and isolated uids rather than only the parent uid.
         FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid,
                 ActivityManager.processStateAmToProto(state));
-        getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+        getUidStatsLocked(parentUid, elapsedRealtimeMs, uptimeMs)
                 .updateUidProcessStateLocked(state, elapsedRealtimeMs, uptimeMs);
     }
 
@@ -7995,6 +8199,32 @@
                 elapsedRealtimeMs * 1000, STATS_SINCE_CHARGED) / 1000;
     }
 
+    @Override
+    public long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat,
+            @ServiceState.FrequencyRange int frequencyRange, int signalStrength,
+            long elapsedRealtimeMs) {
+        final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat];
+        if (stats == null) return DURATION_UNAVAILABLE;
+
+        final LongSamplingCounter counter = stats.getTxDurationCounter(frequencyRange,
+                signalStrength, false);
+        if (counter == null) return DURATION_UNAVAILABLE;
+
+        return counter.getCountLocked(STATS_SINCE_CHARGED);
+    }
+
+    @Override
+    public long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat,
+            @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs) {
+        final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat];
+        if (stats == null) return DURATION_UNAVAILABLE;
+
+        final LongSamplingCounter counter = stats.getRxDurationCounter(frequencyRange, false);
+        if (counter == null) return DURATION_UNAVAILABLE;
+
+        return counter.getCountLocked(STATS_SINCE_CHARGED);
+    }
+
     @UnsupportedAppUsage
     @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
         return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
@@ -10739,11 +10969,9 @@
                             = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
                 }
                 if (in.readBoolean()) {
-                    final TimeMultiStateCounter counter =
-                            new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, in, timestampMs);
-                    if (counter.getStateCount() == BatteryConsumer.PROCESS_STATE_COUNT) {
-                        mMobileRadioActiveTime = counter;
-                    }
+                    mMobileRadioActiveTime = TimeMultiStateCounter.readFromParcel(in,
+                            mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT,
+                            timestampMs);
                 }
 
                 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
@@ -10789,11 +11017,9 @@
 
             int stateCount = in.readInt();
             if (stateCount != 0) {
-                final TimeMultiStateCounter counter = new TimeMultiStateCounter(
-                        mBsi.mOnBatteryTimeBase, in, timestampMs);
-                if (stateCount == BatteryConsumer.PROCESS_STATE_COUNT) {
-                    mCpuActiveTimeMs = counter;
-                }
+                mCpuActiveTimeMs = TimeMultiStateCounter.readFromParcel(in,
+                        mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT,
+                        timestampMs);
             }
             mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in);
 
@@ -13477,6 +13703,67 @@
                     addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
                     mTmpRailStats.resetCellularTotalEnergyUsed();
                 }
+
+                // Proportionally smear Rx and Tx times across each RAt
+                final int levelCount = CellSignalStrength.getNumSignalStrengthLevels();
+                long[] perSignalStrengthActiveTimeMs = new long[levelCount];
+                long totalActiveTimeMs = 0;
+
+                for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) {
+                    final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat];
+                    if (ratStats == null) continue;
+
+                    final int freqCount = ratStats.getFrequencyRangeCount();
+                    for (int freq = 0; freq < freqCount; freq++) {
+                        for (int level = 0; level < levelCount; level++) {
+                            final long durationMs = ratStats.getTimeSinceMark(freq, level,
+                                    elapsedRealtimeMs);
+                            perSignalStrengthActiveTimeMs[level] += durationMs;
+                            totalActiveTimeMs += durationMs;
+                        }
+                    }
+                }
+
+                if (totalActiveTimeMs != 0) {
+                    // Smear the provided Tx/Rx durations across each RAT, frequency, and signal
+                    // strength.
+                    for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) {
+                        final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat];
+                        if (ratStats == null) continue;
+
+                        final int freqCount = ratStats.getFrequencyRangeCount();
+                        for (int freq = 0; freq < freqCount; freq++) {
+                            long frequencyDurationMs = 0;
+                            for (int level = 0; level < levelCount; level++) {
+                                final long durationMs = ratStats.getTimeSinceMark(freq, level,
+                                        elapsedRealtimeMs);
+                                final long totalLvlDurationMs =
+                                        perSignalStrengthActiveTimeMs[level];
+                                if (totalLvlDurationMs == 0) continue;
+                                final long totalTxLvlDurations =
+                                        deltaInfo.getTransmitDurationMillisAtPowerLevel(level);
+                                // Smear HAL provided Tx power level duration based on active modem
+                                // duration in a given state. (Add totalLvlDurationMs / 2 before
+                                // the integer division with totalLvlDurationMs for rounding.)
+                                final long proportionalTxDurationMs =
+                                        (durationMs * totalTxLvlDurations
+                                                + (totalLvlDurationMs / 2)) / totalLvlDurationMs;
+                                ratStats.incrementTxDuration(freq, level, proportionalTxDurationMs);
+                                frequencyDurationMs += durationMs;
+                            }
+                            final long totalRxDuration = deltaInfo.getReceiveTimeMillis();
+                            // Smear HAL provided Rx power duration based on active modem
+                            // duration in a given state.  (Add totalActiveTimeMs / 2 before the
+                            // integer division with totalActiveTimeMs for rounding.)
+                            final long proportionalRxDurationMs =
+                                    (frequencyDurationMs * totalRxDuration + (totalActiveTimeMs
+                                            / 2)) / totalActiveTimeMs;
+                            ratStats.incrementRxDuration(freq, proportionalRxDurationMs);
+                        }
+
+                        ratStats.setMark(elapsedRealtimeMs);
+                    }
+                }
             }
             long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
                     elapsedRealtimeMs * 1000);
@@ -15970,6 +16257,9 @@
     public Uid getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         Uid u = mUidStats.get(uid);
         if (u == null) {
+            if (Process.isSdkSandboxUid(uid)) {
+                Log.wtf(TAG, "Tracking an SDK Sandbox UID");
+            }
             u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs);
             mUidStats.put(uid, u);
         }
@@ -16879,14 +17169,18 @@
         mNextMaxDailyDeadlineMs = in.readLong();
         mBatteryTimeToFullSeconds = in.readLong();
 
-        mMeasuredEnergyStatsConfig = MeasuredEnergyStats.Config.createFromParcel(in);
-
-        /**
-         * WARNING: Supported buckets may have changed across boots. Bucket mismatch is handled
-         *          later when {@link #initMeasuredEnergyStatsLocked} is called.
-         */
-        mGlobalMeasuredEnergyStats = MeasuredEnergyStats.createAndReadSummaryFromParcel(
-                mMeasuredEnergyStatsConfig, in);
+        final MeasuredEnergyStats.Config config = MeasuredEnergyStats.Config.createFromParcel(in);
+        final MeasuredEnergyStats measuredEnergyStats =
+                MeasuredEnergyStats.createAndReadSummaryFromParcel(mMeasuredEnergyStatsConfig, in);
+        if (config != null && Arrays.equals(config.getStateNames(),
+                getBatteryConsumerProcessStateNames())) {
+            /**
+             * WARNING: Supported buckets may have changed across boots. Bucket mismatch is handled
+             *          later when {@link #initMeasuredEnergyStatsLocked} is called.
+             */
+            mMeasuredEnergyStatsConfig = config;
+            mGlobalMeasuredEnergyStats = measuredEnergyStats;
+        }
 
         mStartCount++;
 
@@ -16918,6 +17212,13 @@
             mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
             mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
         }
+
+        final int numRat = in.readInt();
+        for (int i = 0; i < numRat; i++) {
+            if (in.readInt() == 0) continue;
+            getRatBatteryStatsLocked(i).readSummaryFromParcel(in);
+        }
+
         mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
         mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
         mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
@@ -16978,7 +17279,6 @@
                 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in);
             }
         }
-
         int NKW = in.readInt();
         if (NKW > 10000) {
             throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW);
@@ -17106,11 +17406,9 @@
                     u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
                 }
                 if (in.readBoolean()) {
-                    TimeMultiStateCounter counter = new TimeMultiStateCounter(
-                            mOnBatteryTimeBase, in, elapsedRealtimeMs);
-                    if (counter.getStateCount() == BatteryConsumer.PROCESS_STATE_COUNT) {
-                        u.mMobileRadioActiveTime = counter;
-                    }
+                    u.mMobileRadioActiveTime = TimeMultiStateCounter.readFromParcel(in,
+                            mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT,
+                            elapsedRealtimeMs);
                 }
                 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
             }
@@ -17160,11 +17458,9 @@
 
             int stateCount = in.readInt();
             if (stateCount != 0) {
-                final TimeMultiStateCounter counter = new TimeMultiStateCounter(
-                        mOnBatteryTimeBase, in, mClock.elapsedRealtime());
-                if (stateCount == BatteryConsumer.PROCESS_STATE_COUNT) {
-                    u.mCpuActiveTimeMs = counter;
-                }
+                u.mCpuActiveTimeMs = TimeMultiStateCounter.readFromParcel(in,
+                        mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT,
+                        mClock.elapsedRealtime());
             }
             u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in);
 
@@ -17423,6 +17719,17 @@
             mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
             mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
         }
+        final int numRat = mPerRatBatteryStats.length;
+        out.writeInt(numRat);
+        for (int i = 0; i < numRat; i++) {
+            final RadioAccessTechnologyBatteryStats ratStat = mPerRatBatteryStats[i];
+            if (ratStat == null) {
+                out.writeInt(0);
+                continue;
+            }
+            out.writeInt(1);
+            ratStat.writeSummaryToParcel(out, nowRealtime);
+        }
         mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime);
         mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, nowRealtime);
         mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
@@ -17999,9 +18306,15 @@
         mLastWriteTimeMs = in.readLong();
         mBatteryTimeToFullSeconds = in.readLong();
 
-        mMeasuredEnergyStatsConfig = MeasuredEnergyStats.Config.createFromParcel(in);
-        mGlobalMeasuredEnergyStats =
+
+        final MeasuredEnergyStats.Config config = MeasuredEnergyStats.Config.createFromParcel(in);
+        final MeasuredEnergyStats measuredEnergyStats =
                 MeasuredEnergyStats.createFromParcel(mMeasuredEnergyStatsConfig, in);
+        if (config != null && Arrays.equals(config.getStateNames(),
+                getBatteryConsumerProcessStateNames())) {
+            mMeasuredEnergyStatsConfig = config;
+            mGlobalMeasuredEnergyStats = measuredEnergyStats;
+        }
 
         mRpmStats.clear();
         int NRPMS = in.readInt();
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
index a1c1917..81c6ee7 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -22,6 +22,7 @@
 import android.os.BatteryUsageStats;
 import android.os.BatteryUsageStatsQuery;
 import android.os.Parcel;
+import android.os.Process;
 import android.os.SystemClock;
 import android.os.UidBatteryConsumer;
 import android.util.Log;
@@ -162,6 +163,8 @@
         final boolean includeProcessStateData = ((query.getFlags()
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0)
                 && mStats.isProcessStateDataAvailable();
+        final boolean includeVirtualUids =  ((query.getFlags()
+                & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS) != 0);
 
         final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder(
                 mStats.getCustomEnergyConsumerNames(), includePowerModels,
@@ -174,6 +177,10 @@
         SparseArray<? extends BatteryStats.Uid> uidStats = mStats.getUidStats();
         for (int i = uidStats.size() - 1; i >= 0; i--) {
             final BatteryStats.Uid uid = uidStats.valueAt(i);
+            if (!includeVirtualUids && uid.getUid() == Process.SDK_SANDBOX_VIRTUAL_UID) {
+                continue;
+            }
+
             batteryUsageStatsBuilder.getOrCreateUidBatteryConsumerBuilder(uid)
                     .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND,
                             getProcessBackgroundTimeMs(uid, realtimeUs))
diff --git a/core/java/com/android/internal/os/BluetoothPowerCalculator.java b/core/java/com/android/internal/os/BluetoothPowerCalculator.java
index 2ebf689..e52c8a3 100644
--- a/core/java/com/android/internal/os/BluetoothPowerCalculator.java
+++ b/core/java/com/android/internal/os/BluetoothPowerCalculator.java
@@ -139,8 +139,10 @@
                         BatteryConsumer.POWER_COMPONENT_BLUETOOTH, powerAndDuration.powerMah,
                         powerModel);
 
-        powerAndDuration.totalDurationMs += powerAndDuration.durationMs;
-        powerAndDuration.totalPowerMah += powerAndDuration.powerMah;
+        if (!app.isVirtualUid()) {
+            powerAndDuration.totalDurationMs += powerAndDuration.durationMs;
+            powerAndDuration.totalPowerMah += powerAndDuration.powerMah;
+        }
 
         if (query.isProcessStateDataNeeded() && powerAndDuration.keys != null) {
             for (int j = 0; j < powerAndDuration.keys.length; j++) {
diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java
index 1fc2baf..8704e93 100644
--- a/core/java/com/android/internal/os/CpuPowerCalculator.java
+++ b/core/java/com/android/internal/os/CpuPowerCalculator.java
@@ -117,7 +117,9 @@
                 }
             }
             calculateApp(app, app.getBatteryStatsUid(), query, result, keys);
-            totalPowerMah += result.powerMah;
+            if (!app.isVirtualUid()) {
+                totalPowerMah += result.powerMah;
+            }
         }
 
         final long consumptionUC = batteryStats.getCpuMeasuredBatteryConsumptionUC();
diff --git a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java
index cbbb526..0853bd8 100644
--- a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java
+++ b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java
@@ -96,7 +96,9 @@
                 app.setConsumedPowerForCustomComponent(
                         BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i,
                         customMeasuredPowerMah[i]);
-                newTotalPowerMah[i] += customMeasuredPowerMah[i];
+                if (!app.isVirtualUid()) {
+                    newTotalPowerMah[i] += customMeasuredPowerMah[i];
+                }
             }
         }
         return newTotalPowerMah;
diff --git a/core/java/com/android/internal/os/GnssPowerCalculator.java b/core/java/com/android/internal/os/GnssPowerCalculator.java
index 0f78306..070783a 100644
--- a/core/java/com/android/internal/os/GnssPowerCalculator.java
+++ b/core/java/com/android/internal/os/GnssPowerCalculator.java
@@ -58,8 +58,11 @@
             final long consumptionUC =
                     app.getBatteryStatsUid().getGnssMeasuredBatteryConsumptionUC();
             final int powerModel = getPowerModel(consumptionUC, query);
-            appsPowerMah += calculateApp(app, app.getBatteryStatsUid(), powerModel,
+            final double powerMah = calculateApp(app, app.getBatteryStatsUid(), powerModel,
                     rawRealtimeUs, averageGnssPowerMa, consumptionUC);
+            if (!app.isVirtualUid()) {
+                appsPowerMah += powerMah;
+            }
         }
 
         final long consumptionUC = batteryStats.getGnssMeasuredBatteryConsumptionUC();
diff --git a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
index f4624de..d0df45c 100644
--- a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
+++ b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
@@ -136,12 +136,14 @@
             PowerAndDuration total,
             BatteryUsageStatsQuery query, BatteryConsumer.Key[] keys) {
         final long radioActiveDurationMs = calculateDuration(u, BatteryStats.STATS_SINCE_CHARGED);
-        total.totalAppDurationMs += radioActiveDurationMs;
-
         final long consumptionUC = u.getMobileRadioMeasuredBatteryConsumptionUC();
         final int powerModel = getPowerModel(consumptionUC, query);
         final double powerMah = calculatePower(u, powerModel, radioActiveDurationMs, consumptionUC);
-        total.totalAppPowerMah += powerMah;
+
+        if (!app.isVirtualUid()) {
+            total.totalAppDurationMs += radioActiveDurationMs;
+            total.totalAppPowerMah += powerMah;
+        }
 
         app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO,
                         radioActiveDurationMs)
diff --git a/core/java/com/android/internal/os/ScreenPowerCalculator.java b/core/java/com/android/internal/os/ScreenPowerCalculator.java
index 67d3d6e..5ca1a85 100644
--- a/core/java/com/android/internal/os/ScreenPowerCalculator.java
+++ b/core/java/com/android/internal/os/ScreenPowerCalculator.java
@@ -96,8 +96,10 @@
                                     appPowerAndDuration.durationMs)
                             .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN,
                                     appPowerAndDuration.powerMah, powerModel);
-                    totalAppPower += appPowerAndDuration.powerMah;
-                    totalAppDuration += appPowerAndDuration.durationMs;
+                    if (!app.isVirtualUid()) {
+                        totalAppPower += appPowerAndDuration.powerMah;
+                        totalAppDuration += appPowerAndDuration.durationMs;
+                    }
                 }
                 break;
             case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
@@ -192,10 +194,13 @@
         long totalActivityTimeMs = 0;
         final SparseLongArray activityTimeArray = new SparseLongArray();
         for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
-            final BatteryStats.Uid uid = uidBatteryConsumerBuilders.valueAt(i).getBatteryStatsUid();
+            final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
+            final BatteryStats.Uid uid = app.getBatteryStatsUid();
             final long timeMs = getProcessForegroundTimeMs(uid, rawRealtimeUs);
             activityTimeArray.put(uid.getUid(), timeMs);
-            totalActivityTimeMs += timeMs;
+            if (!app.isVirtualUid()) {
+                totalActivityTimeMs += timeMs;
+            }
         }
 
         if (totalActivityTimeMs >= MIN_ACTIVE_TIME_FOR_SMEARING) {
diff --git a/core/java/com/android/internal/os/SensorPowerCalculator.java b/core/java/com/android/internal/os/SensorPowerCalculator.java
index 4a9c91d..573692e 100644
--- a/core/java/com/android/internal/os/SensorPowerCalculator.java
+++ b/core/java/com/android/internal/os/SensorPowerCalculator.java
@@ -51,7 +51,9 @@
                 builder.getUidBatteryConsumerBuilders();
         for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
             final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
-            appsPowerMah += calculateApp(app, app.getBatteryStatsUid(), rawRealtimeUs);
+            if (!app.isVirtualUid()) {
+                appsPowerMah += calculateApp(app, app.getBatteryStatsUid(), rawRealtimeUs);
+            }
         }
 
         builder.getAggregateBatteryConsumerBuilder(
diff --git a/core/java/com/android/internal/os/UserPowerCalculator.java b/core/java/com/android/internal/os/UserPowerCalculator.java
index 22cff6e..79e3a19 100644
--- a/core/java/com/android/internal/os/UserPowerCalculator.java
+++ b/core/java/com/android/internal/os/UserPowerCalculator.java
@@ -49,7 +49,11 @@
                 builder.getUidBatteryConsumerBuilders();
 
         for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
-            UidBatteryConsumer.Builder uidBuilder = uidBatteryConsumerBuilders.valueAt(i);
+            final UidBatteryConsumer.Builder uidBuilder = uidBatteryConsumerBuilders.valueAt(i);
+            if (uidBuilder.isVirtualUid()) {
+                continue;
+            }
+
             final int uid = uidBuilder.getUid();
             if (UserHandle.getAppId(uid) < Process.FIRST_APPLICATION_UID) {
                 continue;
diff --git a/core/java/com/android/internal/os/VideoPowerCalculator.java b/core/java/com/android/internal/os/VideoPowerCalculator.java
index a222bcb..2daf15e 100644
--- a/core/java/com/android/internal/os/VideoPowerCalculator.java
+++ b/core/java/com/android/internal/os/VideoPowerCalculator.java
@@ -75,7 +75,9 @@
         final double powerMah = mPowerEstimator.calculatePower(durationMs);
         app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO, durationMs)
                 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_VIDEO, powerMah);
-        total.durationMs += durationMs;
-        total.powerMah += powerMah;
+        if (!app.isVirtualUid()) {
+            total.durationMs += durationMs;
+            total.powerMah += powerMah;
+        }
     }
 }
diff --git a/core/java/com/android/internal/os/WakelockPowerCalculator.java b/core/java/com/android/internal/os/WakelockPowerCalculator.java
index 0251e1c..3ae7113 100644
--- a/core/java/com/android/internal/os/WakelockPowerCalculator.java
+++ b/core/java/com/android/internal/os/WakelockPowerCalculator.java
@@ -62,8 +62,10 @@
                     BatteryStats.STATS_SINCE_CHARGED);
             app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WAKELOCK, result.durationMs)
                     .setConsumedPower(BatteryConsumer.POWER_COMPONENT_WAKELOCK, result.powerMah);
-            totalAppDurationMs += result.durationMs;
-            appPowerMah += result.powerMah;
+            if (!app.isVirtualUid()) {
+                totalAppDurationMs += result.durationMs;
+                appPowerMah += result.powerMah;
+            }
 
             if (app.getUid() == Process.ROOT_UID) {
                 osBatteryConsumer = app;
diff --git a/core/java/com/android/internal/os/WifiPowerCalculator.java b/core/java/com/android/internal/os/WifiPowerCalculator.java
index 8c3fb86..2181821 100644
--- a/core/java/com/android/internal/os/WifiPowerCalculator.java
+++ b/core/java/com/android/internal/os/WifiPowerCalculator.java
@@ -111,9 +111,10 @@
             calculateApp(powerDurationAndTraffic, app.getBatteryStatsUid(), powerModel,
                     rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED,
                     batteryStats.hasWifiActivityReporting(), consumptionUC);
-
-            totalAppDurationMs += powerDurationAndTraffic.durationMs;
-            totalAppPowerMah += powerDurationAndTraffic.powerMah;
+            if (!app.isVirtualUid()) {
+                totalAppDurationMs += powerDurationAndTraffic.durationMs;
+                totalAppPowerMah += powerDurationAndTraffic.powerMah;
+            }
 
             app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI,
                     powerDurationAndTraffic.durationMs);
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 40e4085..89ac722 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -30,6 +30,7 @@
 import static android.view.View.MeasureSpec.getMode;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.view.ViewRootImpl.CAPTION_ON_SHELL;
 import static android.view.Window.DECOR_CAPTION_SHADE_DARK;
 import static android.view.Window.DECOR_CAPTION_SHADE_LIGHT;
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
@@ -2120,7 +2121,9 @@
      * corresponding insets change to the InsetsController.
      */
     public void notifyCaptionHeightChanged() {
-        getWindowInsetsController().setCaptionInsetsHeight(getCaptionInsetsHeight());
+        if (!CAPTION_ON_SHELL) {
+            getWindowInsetsController().setCaptionInsetsHeight(getCaptionInsetsHeight());
+        }
     }
 
     void setWindow(PhoneWindow phoneWindow) {
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java
index 37c96e7..74749cc 100644
--- a/core/java/com/android/internal/policy/TransitionAnimation.java
+++ b/core/java/com/android/internal/policy/TransitionAnimation.java
@@ -100,7 +100,7 @@
 
     // TODO (b/215515255): remove once we full migrate to shell transitions
     private static final boolean SHELL_TRANSITIONS_ENABLED =
-            SystemProperties.getBoolean("persist.debug.shell_transit", false);
+            SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
 
     private final Context mContext;
     private final String mTag;
@@ -312,9 +312,9 @@
 
     /** Load animation by attribute Id from android package. */
     @Nullable
-    public Animation loadDefaultAnimationAttr(int animAttr) {
+    public Animation loadDefaultAnimationAttr(int animAttr, boolean translucent) {
         return loadAnimationAttr(DEFAULT_PACKAGE, mDefaultWindowAnimationStyleResId, animAttr,
-                false /* translucent */);
+                translucent);
     }
 
     @Nullable
diff --git a/core/java/com/android/internal/power/MeasuredEnergyStats.java b/core/java/com/android/internal/power/MeasuredEnergyStats.java
index 7262e84..7fb8696 100644
--- a/core/java/com/android/internal/power/MeasuredEnergyStats.java
+++ b/core/java/com/android/internal/power/MeasuredEnergyStats.java
@@ -194,6 +194,7 @@
             return mSupportedMultiStateBuckets[index];
         }
 
+        @NonNull
         public String[] getStateNames() {
             return mStateNames;
         }
@@ -321,6 +322,10 @@
             LongMultiStateCounter multiStateCounter = null;
             if (in.readBoolean()) {
                 multiStateCounter = LongMultiStateCounter.CREATOR.createFromParcel(in);
+                if (mConfig == null
+                        || multiStateCounter.getStateCount() != mConfig.getStateNames().length) {
+                    multiStateCounter = null;
+                }
             }
 
             if (index < mAccumulatedChargeMicroCoulomb.length) {
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index d629d66..089179d 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -297,6 +297,11 @@
      */
     void runGcForTest();
 
+    /**
+     * Send a request to SystemUI to put a given active tile in listening state
+     */
+    void requestTileServiceListeningState(in ComponentName componentName);
+
     void requestAddTile(in ComponentName componentName, in CharSequence appName, in CharSequence label, in Icon icon, in IAddTileResultCallback callback);
     void cancelRequestAddTile(in String packageName);
 
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 9163b6d..2ee5e79 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -70,7 +70,7 @@
     void onPanelRevealed(boolean clearNotificationEffects, int numItems);
     void onPanelHidden();
     // Mark current notifications as "seen" and stop ringing, vibrating, blinking.
-    void clearNotificationEffects();
+    oneway void clearNotificationEffects();
     void onNotificationClick(String key, in NotificationVisibility nv);
     void onNotificationActionClick(String key, int actionIndex, in Notification.Action action, in NotificationVisibility nv, boolean generatedByAssistant);
     void onNotificationError(String pkg, String tag, int id,
@@ -91,7 +91,7 @@
     void onBubbleNotificationSuppressionChanged(String key, boolean isNotifSuppressed, boolean isBubbleSuppressed);
     void hideCurrentInputMethodForBubbles();
     void grantInlineReplyUriPermission(String key, in Uri uri, in UserHandle user, String packageName);
-    void clearInlineReplyUriPermissions(String key);
+    oneway void clearInlineReplyUriPermissions(String key);
     void onNotificationFeedbackReceived(String key, in Bundle feedback);
 
     void onGlobalActionsShown();
@@ -171,6 +171,11 @@
      */
     void suppressAmbientDisplay(boolean suppress);
 
+    /**
+     * Send a request to SystemUI to put a given active tile in listening state
+     */
+    void requestTileServiceListeningState(in ComponentName componentName, int userId);
+
     void requestAddTile(in ComponentName componentName, in CharSequence label, in Icon icon, int userId, in IAddTileResultCallback callback);
     void cancelRequestAddTile(in String packageName);
 
diff --git a/core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl b/core/java/com/android/internal/telephony/ICarrierPrivilegesCallback.aidl
similarity index 84%
rename from core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl
rename to core/java/com/android/internal/telephony/ICarrierPrivilegesCallback.aidl
index 6ca8cec..0c8e73f 100644
--- a/core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl
+++ b/core/java/com/android/internal/telephony/ICarrierPrivilegesCallback.aidl
@@ -16,7 +16,8 @@
 
 package com.android.internal.telephony;
 
-oneway interface ICarrierPrivilegesListener {
+oneway interface ICarrierPrivilegesCallback {
     void onCarrierPrivilegesChanged(
             in List<String> privilegedPackageNames, in int[] privilegedUids);
+    void onCarrierServiceChanged(in String carrierServicePackageName, in int carrierServiceUid);
 }
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 9712d7e..c7fa757 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -32,7 +32,7 @@
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.emergency.EmergencyNumber;
-import com.android.internal.telephony.ICarrierPrivilegesListener;
+import com.android.internal.telephony.ICarrierPrivilegesCallback;
 import com.android.internal.telephony.IPhoneStateListener;
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
 
@@ -102,9 +102,11 @@
     void notifyLinkCapacityEstimateChanged(in int phoneId, in int subId,
             in List<LinkCapacityEstimate> linkCapacityEstimateList);
 
-    void addCarrierPrivilegesListener(
-            int phoneId, ICarrierPrivilegesListener callback, String pkg, String featureId);
-    void removeCarrierPrivilegesListener(ICarrierPrivilegesListener callback, String pkg);
+    void addCarrierPrivilegesCallback(
+            int phoneId, ICarrierPrivilegesCallback callback, String pkg, String featureId);
+    void removeCarrierPrivilegesCallback(ICarrierPrivilegesCallback callback, String pkg);
     void notifyCarrierPrivilegesChanged(
             int phoneId, in List<String> privilegedPackageNames, in int[] privilegedUids);
+    void notifyCarrierServiceChanged(int phoneId, in String packageName, int uid);
+
 }
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index d3c3917..f4f438b 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -11,8 +11,12 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.graphics.Bitmap;
+import android.graphics.ColorSpace;
 import android.graphics.Insets;
+import android.graphics.ParcelableColorSpace;
 import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -26,6 +30,7 @@
 import android.util.Log;
 import android.view.WindowManager;
 
+import java.util.Objects;
 import java.util.function.Consumer;
 
 public class ScreenshotHelper {
@@ -154,6 +159,72 @@
                 };
     }
 
+    /**
+     * Bundler used to convert between a hardware bitmap and a bundle without copying the internal
+     * content. This is expected to be used together with {@link #provideScreenshot} to handle a
+     * hardware bitmap as a screenshot.
+     */
+    public static final class HardwareBitmapBundler {
+        private static final String KEY_BUFFER = "bitmap_util_buffer";
+        private static final String KEY_COLOR_SPACE = "bitmap_util_color_space";
+
+        private HardwareBitmapBundler() {
+        }
+
+        /**
+         * Creates a Bundle that represents the given Bitmap.
+         * <p>The Bundle will contain a wrapped version of the Bitmaps HardwareBuffer, so will avoid
+         * copies when passing across processes, only pass to processes you trust.
+         *
+         * <p>Returns a new Bundle rather than modifying an exiting one to avoid key collisions, the
+         * returned Bundle should be treated as a standalone object.
+         *
+         * @param bitmap to convert to bundle
+         * @return a Bundle representing the bitmap, should only be parsed by
+         * {@link #bundleToHardwareBitmap(Bundle)}
+         */
+        public static Bundle hardwareBitmapToBundle(Bitmap bitmap) {
+            if (bitmap.getConfig() != Bitmap.Config.HARDWARE) {
+                throw new IllegalArgumentException(
+                        "Passed bitmap must have hardware config, found: " + bitmap.getConfig());
+            }
+
+            // Bitmap assumes SRGB for null color space
+            ParcelableColorSpace colorSpace =
+                    bitmap.getColorSpace() == null
+                            ? new ParcelableColorSpace(ColorSpace.get(ColorSpace.Named.SRGB))
+                            : new ParcelableColorSpace(bitmap.getColorSpace());
+
+            Bundle bundle = new Bundle();
+            bundle.putParcelable(KEY_BUFFER, bitmap.getHardwareBuffer());
+            bundle.putParcelable(KEY_COLOR_SPACE, colorSpace);
+
+            return bundle;
+        }
+
+        /**
+         * Extracts the Bitmap added to a Bundle with {@link #hardwareBitmapToBundle(Bitmap)} .}
+         *
+         * <p>This Bitmap contains the HardwareBuffer from the original caller, be careful passing
+         * this
+         * Bitmap on to any other source.
+         *
+         * @param bundle containing the bitmap
+         * @return a hardware Bitmap
+         */
+        public static Bitmap bundleToHardwareBitmap(Bundle bundle) {
+            if (!bundle.containsKey(KEY_BUFFER) || !bundle.containsKey(KEY_COLOR_SPACE)) {
+                throw new IllegalArgumentException("Bundle does not contain a hardware bitmap");
+            }
+
+            HardwareBuffer buffer = bundle.getParcelable(KEY_BUFFER);
+            ParcelableColorSpace colorSpace = bundle.getParcelable(KEY_COLOR_SPACE);
+
+            return Bitmap.wrapHardwareBuffer(Objects.requireNonNull(buffer),
+                    colorSpace.getColorSpace());
+        }
+    }
+
     private static final String TAG = "ScreenshotHelper";
 
     // Time until we give up on the screenshot & show an error instead.
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 6673f67..842d72a 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -51,10 +51,10 @@
     @Override
     public void resized(ClientWindowFrames frames, boolean reportDraw,
             MergedConfiguration mergedConfiguration, boolean forceLayout,
-            boolean alwaysConsumeSystemBars, int displayId) {
+            boolean alwaysConsumeSystemBars, int displayId, int seqId) {
         if (reportDraw) {
             try {
-                mSession.finishDrawing(this, null /* postDrawTransaction */);
+                mSession.finishDrawing(this, null /* postDrawTransaction */, seqId);
             } catch (RemoteException e) {
             }
         }
diff --git a/core/java/com/android/internal/view/IInputMethod.aidl b/core/java/com/android/internal/view/IInputMethod.aidl
index d2bc344..273c5f1 100644
--- a/core/java/com/android/internal/view/IInputMethod.aidl
+++ b/core/java/com/android/internal/view/IInputMethod.aidl
@@ -37,8 +37,7 @@
  */
 oneway interface IInputMethod {
     void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privOps,
-             int configChanges, boolean stylusHwSupported,
-             boolean shouldShowImeSwitcherWhenImeIsShown);
+             int configChanges, boolean stylusHwSupported, int navigationBarFlags);
 
     void onCreateInlineSuggestionsRequest(in InlineSuggestionsRequestInfo requestInfo,
             in IInlineSuggestionsRequestCallback cb);
@@ -48,10 +47,9 @@
     void unbindInput();
 
     void startInput(in IBinder startInputToken, in IInputContext inputContext,
-            in EditorInfo attribute, boolean restarting,
-             boolean shouldShowImeSwitcherWhenImeIsShown);
+            in EditorInfo attribute, boolean restarting, int navigationBarFlags);
 
-    void onShouldShowImeSwitcherWhenImeIsShownChanged(boolean shouldShowImeSwitcherWhenImeIsShown);
+    void onNavButtonFlagsChanged(int navButtonFlags);
 
     void createSession(in InputChannel channel, IInputSessionCallback callback);
 
diff --git a/core/java/com/android/internal/widget/CachingIconView.java b/core/java/com/android/internal/widget/CachingIconView.java
index 299cbe1..bd27e60 100644
--- a/core/java/com/android/internal/widget/CachingIconView.java
+++ b/core/java/com/android/internal/widget/CachingIconView.java
@@ -23,6 +23,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
@@ -35,6 +36,9 @@
 import android.widget.ImageView;
 import android.widget.RemoteViews;
 
+import com.android.internal.R;
+
+import java.io.IOException;
 import java.util.Objects;
 import java.util.function.Consumer;
 
@@ -55,9 +59,42 @@
     private int mBackgroundColor;
     private boolean mWillBeForceHidden;
 
+    private int mMaxDrawableWidth = -1;
+    private int mMaxDrawableHeight = -1;
+
+    public CachingIconView(Context context) {
+        this(context, null, 0, 0);
+    }
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public CachingIconView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0, 0);
+    }
+
+    public CachingIconView(Context context, @Nullable AttributeSet attrs,
+            int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public CachingIconView(Context context, @Nullable AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    private void init(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        if (attrs == null) {
+            return;
+        }
+
+        TypedArray ta = context.obtainStyledAttributes(attrs,
+                R.styleable.CachingIconView, defStyleAttr, defStyleRes);
+        mMaxDrawableWidth = ta.getDimensionPixelSize(R.styleable
+                .CachingIconView_maxDrawableWidth, -1);
+        mMaxDrawableHeight = ta.getDimensionPixelSize(R.styleable
+                .CachingIconView_maxDrawableHeight, -1);
+        ta.recycle();
     }
 
     @Override
@@ -66,15 +103,31 @@
         if (!testAndSetCache(icon)) {
             mInternalSetDrawable = true;
             // This calls back to setImageDrawable, make sure we don't clear the cache there.
-            super.setImageIcon(icon);
+            Drawable drawable = loadSizeRestrictedIcon(icon);
+            if (drawable == null) {
+                super.setImageIcon(icon);
+            } else {
+                super.setImageDrawable(drawable);
+            }
             mInternalSetDrawable = false;
         }
     }
 
+    @Nullable
+    private Drawable loadSizeRestrictedIcon(@Nullable Icon icon) {
+        try {
+            return LocalImageResolver.resolveImage(icon, getContext(), mMaxDrawableWidth,
+                    mMaxDrawableHeight);
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
     @Override
-    public Runnable setImageIconAsync(@Nullable Icon icon) {
+    public Runnable setImageIconAsync(@Nullable final Icon icon) {
         resetCache();
-        return super.setImageIconAsync(icon);
+        Drawable drawable = loadSizeRestrictedIcon(icon);
+        return () -> setImageDrawable(drawable);
     }
 
     @Override
@@ -83,14 +136,34 @@
         if (!testAndSetCache(resId)) {
             mInternalSetDrawable = true;
             // This calls back to setImageDrawable, make sure we don't clear the cache there.
-            super.setImageResource(resId);
+            Drawable drawable = loadSizeRestrictedDrawable(resId);
+            if (drawable == null) {
+                super.setImageResource(resId);
+            } else {
+                super.setImageDrawable(drawable);
+            }
             mInternalSetDrawable = false;
         }
     }
 
+    @Nullable
+    private Drawable loadSizeRestrictedDrawable(@DrawableRes int resId) {
+        try {
+            return LocalImageResolver.resolveImage(resId, getContext(), mMaxDrawableWidth,
+                    mMaxDrawableHeight);
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
     @Override
     public Runnable setImageResourceAsync(@DrawableRes int resId) {
         resetCache();
+        Drawable drawable = loadSizeRestrictedDrawable(resId);
+        if (drawable != null) {
+            return () -> setImageDrawable(drawable);
+        }
+
         return super.setImageResourceAsync(resId);
     }
 
@@ -98,13 +171,35 @@
     @RemotableViewMethod(asyncImpl="setImageURIAsync")
     public void setImageURI(@Nullable Uri uri) {
         resetCache();
-        super.setImageURI(uri);
+        Drawable drawable = loadSizeRestrictedUri(uri);
+        if (drawable == null) {
+            super.setImageURI(uri);
+        } else {
+            mInternalSetDrawable = true;
+            super.setImageDrawable(drawable);
+            mInternalSetDrawable = false;
+        }
+    }
+
+    @Nullable
+    private Drawable loadSizeRestrictedUri(@Nullable Uri uri) {
+        try {
+            return LocalImageResolver.resolveImage(uri, getContext(), mMaxDrawableWidth,
+                    mMaxDrawableHeight);
+        } catch (IOException e) {
+            return null;
+        }
     }
 
     @Override
     public Runnable setImageURIAsync(@Nullable Uri uri) {
         resetCache();
-        return super.setImageURIAsync(uri);
+        Drawable drawable = loadSizeRestrictedUri(uri);
+        if (drawable == null) {
+            return super.setImageURIAsync(uri);
+        } else {
+            return () -> setImageDrawable(drawable);
+        }
     }
 
     @Override
@@ -307,4 +402,18 @@
     public void setWillBeForceHidden(boolean forceHidden) {
         mWillBeForceHidden = forceHidden;
     }
+
+    /**
+     * Returns the set maximum width of drawable in pixels. -1 if not set.
+     */
+    public int getMaxDrawableWidth() {
+        return mMaxDrawableWidth;
+    }
+
+    /**
+     * Returns the set maximum height of drawable in pixels. -1 if not set.
+     */
+    public int getMaxDrawableHeight() {
+        return mMaxDrawableHeight;
+    }
 }
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 5fa4a65..4706aff 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -66,7 +66,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.function.Consumer;
 
 /**
  * A custom-built layout for the Notification.MessagingStyle allows dynamic addition and removal
@@ -76,8 +75,6 @@
 public class ConversationLayout extends FrameLayout
         implements ImageMessageConsumer, IMessagingLayout {
 
-    private static final Consumer<MessagingMessage> REMOVE_MESSAGE
-            = MessagingMessage::removeMessage;
     public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
     public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
     public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
@@ -150,7 +147,7 @@
     private Icon mShortcutIcon;
     private View mAppNameDivider;
     private TouchDelegateComposite mTouchDelegate = new TouchDelegateComposite(this);
-    private ArrayList<MessagingGroup> mToRecycle = new ArrayList<>();
+    private ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();
 
     public ConversationLayout(@NonNull Context context) {
         super(context);
@@ -463,8 +460,12 @@
         removeGroups(oldGroups);
 
         // Let's remove the remaining messages
-        mMessages.forEach(REMOVE_MESSAGE);
-        mHistoricMessages.forEach(REMOVE_MESSAGE);
+        for (MessagingMessage message : mMessages) {
+            message.removeMessage(mToRecycle);
+        }
+        for (MessagingMessage historicMessage : mHistoricMessages) {
+            historicMessage.removeMessage(mToRecycle);
+        }
 
         mMessages = messages;
         mHistoricMessages = historicMessages;
@@ -475,8 +476,8 @@
         updateConversationLayout();
 
         // Recycle everything at the end of the update, now that we know it's no longer needed.
-        for (MessagingGroup group : mToRecycle) {
-            group.recycle();
+        for (MessagingLinearLayout.MessagingChild child : mToRecycle) {
+            child.recycle();
         }
         mToRecycle.clear();
     }
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index db4bc2c..3494c9e 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -53,7 +53,6 @@
     VerifyCredentialResponse verifyTiedProfileChallenge(in LockscreenCredential credential, int userId, int flags);
     VerifyCredentialResponse verifyGatekeeperPasswordHandle(long gatekeeperPasswordHandle, long challenge, int userId);
     void removeGatekeeperPasswordHandle(long gatekeeperPasswordHandle);
-    boolean checkVoldPassword(int userId);
     int getCredentialType(int userId);
     byte[] getHashFactor(in LockscreenCredential currentCredential, int userId);
     void setSeparateProfileChallengeEnabled(int userId, boolean enabled, in LockscreenCredential managedUserPassword);
@@ -97,7 +96,6 @@
     boolean hasSecureLockScreen();
     boolean tryUnlockWithCachedUnifiedChallenge(int userId);
     void removeCachedUnifiedChallenge(int userId);
-    void updateEncryptionPassword(int type, in byte[] password);
     boolean registerWeakEscrowTokenRemovedListener(in IWeakEscrowTokenRemovedListener listener);
     boolean unregisterWeakEscrowTokenRemovedListener(in IWeakEscrowTokenRemovedListener listener);
     long addWeakEscrowToken(in byte[] token, int userId, in IWeakEscrowTokenActivatedListener callback);
diff --git a/core/java/com/android/internal/widget/LocalImageResolver.java b/core/java/com/android/internal/widget/LocalImageResolver.java
index 616b699..66a3ff9 100644
--- a/core/java/com/android/internal/widget/LocalImageResolver.java
+++ b/core/java/com/android/internal/widget/LocalImageResolver.java
@@ -16,21 +16,25 @@
 
 package com.android.internal.widget;
 
+import android.annotation.DrawableRes;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.graphics.Bitmap;
 import android.graphics.ImageDecoder;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.util.Size;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.io.IOException;
 
 /** A class to extract Drawables from a MessagingStyle/ConversationStyle message. */
 public class LocalImageResolver {
-    private static final String TAG = LocalImageResolver.class.getSimpleName();
 
-    private static final int MAX_SAFE_ICON_SIZE_PX = 480;
+    @VisibleForTesting
+    static final int DEFAULT_MAX_SAFE_ICON_SIZE_PX = 480;
 
     /**
      * Resolve an image from the given Uri using {@link ImageDecoder}
@@ -38,9 +42,9 @@
     public static Drawable resolveImage(Uri uri, Context context) throws IOException {
         final ImageDecoder.Source source =
                 ImageDecoder.createSource(context.getContentResolver(), uri);
-        final Drawable drawable =
-                ImageDecoder.decodeDrawable(source, LocalImageResolver::onHeaderDecoded);
-        return drawable;
+        return ImageDecoder.decodeDrawable(source,
+                (decoder, info, s) -> LocalImageResolver.onHeaderDecoded(decoder, info,
+                        DEFAULT_MAX_SAFE_ICON_SIZE_PX, DEFAULT_MAX_SAFE_ICON_SIZE_PX));
     }
 
     /**
@@ -48,17 +52,49 @@
      * using {@link Icon#loadDrawable(Context)} otherwise.  This will correctly apply the Icon's,
      * tint, if present, to the drawable.
      */
-    public static Drawable resolveImage(Icon icon, Context context) throws IOException {
-        Uri uri = getResolvableUri(icon);
-        if (uri != null) {
-            Drawable result = resolveImage(uri, context);
-            if (icon.hasTint()) {
-                result.mutate();
-                result.setTintList(icon.getTintList());
-                result.setTintBlendMode(icon.getTintBlendMode());
-            }
-            return result;
+    public static Drawable resolveImage(@Nullable Icon icon, Context context)
+            throws IOException {
+        return resolveImage(icon, context, DEFAULT_MAX_SAFE_ICON_SIZE_PX,
+                DEFAULT_MAX_SAFE_ICON_SIZE_PX);
+    }
+
+    /**
+     * Get the drawable from Icon using {@link ImageDecoder} if it contains a Uri, or
+     * using {@link Icon#loadDrawable(Context)} otherwise.  This will correctly apply the Icon's,
+     * tint, if present, to the drawable.
+     */
+    @Nullable
+    public static Drawable resolveImage(@Nullable Icon icon, Context context, int maxWidth,
+            int maxHeight)
+            throws IOException {
+        if (icon == null) {
+            return null;
         }
+
+        switch (icon.getType()) {
+            case Icon.TYPE_URI:
+            case Icon.TYPE_URI_ADAPTIVE_BITMAP:
+                Uri uri = getResolvableUri(icon);
+                if (uri != null) {
+                    Drawable result = resolveImage(uri, context, maxWidth, maxHeight);
+                    return tintDrawable(icon, result);
+                }
+                break;
+            case Icon.TYPE_RESOURCE:
+                Drawable result = resolveImage(icon.getResId(), context, maxWidth, maxHeight);
+                if (result != null) {
+                    return tintDrawable(icon, result);
+                }
+                break;
+            case Icon.TYPE_BITMAP:
+            case Icon.TYPE_ADAPTIVE_BITMAP:
+                return resolveBitmapImage(icon, context, maxWidth, maxHeight);
+            case Icon.TYPE_DATA:    // We can't really improve on raw data images.
+            default:
+                break;
+        }
+
+        // Fallback to straight drawable load if we fail with more efficient approach.
         return icon.loadDrawable(context);
     }
 
@@ -66,7 +102,71 @@
             throws IOException {
         final ImageDecoder.Source source =
                 ImageDecoder.createSource(context.getContentResolver(), uri);
+        return resolveImage(source, maxWidth, maxHeight);
+    }
+
+    /**
+     * Attempts to resolve the resource as a bitmap drawable constrained within max sizes.
+     *
+     * @return decoded drawable or null if the passed resource is not a straight bitmap
+     */
+    @Nullable
+    public static Drawable resolveImage(@DrawableRes int resId, Context context, int maxWidth,
+            int maxHeight)
+            throws IOException {
+        final ImageDecoder.Source source = ImageDecoder.createSource(context.getResources(), resId);
+        // It's possible that the resource isn't an actual bitmap drawable so this decode can fail.
+        // Return null in that case.
+        try {
+            return resolveImage(source, maxWidth, maxHeight);
+        } catch (ImageDecoder.DecodeException e) {
+            return null;
+        }
+    }
+
+    @Nullable
+    private static Drawable resolveBitmapImage(Icon icon, Context context, int maxWidth,
+            int maxHeight) {
+        Bitmap bitmap = icon.getBitmap();
+        if (bitmap == null) {
+            return null;
+        }
+
+        if (bitmap.getWidth() > maxWidth || bitmap.getHeight() > maxHeight) {
+            Icon smallerIcon = icon.getType() == Icon.TYPE_ADAPTIVE_BITMAP
+                    ? Icon.createWithAdaptiveBitmap(bitmap) : Icon.createWithBitmap(bitmap);
+            // We don't want to modify the source icon, create a copy.
+            smallerIcon.setTintList(icon.getTintList())
+                    .setTintBlendMode(icon.getTintBlendMode())
+                    .scaleDownIfNecessary(maxWidth, maxHeight);
+            return smallerIcon.loadDrawable(context);
+        }
+
+        return icon.loadDrawable(context);
+    }
+
+    @Nullable
+    private static Drawable tintDrawable(Icon icon, @Nullable Drawable drawable) {
+        if (drawable == null) {
+            return null;
+        }
+
+        if (icon.hasTint()) {
+            drawable.mutate();
+            drawable.setTintList(icon.getTintList());
+            drawable.setTintBlendMode(icon.getTintBlendMode());
+        }
+
+        return drawable;
+    }
+
+    private static Drawable resolveImage(ImageDecoder.Source source, int maxWidth, int maxHeight)
+            throws IOException {
         return ImageDecoder.decodeDrawable(source, (decoder, info, unused) -> {
+            if (maxWidth <= 0 || maxHeight <= 0) {
+                return;
+            }
+
             final Size size = info.getSize();
             if (size.getWidth() > size.getHeight()) {
                 if (size.getWidth() > maxWidth) {
@@ -88,11 +188,12 @@
     }
 
     private static void onHeaderDecoded(ImageDecoder decoder, ImageDecoder.ImageInfo info,
-            ImageDecoder.Source source) {
+            int maxWidth, int maxHeight) {
         final Size size = info.getSize();
         final int originalSize = Math.max(size.getHeight(), size.getWidth());
-        final double ratio = (originalSize > MAX_SAFE_ICON_SIZE_PX)
-                ? originalSize * 1f / MAX_SAFE_ICON_SIZE_PX
+        final int maxSize = Math.max(maxWidth, maxHeight);
+        final double ratio = (originalSize > maxSize)
+                ? originalSize * 1f / maxSize
                 : 1.0;
         decoder.setTargetSampleSize(getPowerOfTwoForSampleRatio(ratio));
     }
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 1e11c6d..a94b307 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -526,20 +526,6 @@
     }
 
     /**
-     * Check to see if vold already has the password.
-     * Note that this also clears vold's copy of the password.
-     * @return Whether the vold password matches or not.
-     */
-    public boolean checkVoldPassword(int userId) {
-        try {
-            return getLockSettings().checkVoldPassword(userId);
-        } catch (RemoteException re) {
-            Log.e(TAG, "failed to check vold password", re);
-            return false;
-        }
-    }
-
-    /**
      * Returns the password history hash factor, needed to check new password against password
      * history with {@link #checkPasswordHistory(byte[], byte[], int)}
      */
@@ -722,38 +708,14 @@
         return true;
     }
 
-    private void updateCryptoUserInfo(int userId) {
-        if (userId != UserHandle.USER_SYSTEM) {
-            return;
-        }
-
-        final String ownerInfo = isOwnerInfoEnabled(userId) ? getOwnerInfo(userId) : "";
-
-        IBinder service = ServiceManager.getService("mount");
-        if (service == null) {
-            Log.e(TAG, "Could not find the mount service to update the user info");
-            return;
-        }
-
-        IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
-        try {
-            Log.d(TAG, "Setting owner info");
-            storageManager.setField(StorageManager.OWNER_INFO_KEY, ownerInfo);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error changing user info", e);
-        }
-    }
-
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public void setOwnerInfo(String info, int userId) {
         setString(LOCK_SCREEN_OWNER_INFO, info, userId);
-        updateCryptoUserInfo(userId);
     }
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public void setOwnerInfoEnabled(boolean enabled, int userId) {
         setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId);
-        updateCryptoUserInfo(userId);
     }
 
     @UnsupportedAppUsage
@@ -808,17 +770,6 @@
     }
 
     /**
-     * Clears the encryption password.
-     */
-    public void clearEncryptionPassword() {
-        try {
-            getLockSettings().updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Couldn't clear encryption password");
-        }
-    }
-
-    /**
      * Retrieves the quality mode for {@code userHandle}.
      * @see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)
      *
@@ -843,7 +794,7 @@
      */
     public void setSeparateProfileChallengeEnabled(int userHandle, boolean enabled,
             LockscreenCredential profilePassword) {
-        if (!isCredentialSharedWithParent(userHandle)) {
+        if (!isCredentialSharableWithParent(userHandle)) {
             return;
         }
         try {
@@ -859,7 +810,7 @@
      * Returns true if {@code userHandle} is a managed profile with separate challenge.
      */
     public boolean isSeparateProfileChallengeEnabled(int userHandle) {
-        return isCredentialSharedWithParent(userHandle) && hasSeparateChallenge(userHandle);
+        return isCredentialSharableWithParent(userHandle) && hasSeparateChallenge(userHandle);
     }
 
     /**
@@ -884,8 +835,8 @@
         return info != null && info.isManagedProfile();
     }
 
-    private boolean isCredentialSharedWithParent(int userHandle) {
-        return getUserManager(userHandle).isCredentialSharedWithParent();
+    private boolean isCredentialSharableWithParent(int userHandle) {
+        return getUserManager(userHandle).isCredentialSharableWithParent();
     }
 
     /**
@@ -1042,24 +993,6 @@
      */
     public void setVisiblePatternEnabled(boolean enabled, int userId) {
         setBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, enabled, userId);
-
-        // Update for crypto if owner
-        if (userId != UserHandle.USER_SYSTEM) {
-            return;
-        }
-
-        IBinder service = ServiceManager.getService("mount");
-        if (service == null) {
-            Log.e(TAG, "Could not find the mount service to update the user info");
-            return;
-        }
-
-        IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
-        try {
-            storageManager.setField(StorageManager.PATTERN_VISIBLE_KEY, enabled ? "1" : "0");
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error changing pattern visible state", e);
-        }
     }
 
     public boolean isVisiblePatternEverChosen(int userId) {
@@ -1070,23 +1003,7 @@
      * Set whether the visible password is enabled for cryptkeeper screen.
      */
     public void setVisiblePasswordEnabled(boolean enabled, int userId) {
-        // Update for crypto if owner
-        if (userId != UserHandle.USER_SYSTEM) {
-            return;
-        }
-
-        IBinder service = ServiceManager.getService("mount");
-        if (service == null) {
-            Log.e(TAG, "Could not find the mount service to update the user info");
-            return;
-        }
-
-        IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
-        try {
-            storageManager.setField(StorageManager.PASSWORD_VISIBLE_KEY, enabled ? "1" : "0");
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error changing password visible state", e);
-        }
+        // No longer does anything.
     }
 
     /**
@@ -1204,7 +1121,7 @@
     public List<ComponentName> getEnabledTrustAgents(int userId) {
         String serialized = getString(ENABLED_TRUST_AGENTS, userId);
         if (TextUtils.isEmpty(serialized)) {
-            return null;
+            return new ArrayList<ComponentName>();
         }
         String[] split = serialized.split(",");
         ArrayList<ComponentName> activeTrustAgents = new ArrayList<ComponentName>(split.length);
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 2b6b933..01cec77 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -45,6 +45,7 @@
 import android.util.IntArray;
 import android.util.Log;
 import android.util.SparseArray;
+import android.util.TypedValue;
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 import android.view.RenderNodeAnimator;
@@ -82,10 +83,12 @@
     private static final int DOT_ACTIVATION_DURATION_MILLIS = 50;
     private static final int DOT_RADIUS_INCREASE_DURATION_MILLIS = 96;
     private static final int DOT_RADIUS_DECREASE_DURATION_MILLIS = 192;
+    private static final float MIN_DOT_HIT_FACTOR = 0.2f;
     private final CellState[][] mCellStates;
 
     private final int mDotSize;
     private final int mDotSizeActivated;
+    private final float mDotHitFactor;
     private final int mPathWidth;
 
     private boolean mDrawingProfilingStarted = false;
@@ -143,12 +146,11 @@
     private boolean mPatternInProgress = false;
     private boolean mFadePattern = true;
 
-    private float mHitFactor = 0.6f;
-
     @UnsupportedAppUsage
     private float mSquareWidth;
     @UnsupportedAppUsage
     private float mSquareHeight;
+    private float mDotHitRadius;
     private final LinearGradient mFadeOutGradientShader;
 
     private final Path mCurrentPath = new Path();
@@ -164,8 +166,7 @@
 
     private final Interpolator mFastOutSlowInInterpolator;
     private final Interpolator mLinearOutSlowInInterpolator;
-    private PatternExploreByTouchHelper mExploreByTouchHelper;
-    private AudioManager mAudioManager;
+    private final PatternExploreByTouchHelper mExploreByTouchHelper;
 
     private Drawable mSelectedDrawable;
     private Drawable mNotSelectedDrawable;
@@ -349,6 +350,9 @@
         mDotSize = getResources().getDimensionPixelSize(R.dimen.lock_pattern_dot_size);
         mDotSizeActivated = getResources().getDimensionPixelSize(
                 R.dimen.lock_pattern_dot_size_activated);
+        TypedValue outValue = new TypedValue();
+        getResources().getValue(R.dimen.lock_pattern_dot_hit_factor, outValue, true);
+        mDotHitFactor = Math.max(Math.min(outValue.getFloat(), 1f), MIN_DOT_HIT_FACTOR);
 
         mUseLockPatternDrawable = getResources().getBoolean(R.bool.use_lock_pattern_drawable);
         if (mUseLockPatternDrawable) {
@@ -375,7 +379,6 @@
                 AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
         mExploreByTouchHelper = new PatternExploreByTouchHelper(this);
         setAccessibilityDelegate(mExploreByTouchHelper);
-        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
 
         int fadeAwayGradientWidth = getResources().getDimensionPixelSize(
                 R.dimen.lock_pattern_fade_away_gradient_width);
@@ -679,6 +682,7 @@
         final int height = h - mPaddingTop - mPaddingBottom;
         mSquareHeight = height / 3.0f;
         mExploreByTouchHelper.invalidateRoot();
+        mDotHitRadius = Math.min(mSquareHeight / 2, mSquareWidth / 2) * mDotHitFactor;
 
         if (mUseLockPatternDrawable) {
             mNotSelectedDrawable.setBounds(mPaddingLeft, mPaddingTop, width, height);
@@ -890,63 +894,30 @@
         return set;
     }
 
-    // helper method to find which cell a point maps to
+    @Nullable
     private Cell checkForNewHit(float x, float y) {
-
-        final int rowHit = getRowHit(y);
-        if (rowHit < 0) {
-            return null;
+        Cell cellHit = detectCellHit(x, y);
+        if (cellHit != null && !mPatternDrawLookup[cellHit.row][cellHit.column]) {
+            return cellHit;
         }
-        final int columnHit = getColumnHit(x);
-        if (columnHit < 0) {
-            return null;
-        }
-
-        if (mPatternDrawLookup[rowHit][columnHit]) {
-            return null;
-        }
-        return Cell.of(rowHit, columnHit);
+        return null;
     }
 
-    /**
-     * Helper method to find the row that y falls into.
-     * @param y The y coordinate
-     * @return The row that y falls in, or -1 if it falls in no row.
-     */
-    private int getRowHit(float y) {
-
-        final float squareHeight = mSquareHeight;
-        float hitSize = squareHeight * mHitFactor;
-
-        float offset = mPaddingTop + (squareHeight - hitSize) / 2f;
-        for (int i = 0; i < 3; i++) {
-
-            final float hitTop = offset + squareHeight * i;
-            if (y >= hitTop && y <= hitTop + hitSize) {
-                return i;
+    /** Helper method to find which cell a point maps to. */
+    @Nullable
+    private Cell detectCellHit(float x, float y) {
+        final float hitRadiusSquared = mDotHitRadius * mDotHitRadius;
+        for (int row = 0; row < 3; row++) {
+            for (int column = 0; column < 3; column++) {
+                float centerY = getCenterYForRow(row);
+                float centerX = getCenterXForColumn(column);
+                if ((x - centerX) * (x - centerX) + (y - centerY) * (y - centerY)
+                        < hitRadiusSquared) {
+                    return Cell.of(row, column);
+                }
             }
         }
-        return -1;
-    }
-
-    /**
-     * Helper method to find the column x fallis into.
-     * @param x The x coordinate.
-     * @return The column that x falls in, or -1 if it falls in no column.
-     */
-    private int getColumnHit(float x) {
-        final float squareWidth = mSquareWidth;
-        float hitSize = squareWidth * mHitFactor;
-
-        float offset = mPaddingLeft + (squareWidth - hitSize) / 2f;
-        for (int i = 0; i < 3; i++) {
-
-            final float hitLeft = offset + squareWidth * i;
-            if (x >= hitLeft && x <= hitLeft + hitSize) {
-                return i;
-            }
-        }
-        return -1;
+        return null;
     }
 
     @Override
@@ -1553,8 +1524,7 @@
         protected int getVirtualViewAt(float x, float y) {
             // This must use the same hit logic for the screen to ensure consistency whether
             // accessibility is on or off.
-            int id = getVirtualViewIdForHit(x, y);
-            return id;
+            return getVirtualViewIdForHit(x, y);
         }
 
         @Override
@@ -1670,12 +1640,11 @@
             final int col = ordinal % 3;
             float centerX = getCenterXForColumn(col);
             float centerY = getCenterYForRow(row);
-            float cellheight = mSquareHeight * mHitFactor * 0.5f;
-            float cellwidth = mSquareWidth * mHitFactor * 0.5f;
-            bounds.left = (int) (centerX - cellwidth);
-            bounds.right = (int) (centerX + cellwidth);
-            bounds.top = (int) (centerY - cellheight);
-            bounds.bottom = (int) (centerY + cellheight);
+            float cellHitRadius = mDotHitRadius;
+            bounds.left = (int) (centerX - cellHitRadius);
+            bounds.right = (int) (centerX + cellHitRadius);
+            bounds.top = (int) (centerY - cellHitRadius);
+            bounds.bottom = (int) (centerY + cellHitRadius);
             return bounds;
         }
 
@@ -1694,16 +1663,12 @@
          * @return VIRTUAL_BASE_VIEW_ID+id or 0 if no view was hit
          */
         private int getVirtualViewIdForHit(float x, float y) {
-            final int rowHit = getRowHit(y);
-            if (rowHit < 0) {
+            Cell cellHit = detectCellHit(x, y);
+            if (cellHit == null) {
                 return ExploreByTouchHelper.INVALID_ID;
             }
-            final int columnHit = getColumnHit(x);
-            if (columnHit < 0) {
-                return ExploreByTouchHelper.INVALID_ID;
-            }
-            boolean dotAvailable = mPatternDrawLookup[rowHit][columnHit];
-            int dotId = (rowHit * 3 + columnHit) + VIRTUAL_BASE_VIEW_ID;
+            boolean dotAvailable = mPatternDrawLookup[cellHit.row][cellHit.column];
+            int dotId = (cellHit.row * 3 + cellHit.column) + VIRTUAL_BASE_VIEW_ID;
             int view = dotAvailable ? dotId : ExploreByTouchHelper.INVALID_ID;
             if (DEBUG_A11Y) Log.v(TAG, "getVirtualViewIdForHit(" + x + "," + y + ") => "
                     + view + "avail =" + dotAvailable);
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index 9e06e33..146cb3f 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -262,7 +262,8 @@
         return createdGroup;
     }
 
-    public void removeMessage(MessagingMessage messagingMessage) {
+    public void removeMessage(MessagingMessage messagingMessage,
+            ArrayList<MessagingLinearLayout.MessagingChild> toRecycle) {
         View view = messagingMessage.getView();
         boolean wasShown = view.isShown();
         ViewGroup messageParent = (ViewGroup) view.getParent();
@@ -270,15 +271,14 @@
             return;
         }
         messageParent.removeView(view);
-        Runnable recycleRunnable = () -> {
-            messageParent.removeTransientView(view);
-            messagingMessage.recycle();
-        };
         if (wasShown && !MessagingLinearLayout.isGone(view)) {
             messageParent.addTransientView(view, 0);
-            performRemoveAnimation(view, recycleRunnable);
+            performRemoveAnimation(view, () -> {
+                messageParent.removeTransientView(view);
+                messagingMessage.recycle();
+            });
         } else {
-            recycleRunnable.run();
+            toRecycle.add(messagingMessage);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index 21ca196..9ac6ef7 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -51,7 +51,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.function.Consumer;
 
 /**
  * A custom-built layout for the Notification.MessagingStyle allows dynamic addition and removal
@@ -62,8 +61,6 @@
         implements ImageMessageConsumer, IMessagingLayout {
 
     private static final float COLOR_SHIFT_AMOUNT = 60;
-    private static final Consumer<MessagingMessage> REMOVE_MESSAGE
-            = MessagingMessage::removeMessage;
     public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
     public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
     public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
@@ -89,6 +86,7 @@
     private boolean mIsCollapsed;
     private ImageResolver mImageResolver;
     private CharSequence mConversationTitle;
+    private ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();
 
     public MessagingLayout(@NonNull Context context) {
         super(context);
@@ -212,8 +210,12 @@
         removeGroups(oldGroups);
 
         // Let's remove the remaining messages
-        mMessages.forEach(REMOVE_MESSAGE);
-        mHistoricMessages.forEach(REMOVE_MESSAGE);
+        for (MessagingMessage message : mMessages) {
+            message.removeMessage(mToRecycle);
+        }
+        for (MessagingMessage historicMessage : mHistoricMessages) {
+            historicMessage.removeMessage(mToRecycle);
+        }
 
         mMessages = messages;
         mHistoricMessages = historicMessages;
@@ -223,6 +225,12 @@
         // after groups are finalized, hide the first sender name if it's showing as the title
         mPeopleHelper.maybeHideFirstSenderName(mGroups, mIsOneToOne, mConversationTitle);
         updateImageMessages();
+
+        // Recycle everything at the end of the update, now that we know it's no longer needed.
+        for (MessagingLinearLayout.MessagingChild child : mToRecycle) {
+            child.recycle();
+        }
+        mToRecycle.clear();
     }
 
     private void updateImageMessages() {
@@ -263,18 +271,17 @@
             MessagingGroup group = oldGroups.get(i);
             if (!mGroups.contains(group)) {
                 List<MessagingMessage> messages = group.getMessages();
-                Runnable endRunnable = () -> {
-                    mMessagingLinearLayout.removeTransientView(group);
-                    group.recycle();
-                };
 
                 boolean wasShown = group.isShown();
                 mMessagingLinearLayout.removeView(group);
                 if (wasShown && !MessagingLinearLayout.isGone(group)) {
                     mMessagingLinearLayout.addTransientView(group, 0);
-                    group.removeGroupAnimated(endRunnable);
+                    group.removeGroupAnimated(() -> {
+                        mMessagingLinearLayout.removeTransientView(group);
+                        group.recycle();
+                    });
                 } else {
-                    endRunnable.run();
+                    mToRecycle.add(group);
                 }
                 mMessages.removeAll(messages);
                 mHistoricMessages.removeAll(messages);
diff --git a/core/java/com/android/internal/widget/MessagingLinearLayout.java b/core/java/com/android/internal/widget/MessagingLinearLayout.java
index cb1d387..c06f5f7 100644
--- a/core/java/com/android/internal/widget/MessagingLinearLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLinearLayout.java
@@ -365,6 +365,7 @@
         default int getExtraSpacing() {
             return 0;
         }
+        void recycle();
     }
 
     public static class LayoutParams extends MarginLayoutParams {
diff --git a/core/java/com/android/internal/widget/MessagingMessage.java b/core/java/com/android/internal/widget/MessagingMessage.java
index 8c84379..2cc0d23 100644
--- a/core/java/com/android/internal/widget/MessagingMessage.java
+++ b/core/java/com/android/internal/widget/MessagingMessage.java
@@ -20,6 +20,7 @@
 import android.app.Notification;
 import android.view.View;
 
+import java.util.ArrayList;
 import java.util.Objects;
 
 /**
@@ -96,8 +97,8 @@
         return sameAs(message.getMessage());
     }
 
-    default void removeMessage() {
-        getGroup().removeMessage(this);
+    default void removeMessage(ArrayList<MessagingLinearLayout.MessagingChild> toRecycle) {
+        getGroup().removeMessage(this, toRecycle);
     }
 
     default void setMessagingGroup(MessagingGroup group) {
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index b1846d2..cc7e9d9 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -435,15 +435,15 @@
     }
 
     /** Get privapp permission allowlist for an apk-in-apex. */
-    public ArraySet<String> getApexPrivAppPermissions(String module, String packageName) {
-        return mApexPrivAppPermissions.getOrDefault(module, EMPTY_PERMISSIONS)
-                .get(packageName);
+    public ArraySet<String> getApexPrivAppPermissions(String apexName, String apkPackageName) {
+        return mApexPrivAppPermissions.getOrDefault(apexName, EMPTY_PERMISSIONS)
+                .get(apkPackageName);
     }
 
     /** Get privapp permissions denylist for an apk-in-apex. */
-    public ArraySet<String> getApexPrivAppDenyPermissions(String module, String packageName) {
-        return mApexPrivAppDenyPermissions.getOrDefault(module, EMPTY_PERMISSIONS)
-                .get(packageName);
+    public ArraySet<String> getApexPrivAppDenyPermissions(String apexName, String apkPackageName) {
+        return mApexPrivAppDenyPermissions.getOrDefault(apexName, EMPTY_PERMISSIONS)
+                .get(apkPackageName);
     }
 
     public ArraySet<String> getVendorPrivAppPermissions(String packageName) {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 4aa00f6..3a76745 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -361,7 +361,7 @@
                 "libwuffs_mirror_release_c",
             ],
         },
-        linux_glibc: {
+        host_linux: {
             srcs: [
                 "android_content_res_ApkAssets.cpp",
                 "android_database_CursorWindow.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index eedf7fa..eba6cca 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -1567,6 +1567,7 @@
         REG_JNI(register_android_graphics_classes),
         REG_JNI(register_android_graphics_BLASTBufferQueue),
         REG_JNI(register_android_graphics_GraphicBuffer),
+        REG_JNI(register_android_graphics_GraphicsStatsService),
         REG_JNI(register_android_graphics_SurfaceTexture),
         REG_JNI(register_android_database_CursorWindow),
         REG_JNI(register_android_database_SQLiteConnection),
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index f453d1f..db92310 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -23,6 +23,7 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/Log.h>
 #include <binder/IPCThreadState.h>
+#include <ftl/cast.h>
 #include <gui/SurfaceControl.h>
 #include <gui/WindowInfo.h>
 #include <nativehelper/JNIHelp.h>
@@ -63,16 +64,11 @@
     jfieldID surfaceInset;
     jfieldID scaleFactor;
     jfieldID touchableRegion;
-    jfieldID visible;
-    jfieldID focusable;
-    jfieldID hasWallpaper;
-    jfieldID paused;
-    jfieldID trustedOverlay;
     jfieldID touchOcclusionMode;
     jfieldID ownerPid;
     jfieldID ownerUid;
     jfieldID packageName;
-    jfieldID inputFeatures;
+    jfieldID inputConfig;
     jfieldID displayId;
     jfieldID replaceTouchableRegionWithCrop;
     WeakRefHandleField touchableRegionSurfaceControl;
@@ -162,64 +158,8 @@
     mInfo.layoutParamsFlags = flags;
     mInfo.layoutParamsType = type;
 
-    using InputConfig = gui::WindowInfo::InputConfig;
-    // Determine the value for each of the InputConfig flags. We rely on a switch statement and
-    // -Wswitch-enum to give us a build error if we forget to explicitly handle an InputConfig flag.
-    mInfo.inputConfig = InputConfig::NONE;
-    InputConfig enumerationStart = InputConfig::NONE;
-    switch (enumerationStart) {
-        case InputConfig::NONE:
-            FALLTHROUGH_INTENDED;
-        case InputConfig::NOT_VISIBLE:
-            if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.visible) == JNI_FALSE) {
-                mInfo.inputConfig |= InputConfig::NOT_VISIBLE;
-            }
-            FALLTHROUGH_INTENDED;
-        case InputConfig::NOT_FOCUSABLE:
-            if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.focusable) == JNI_FALSE) {
-                mInfo.inputConfig |= InputConfig::NOT_FOCUSABLE;
-            }
-            FALLTHROUGH_INTENDED;
-        case InputConfig::NOT_TOUCHABLE:
-            if (flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
-                mInfo.inputConfig |= InputConfig::NOT_TOUCHABLE;
-            }
-            FALLTHROUGH_INTENDED;
-        case InputConfig::PREVENT_SPLITTING:
-            if (!flags.test(WindowInfo::Flag::SPLIT_TOUCH)) {
-                mInfo.inputConfig |= InputConfig::PREVENT_SPLITTING;
-            }
-            FALLTHROUGH_INTENDED;
-        case InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER:
-            if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.hasWallpaper) == JNI_TRUE) {
-                mInfo.inputConfig |= InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER;
-            }
-            FALLTHROUGH_INTENDED;
-        case InputConfig::IS_WALLPAPER:
-            if (type == WindowInfo::Type::WALLPAPER) {
-                mInfo.inputConfig |= InputConfig::IS_WALLPAPER;
-            }
-            FALLTHROUGH_INTENDED;
-        case InputConfig::PAUSE_DISPATCHING:
-            if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.paused) == JNI_TRUE) {
-                mInfo.inputConfig |= InputConfig::PAUSE_DISPATCHING;
-            }
-            FALLTHROUGH_INTENDED;
-        case InputConfig::TRUSTED_OVERLAY:
-            if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.trustedOverlay) == JNI_TRUE) {
-                mInfo.inputConfig |= InputConfig::TRUSTED_OVERLAY;
-            }
-            FALLTHROUGH_INTENDED;
-        case InputConfig::WATCH_OUTSIDE_TOUCH:
-            if (flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
-                mInfo.inputConfig |= InputConfig::WATCH_OUTSIDE_TOUCH;
-            }
-            FALLTHROUGH_INTENDED;
-        case InputConfig::SLIPPERY:
-            if (flags.test(WindowInfo::Flag::SLIPPERY)) {
-                mInfo.inputConfig |= InputConfig::SLIPPERY;
-            }
-    }
+    mInfo.inputConfig = static_cast<gui::WindowInfo::InputConfig>(
+            env->GetIntField(obj, gInputWindowHandleClassInfo.inputConfig));
 
     mInfo.touchOcclusionMode = static_cast<TouchOcclusionMode>(
             env->GetIntField(obj, gInputWindowHandleClassInfo.touchOcclusionMode));
@@ -228,8 +168,6 @@
     mInfo.ownerUid = env->GetIntField(obj,
             gInputWindowHandleClassInfo.ownerUid);
     mInfo.packageName = getStringField(env, obj, gInputWindowHandleClassInfo.packageName, "<null>");
-    mInfo.inputFeatures = static_cast<WindowInfo::Feature>(
-            env->GetIntField(obj, gInputWindowHandleClassInfo.inputFeatures));
     mInfo.displayId = env->GetIntField(obj,
             gInputWindowHandleClassInfo.displayId);
 
@@ -359,17 +297,6 @@
     env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.touchableRegion,
                         regionObj.get());
 
-    using InputConfig = gui::WindowInfo::InputConfig;
-    env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.visible,
-                         !windowInfo.inputConfig.test(InputConfig::NOT_VISIBLE));
-    env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.focusable,
-                         !windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::NOT_FOCUSABLE));
-    env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.hasWallpaper,
-                         windowInfo.inputConfig.test(InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER));
-    env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.paused,
-                         windowInfo.inputConfig.test(InputConfig::PAUSE_DISPATCHING));
-    env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.trustedOverlay,
-                         windowInfo.inputConfig.test(InputConfig::TRUSTED_OVERLAY));
     env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.touchOcclusionMode,
                      static_cast<int32_t>(windowInfo.touchOcclusionMode));
     env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.ownerPid, windowInfo.ownerPid);
@@ -377,8 +304,11 @@
     ScopedLocalRef<jstring> packageName(env, env->NewStringUTF(windowInfo.packageName.data()));
     env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.packageName,
                         packageName.get());
-    env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.inputFeatures,
-                     static_cast<int32_t>(windowInfo.inputFeatures.get()));
+
+    const auto inputConfig = windowInfo.inputConfig.get();
+    static_assert(sizeof(inputConfig) == sizeof(int32_t));
+    env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.inputConfig,
+                     static_cast<int32_t>(inputConfig));
 
     float transformVals[9];
     for (int i = 0; i < 9; i++) {
@@ -481,19 +411,6 @@
     GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegion, clazz,
             "touchableRegion", "Landroid/graphics/Region;");
 
-    GET_FIELD_ID(gInputWindowHandleClassInfo.visible, clazz,
-            "visible", "Z");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.focusable, clazz, "focusable", "Z");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.hasWallpaper, clazz,
-            "hasWallpaper", "Z");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.paused, clazz,
-            "paused", "Z");
-
-    GET_FIELD_ID(gInputWindowHandleClassInfo.trustedOverlay, clazz, "trustedOverlay", "Z");
-
     GET_FIELD_ID(gInputWindowHandleClassInfo.touchOcclusionMode, clazz, "touchOcclusionMode", "I");
 
     GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz,
@@ -505,8 +422,7 @@
     GET_FIELD_ID(gInputWindowHandleClassInfo.packageName, clazz, "packageName",
                  "Ljava/lang/String;");
 
-    GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
-            "inputFeatures", "I");
+    GET_FIELD_ID(gInputWindowHandleClassInfo.inputConfig, clazz, "inputConfig", "I");
 
     GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz,
             "displayId", "I");
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 5b7092c..7bc6905 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -895,7 +895,7 @@
 
   // pthread_setname_np fails rather than truncating long strings.
   char buf[16];       // MAX_TASK_COMM_LEN=16 is hard-coded into bionic
-  strlcpy(buf, name_start_ptr, sizeof(buf) - 1);
+  strlcpy(buf, name_start_ptr, sizeof(buf));
   errno = pthread_setname_np(pthread_self(), buf);
   if (errno != 0) {
     ALOGW("Unable to set the name of current thread to '%s': %s", buf, strerror(errno));
diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
index 248db76..679a4f0 100644
--- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
@@ -34,6 +34,7 @@
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/system_properties.h>
 #include <vector>
 
 namespace android {
@@ -43,10 +44,10 @@
 using android::zygote::ZygoteFailure;
 
 // WARNING: Knows a little about the wire protocol used to communicate with Zygote.
-// TODO: Fix error handling.
 
-constexpr size_t MAX_COMMAND_BYTES = 12200;
-constexpr size_t NICE_NAME_BYTES = 50;
+// Commands and nice names have large arbitrary size limits to avoid dynamic memory allocation.
+constexpr size_t MAX_COMMAND_BYTES = 32768;
+constexpr size_t NICE_NAME_BYTES = 128;
 
 // A buffer optionally bundled with a file descriptor from which we can fill it.
 // Does not own the file descriptor; destroying a NativeCommandBuffer does not
@@ -190,6 +191,9 @@
         size_t copy_len = std::min(name_len, NICE_NAME_BYTES - 1);
         memcpy(mNiceName, arg_start + NN_LENGTH, copy_len);
         mNiceName[copy_len] = '\0';
+        if (haveWrapProperty()) {
+          return false;
+        }
         continue;
       }
       if (arg_end - arg_start == IW_LENGTH
@@ -222,6 +226,8 @@
         }
         saw_setgid = true;
       }
+      // ro.debuggable can be handled entirely in the child unless --invoke-with is also specified.
+      // Thus we do not need to check it here.
     }
     return saw_runtime_args && saw_setuid && saw_setgid;
   }
@@ -249,6 +255,14 @@
   }
 
  private:
+  bool haveWrapProperty() {
+    static const char* WRAP = "wrap.";
+    static const size_t WRAP_LENGTH = strlen(WRAP);
+    char propNameBuf[WRAP_LENGTH + NICE_NAME_BYTES];
+    strcpy(propNameBuf, WRAP);
+    strlcpy(propNameBuf + WRAP_LENGTH, mNiceName, NICE_NAME_BYTES);
+    return __system_property_find(propNameBuf) != nullptr;
+  }
   // Picky version of atoi(). No sign or unexpected characters allowed. Return -1 on failure.
   static int digitsVal(char* start, char* end) {
     int result = 0;
@@ -269,12 +283,10 @@
   uint32_t mNext;  // Index of first character past last line returned by readLine.
   int32_t mLinesLeft;  // Lines in current command that haven't yet been read.
   int mFd;  // Open file descriptor from which we can read more. -1 if none.
-  char mNiceName[NICE_NAME_BYTES];
+  char mNiceName[NICE_NAME_BYTES];  // Always null terminated.
   char mBuffer[MAX_COMMAND_BYTES];
 };
 
-static_assert(sizeof(NativeCommandBuffer) < 3 * 4096);
-
 static int buffersAllocd(0);
 
 // Get a new NativeCommandBuffer. Can only be called once between freeNativeBuffer calls,
@@ -374,6 +386,7 @@
             jint minUid,
             jstring managed_nice_name) {
 
+  ALOGI("Entering forkRepeatedly native zygote loop");
   NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer);
   int session_socket = n_buffer->getFd();
   std::vector<int> session_socket_fds {session_socket};
@@ -402,7 +415,8 @@
   socklen_t cred_size = sizeof credentials;
   if (getsockopt(n_buffer->getFd(), SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1
       || cred_size != sizeof credentials) {
-    fail_fn_1(CREATE_ERROR("ForkMany failed to get initial credentials, %s", strerror(errno)));
+    fail_fn_1(CREATE_ERROR("ForkRepeatedly failed to get initial credentials, %s",
+                           strerror(errno)));
   }
 
   bool first_time = true;
diff --git a/core/proto/android/os/batteryusagestats.proto b/core/proto/android/os/batteryusagestats.proto
index cc90e05..856bc83 100644
--- a/core/proto/android/os/batteryusagestats.proto
+++ b/core/proto/android/os/batteryusagestats.proto
@@ -76,6 +76,7 @@
                 FOREGROUND = 1;
                 BACKGROUND = 2;
                 FOREGROUND_SERVICE = 3;
+                CACHED = 4;
             }
 
             optional ProcessState process_state = 2;
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 51e150e..57026d9 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -48,7 +48,6 @@
 import "frameworks/base/core/proto/android/service/diskstats.proto";
 import "frameworks/base/core/proto/android/service/dropbox.proto";
 import "frameworks/base/core/proto/android/service/graphicsstats.proto";
-import "frameworks/base/core/proto/android/service/netstats.proto";
 import "frameworks/base/core/proto/android/service/notification.proto";
 import "frameworks/base/core/proto/android/service/package.proto";
 import "frameworks/base/core/proto/android/service/print.proto";
@@ -62,7 +61,8 @@
 import "frameworks/base/core/proto/android/privacy.proto";
 import "frameworks/base/core/proto/android/section.proto";
 import "frameworks/base/proto/src/ipconnectivity.proto";
-import "packages/modules/Permission/service/proto/com/android/role/roleservice.proto";
+import "packages/modules/Connectivity/framework/proto/netstats.proto";
+import "packages/modules/Permission/service/proto/role_service.proto";
 
 package android.os;
 
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 3929027..0ade093 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -53,6 +53,7 @@
     optional int32 last_orientation = 8 [(.android.typedef) = "android.content.pm.ActivityInfo.ScreenOrientation", deprecated=true];
     optional int32 focused_display_id = 9;
     optional bool hard_keyboard_available = 10;
+    optional bool window_frames_valid = 11;
 }
 
 /* represents RootWindowContainer object */
diff --git a/core/proto/android/service/netstats.proto b/core/proto/android/service/netstats.proto
deleted file mode 100644
index ba2b6d6b..0000000
--- a/core/proto/android/service/netstats.proto
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.service;
-
-option java_multiple_files = true;
-option java_outer_classname = "NetworkStatsServiceProto";
-
-// Represents dumpsys from NetworkStatsService (netstats).
-message NetworkStatsServiceDumpProto {
-    repeated NetworkInterfaceProto active_interfaces = 1;
-
-    repeated NetworkInterfaceProto active_uid_interfaces = 2;
-
-    // Device level network stats, which may include non-IP layer traffic.
-    optional NetworkStatsRecorderProto dev_stats = 3;
-
-    // IP-layer traffic stats.
-    optional NetworkStatsRecorderProto xt_stats = 4;
-
-    // Per-UID network stats.
-    optional NetworkStatsRecorderProto uid_stats = 5;
-
-    // Per-UID, per-tag network stats, excluding the default tag (i.e. tag=0).
-    optional NetworkStatsRecorderProto uid_tag_stats = 6;
-}
-
-// Corresponds to NetworkStatsService.mActiveIfaces/mActiveUidIfaces.
-message NetworkInterfaceProto {
-    // Name of the network interface (eg: wlan).
-    optional string interface = 1;
-
-    optional NetworkIdentitySetProto identities = 2;
-}
-
-// Corresponds to NetworkIdentitySet.
-message NetworkIdentitySetProto {
-    repeated NetworkIdentityProto identities = 1;
-}
-
-// Corresponds to NetworkIdentity.
-message NetworkIdentityProto {
-    // Constants from ConnectivityManager.TYPE_*.
-    optional int32 type = 1;
-
-    optional bool roaming = 4;
-
-    optional bool metered = 5;
-
-    optional bool default_network = 6;
-
-    optional int32 oem_managed_network = 7;
-}
-
-// Corresponds to NetworkStatsRecorder.
-message NetworkStatsRecorderProto {
-    optional int64 pending_total_bytes = 1;
-
-    optional NetworkStatsCollectionProto complete_history = 2;
-}
-
-// Corresponds to NetworkStatsCollection.
-message NetworkStatsCollectionProto {
-    repeated NetworkStatsCollectionStatsProto stats = 1;
-}
-
-// Corresponds to NetworkStatsCollection.mStats.
-message NetworkStatsCollectionStatsProto {
-    optional NetworkStatsCollectionKeyProto key = 1;
-
-    optional NetworkStatsHistoryProto history = 2;
-}
-
-// Corresponds to NetworkStatsCollection.Key.
-message NetworkStatsCollectionKeyProto {
-    optional NetworkIdentitySetProto identity = 1;
-
-    optional int32 uid = 2;
-
-    optional int32 set = 3;
-
-    optional int32 tag = 4;
-}
-
-// Corresponds to NetworkStatsHistory.
-message NetworkStatsHistoryProto {
-    // Duration for this bucket in milliseconds.
-    optional int64 bucket_duration_ms = 1;
-
-    repeated NetworkStatsHistoryBucketProto buckets = 2;
-}
-
-// Corresponds to each bucket in NetworkStatsHistory.
-message NetworkStatsHistoryBucketProto {
-    // Bucket start time in milliseconds since epoch.
-    optional int64 bucket_start_ms = 1;
-
-    optional int64 rx_bytes = 2;
-
-    optional int64 rx_packets = 3;
-
-    optional int64 tx_bytes = 4;
-
-    optional int64 tx_packets = 5;
-
-    optional int64 operations = 6;
-}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 434222a..729bc82 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1030,10 +1030,10 @@
       targetSdkVersion}</a> of {@link android.os.Build.VERSION_CODES#S} or lower, this permission
       must not be used and the READ_EXTERNAL_STORAGE permission must be used instead.
      <p>Protection level: dangerous -->
-    <permission android:name="android.permission.READ_MEDIA_IMAGE"
+    <permission android:name="android.permission.READ_MEDIA_IMAGES"
                 android:permissionGroup="android.permission-group.UNDEFINED"
-                android:label="@string/permlab_readMediaImage"
-                android:description="@string/permdesc_readMediaImage"
+                android:label="@string/permlab_readMediaImages"
+                android:description="@string/permdesc_readMediaImages"
                 android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write to external storage.
@@ -1901,11 +1901,21 @@
     <!-- Allows applications to enable/disable wifi auto join. This permission
          is used to let OEMs grant their trusted app access to a subset of privileged wifi APIs
          to improve wifi performance.
-         <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+         @deprecated will be replaced with MANAGE_WIFI_NETWORK_SELECTION -->
     <permission android:name="android.permission.MANAGE_WIFI_AUTO_JOIN"
                 android:protectionLevel="signature|privileged|knownSigner"
                 android:knownCerts="@array/wifi_known_signers" />
 
+    <!-- This permission is used to let OEMs grant their trusted app access to a subset of
+         privileged wifi APIs to improve wifi performance. Allows applications to manage
+         Wi-Fi network selection related features such as enable or disable global auto-join,
+         modify connectivity scan intervals, and approve Wi-Fi Direct connections.
+         <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.MANAGE_WIFI_NETWORK_SELECTION"
+                android:protectionLevel="signature|privileged|knownSigner"
+                android:knownCerts="@array/wifi_known_signers" />
+
     <!-- Allows applications to get notified when a Wi-Fi interface request cannot
          be satisfied without tearing down one or more other interfaces, and provide a decision
          whether to approve the request or reject it.
@@ -2937,7 +2947,7 @@
     <!-- @SystemApi @hide Allows an application to set the profile owners and the device owner.
          This permission is not available to third party applications.-->
     <permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS"
-        android:protectionLevel="signature|role|setup"
+        android:protectionLevel="signature|role"
         android:label="@string/permlab_manageProfileAndDeviceOwners"
         android:description="@string/permdesc_manageProfileAndDeviceOwners" />
 
@@ -2946,6 +2956,10 @@
     <permission android:name="android.permission.QUERY_ADMIN_POLICY"
                 android:protectionLevel="signature|role" />
 
+    <!-- @SystemApi @hide Allows an application to set a device owner on retail demo devices.-->
+    <permission android:name="android.permission.PROVISION_DEMO_DEVICE"
+                android:protectionLevel="signature|setup" />
+
     <!-- @TestApi @hide Allows an application to reset the record of previous system update freeze
          periods. -->
     <permission android:name="android.permission.CLEAR_FREEZE_PERIOD"
@@ -3085,7 +3099,7 @@
 
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SYSTEM_APPLICATION_OVERLAY"
-                android:protectionLevel="signature|recents|role"/>
+                android:protectionLevel="signature|recents|role|installer"/>
 
     <!-- @deprecated Use {@link android.Manifest.permission#REQUEST_COMPANION_RUN_IN_BACKGROUND}
          @hide
@@ -3714,15 +3728,26 @@
         android:protectionLevel="signature|privileged" />
 
     <!-- ========================================= -->
-    <!-- Permissions for SupplementalApi -->
+    <!-- Permissions for AdServices -->
     <!-- ========================================= -->
     <eat-comment />
 
-    <!-- TODO(b/213488783): Update with correct names. -->
-    <!-- Allows an application to access SupplementalApis. -->
-    <permission android:name="android.permission.ACCESS_SUPPLEMENTAL_APIS"
-        android:label="@string/permlab_accessSupplementalApi"
-        android:description="@string/permdesc_accessSupplementalApi"
+    <!-- Allows an application to access AdServices Topics API. -->
+    <permission android:name="android.permission.ACCESS_ADSERVICES_TOPICS"
+        android:label="@string/permlab_accessAdServicesTopics"
+        android:description="@string/permdesc_accessAdServicesTopics"
+        android:protectionLevel="normal" />
+
+    <!-- Allows an application to access AdServices Attribution APIs. -->
+    <permission android:name="android.permission.ACCESS_ADSERVICES_ATTRIBUTION"
+        android:label="@string/permlab_accessAdServicesAttribution"
+        android:description="@string/permdesc_accessAdServicesAttribution"
+        android:protectionLevel="normal" />
+
+    <!-- Allows an application to access AdServices Custom Audiences APIs. -->
+    <permission android:name="android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCES"
+        android:label="@string/permlab_accessAdServicesCustomAudiences"
+        android:description="@string/permdesc_accessAdServicesCustomAudiences"
         android:protectionLevel="normal" />
 
     <!-- ==================================== -->
@@ -6026,10 +6051,10 @@
     <permission android:name="android.permission.MANAGE_APPOPS"
                 android:protectionLevel="signature" />
 
-    <!-- @hide Permission that allows background clipboard access.
-         <p>Not for use by third-party applications. -->
+    <!-- @SystemApi Permission that allows background clipboard access.
+         @hide Not for use by third-party applications. -->
     <permission android:name="android.permission.READ_CLIPBOARD_IN_BACKGROUND"
-        android:protectionLevel="signature" />
+        android:protectionLevel="internal|role" />
     <!-- @hide Permission that suppresses the notification when the clipboard is accessed.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SUPPRESS_CLIPBOARD_ACCESS_NOTIFICATION"
@@ -6135,10 +6160,10 @@
     <!-- Allows input events to be monitored. Very dangerous!  @hide -->
     <permission android:name="android.permission.MONITOR_INPUT"
                 android:protectionLevel="signature|recents" />
-    <!-- Allows the use of FLAG_SLIPPERY, which permits touch events to slip from the current
-         window to the window where the touch currently is on top of.  @hide -->
+    <!-- @SystemApi Allows the use of FLAG_SLIPPERY, which permits touch events to slip from the
+         current window to the window where the touch currently is on top of.  @hide -->
     <permission android:name="android.permission.ALLOW_SLIPPERY_TOUCHES"
-                android:protectionLevel="signature|recents" />
+                android:protectionLevel="signature|privileged|recents|role" />
     <!--  Allows the caller to change the associations between input devices and displays.
         Very dangerous! @hide -->
     <permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY"
@@ -6395,6 +6420,12 @@
     <permission android:name="android.permission.WRITE_SECURITY_LOG"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Allows an UID to be visible to the application based on an interaction between the
+         two apps. This permission is not intended to be held by apps.
+         @hide @TestApi  -->
+    <permission android:name="android.permission.MAKE_UID_VISIBLE"
+                android:protectionLevel="signature" />
+
     <!-- Attribution for Geofencing service. -->
     <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
     <!-- Attribution for Country Detector. -->
@@ -6653,10 +6684,9 @@
                   android:exported="false">
         </activity>
 
-        <activity android:name="com.android.server.logcat.LogAccessConfirmationActivity"
-                  android:theme="@style/Theme.Dialog.Confirmation"
+        <activity android:name="com.android.server.logcat.LogAccessDialogActivity"
+                  android:theme="@style/Theme.DeviceDefault.Dialog.Alert.DayNight"
                   android:excludeFromRecents="true"
-                  android:process=":ui"
                   android:label="@string/log_access_confirmation_title"
                   android:exported="false">
         </activity>
@@ -6815,6 +6845,13 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name="com.android.server.sdksandbox.SdkSandboxVerifierReceiver"
+                 android:exported="false">
+            <intent-filter>
+                <action android:name="android.intent.action.PACKAGE_NEEDS_VERIFICATION"/>
+            </intent-filter>
+        </receiver>
+
         <service android:name="android.hardware.location.GeofenceHardwareService"
             android:permission="android.permission.LOCATION_HARDWARE"
             android:exported="false" />
diff --git a/core/res/OWNERS b/core/res/OWNERS
index 4bea4d5..ca8b3f8 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -26,6 +26,10 @@
 tsuji@google.com
 yamasani@google.com
 
+# Resources finalization
+per-file res/xml/public-staging.xml = file:/tools/aapt2/OWNERS
+per-file res/xml/public-final.xml = file:/tools/aapt2/OWNERS
+
 # Multiuser
 per-file res/xml/config_user_types.xml = file:/MULTIUSER_OWNERS
 
diff --git a/core/res/res/anim-ldrtl/activity_close_enter.xml b/core/res/res/anim-ldrtl/activity_close_enter.xml
new file mode 100644
index 0000000..6a699e7
--- /dev/null
+++ b/core/res/res/anim-ldrtl/activity_close_enter.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false">
+
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="0"
+        android:duration="450" />
+
+    <translate
+        android:fromXDelta="10%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+
+    <extend
+        android:fromExtendLeft="10%"
+        android:fromExtendTop="0"
+        android:fromExtendRight="0"
+        android:fromExtendBottom="0"
+        android:toExtendLeft="10%"
+        android:toExtendTop="0"
+        android:toExtendRight="0"
+        android:toExtendBottom="0"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/activity_close_exit.xml b/core/res/res/anim-ldrtl/activity_close_exit.xml
new file mode 100644
index 0000000..06a0d69
--- /dev/null
+++ b/core/res/res/anim-ldrtl/activity_close_exit.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false">
+
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="0.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="35"
+        android:duration="83" />
+
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="-10%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+
+    <extend
+        android:fromExtendLeft="0"
+        android:fromExtendTop="0"
+        android:fromExtendRight="10%"
+        android:fromExtendBottom="0"
+        android:toExtendLeft="0"
+        android:toExtendTop="0"
+        android:toExtendRight="10%"
+        android:toExtendBottom="0"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+</set>
diff --git a/core/res/res/anim-ldrtl/activity_open_enter.xml b/core/res/res/anim-ldrtl/activity_open_enter.xml
new file mode 100644
index 0000000..7b18294
--- /dev/null
+++ b/core/res/res/anim-ldrtl/activity_open_enter.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+/*
+** 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false">
+
+    <alpha
+        android:fromAlpha="0"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="50"
+        android:duration="83" />
+
+    <translate
+        android:fromXDelta="-10%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="450" />
+
+    <extend
+        android:fromExtendLeft="0"
+        android:fromExtendTop="0"
+        android:fromExtendRight="10%"
+        android:fromExtendBottom="0"
+        android:toExtendLeft="0"
+        android:toExtendTop="0"
+        android:toExtendRight="10%"
+        android:toExtendBottom="0"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+</set>
diff --git a/core/res/res/anim-ldrtl/activity_open_exit.xml b/core/res/res/anim-ldrtl/activity_open_exit.xml
new file mode 100644
index 0000000..c29509e
--- /dev/null
+++ b/core/res/res/anim-ldrtl/activity_open_exit.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+/*
+** 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false">
+
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/standard_accelerate"
+        android:startOffset="0"
+        android:duration="450" />
+
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="10%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+
+    <extend
+        android:fromExtendLeft="10%"
+        android:fromExtendTop="0"
+        android:fromExtendRight="0"
+        android:fromExtendBottom="0"
+        android:toExtendLeft="10%"
+        android:toExtendTop="0"
+        android:toExtendRight="0"
+        android:toExtendBottom="0"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/drawable-nodpi/stat_sys_adb.xml b/core/res/res/drawable-nodpi/stat_sys_adb.xml
index f8c0451..cb4462c 100644
--- a/core/res/res/drawable-nodpi/stat_sys_adb.xml
+++ b/core/res/res/drawable-nodpi/stat_sys_adb.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2021 The Android Open Source Project
+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.
@@ -13,11 +13,78 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp" android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-  <path android:pathData="M18 9c0-.69268-.1174-1.35795-.3333-1.97699C16.8495 4.68061 14.621 3 12 3 8.68629 3 6 5.68629 6 9v3h6M6 15c0 .6927.11738 1.3579.33333 1.977C7.15047 19.3194 9.37897 21 12 21c3.3137 0 6-2.6863 6-6v-3h-6" android:strokeColor="#000000" android:strokeWidth="2" android:fillColor="#00000000"/>
-  <path android:fillColor="#000000" android:pathData="M10 7a1 1 0 1 0 0 2 1 1 0 1 0 0-2zM14 7a1 1 0 1 0 0 2 1 1 0 1 0 0-2z"/>
-  <path android:pathData="M6 3l1.5 1.5M18 3l-1.5 1.5" android:strokeColor="#000000" android:strokeWidth="2" android:fillColor="#000000"/>
+<vector android:width="24dp" android:height="24dp"
+        android:viewportWidth="24" android:viewportHeight="24"
+        xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:pathData="
+        M22.45 11.94
+        l-.58-.21
+        a1.19 1.19 0 0 1-.26-2.12
+        l.51-.34
+        a1.2 1.2 0 0 0-.83-2.19
+        l-.61.08
+        a1.2 1.2 0 0 1-1.21-1.76
+        l.29-.54
+        A1.2 1.2 0 0 0 18 3.31
+        l-.5.36
+        a1.21 1.21 0 0 1-1.9-1
+        v-.61
+        a1.2 1.2 0 0 0-2.27-.56
+        l-.26.5
+        a1.2 1.2 0 0 1-2.14 0
+        l-.28-.54
+        a1.2 1.2 0 0 0-2.27.56
+        v.61
+        a1.21 1.21 0 0 1-1.9 1
+        L6 3.31
+        a1.2 1.2 0 0 0-1.76 1.55
+        l.29.54
+        a1.2 1.2 0 0 1-1.21 1.76
+        l-.61-.08
+        a1.2 1.2 0 0 0-.83 2.19
+        l.51.34
+        a1.19 1.19 0 0 1-.26 2.12
+        l-.58.21
+        a1.21 1.21 0 0 0 .29 2.33
+        l.61.06
+        a1.2 1.2 0 0 1 .76 2
+        l-.42.46
+        a1.2 1.2 0 0 0 1.33 1.92
+        l.57-.22
+        a1.21 1.21 0 0 1 1.61 1.42
+        l-.16.59
+        a1.2 1.2 0 0 0 2.07 1.09
+        l.4-.47
+        a1.2 1.2 0 0 1 2.08.51
+        l.14.6
+        a1.2 1.2 0 0 0 2.34 0
+        l.14-.6
+        a1.2 1.2 0 0 1 2.08-.51
+        l.4.47
+        a1.2 1.2 0 0 0 2.07-1.09
+        l-.16-.59
+        a1.21 1.21 0 0 1 1.61-1.42
+        l.57.22
+        a1.2 1.2 0 0 0 1.33-1.92
+        l-.42-.46
+        a1.2 1.2 0 0 1 .76-2
+        l.61-.06
+        a1.21 1.21 0 0 0 .29-2.33
+        z
+        M12 19
+        a7 7 0 1 1 7-7 7 7 0 0 1-7 7
+        z
+        "
+        android:fillColor="#000000" />
+  <path android:pathData="
+        M9 7.75
+        a.75.75 0 1 0 0 1.5.75.75 0 1 0 0-1.5
+        z
+        M15 7.75
+        a.75.75 0 1 0 0 1.5.75.75 0 1 0 0-1.5
+        z
+        "
+        android:fillColor="#000000" />
+  <path android:strokeColor="#000000" android:strokeMiterLimit="10" android:strokeWidth="2"
+        android:pathData="M4 12h16M12 12v8" />
 </vector>
diff --git a/core/res/res/drawable/grant_permissions_buttons_bottom.xml b/core/res/res/drawable/grant_permissions_buttons_bottom.xml
new file mode 100644
index 0000000..a800f15
--- /dev/null
+++ b/core/res/res/drawable/grant_permissions_buttons_bottom.xml
@@ -0,0 +1,23 @@
+<?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">
+    <solid android:color="@android:color/system_accent1_100"/>
+    <corners android:topLeftRadius="4dp" android:topRightRadius="4dp"
+             android:bottomLeftRadius="12dp" android:bottomRightRadius="12dp"/>
+</shape>
\ No newline at end of file
diff --git a/core/res/res/drawable/grant_permissions_buttons_top.xml b/core/res/res/drawable/grant_permissions_buttons_top.xml
new file mode 100644
index 0000000..2bf803e
--- /dev/null
+++ b/core/res/res/drawable/grant_permissions_buttons_top.xml
@@ -0,0 +1,23 @@
+<?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">
+    <solid android:color="@android:color/system_accent1_100"/>
+    <corners android:topLeftRadius="12dp" android:topRightRadius="12dp"
+             android:bottomLeftRadius="4dp" android:bottomRightRadius="4dp"/>
+</shape>
\ No newline at end of file
diff --git a/core/res/res/layout/log_access_user_consent_dialog_permission.xml b/core/res/res/layout/log_access_user_consent_dialog_permission.xml
new file mode 100644
index 0000000..bd7efbd
--- /dev/null
+++ b/core/res/res/layout/log_access_user_consent_dialog_permission.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:app="http://schemas.android.com/apk/res-auto"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:layout_width="380dp"
+              android:layout_height="match_parent"
+              android:orientation="vertical"
+              android:gravity="center"
+              android:paddingLeft="24dp"
+              android:paddingRight="24dp"
+              android:paddingTop="24dp"
+              android:paddingBottom="24dp"
+              android:background="?attr/colorSurface">
+
+    <ImageView
+            android:id="@+id/log_access_image_view"
+            android:layout_width="32dp"
+            android:layout_height="32dp"
+            android:layout_marginBottom="16dp"
+            android:src="@drawable/ic_doc_document"
+            tools:layout_editor_absoluteX="148dp"
+            tools:layout_editor_absoluteY="35dp"
+            android:gravity="center" />
+
+
+    <TextView
+            android:id="@+id/log_access_dialog_title"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_marginBottom="32dp"
+            android:text="@string/log_access_confirmation_title"
+            android:textAppearance="?attr/textAppearanceLarge"
+            android:textColor="@android:color/system_neutral1_900"
+            android:gravity="center" />
+
+    <TextView
+            android:id="@+id/log_access_dialog_body"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:text="@string/log_access_confirmation_body"
+            android:textAppearance="@style/PrimaryAllowLogAccess"
+            android:gravity="center" />
+
+    <Button
+            android:id="@+id/log_access_dialog_allow_button"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:text="@string/log_access_confirmation_allow"
+            style="@style/PermissionGrantButtonTop"
+            android:layout_marginBottom="5dp"
+            android:layout_centerHorizontal="true"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentBottom="true"
+            android:clipToOutline="true"
+            android:gravity="center" />
+
+    <Button
+            android:id="@+id/log_access_dialog_deny_button"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:text="@string/log_access_confirmation_deny"
+            style="@style/PermissionGrantButtonBottom"
+            android:layout_centerHorizontal="true"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentBottom="true"
+            android:clipToOutline="true"
+            android:gravity="center" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 81a79c5..a7f2aa7 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -49,6 +49,8 @@
         android:layout_marginStart="@dimen/notification_icon_circle_start"
         android:background="@drawable/notification_icon_circle"
         android:padding="@dimen/notification_icon_circle_padding"
+        android:maxDrawableWidth="@dimen/notification_icon_circle_size"
+        android:maxDrawableHeight="@dimen/notification_icon_circle_size"
         />
 
     <!-- extends ViewGroup -->
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index c6983ae..fd787f6 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -45,6 +45,8 @@
         android:layout_marginStart="@dimen/notification_icon_circle_start"
         android:background="@drawable/notification_icon_circle"
         android:padding="@dimen/notification_icon_circle_padding"
+        android:maxDrawableWidth="@dimen/notification_icon_circle_size"
+        android:maxDrawableHeight="@dimen/notification_icon_circle_size"
         />
 
     <FrameLayout
@@ -136,7 +138,7 @@
 
         </LinearLayout>
 
-        <ImageView
+        <com.android.internal.widget.CachingIconView
             android:id="@+id/right_icon"
             android:layout_width="@dimen/notification_right_icon_size"
             android:layout_height="@dimen/notification_right_icon_size"
@@ -148,6 +150,8 @@
             android:clipToOutline="true"
             android:importantForAccessibility="no"
             android:scaleType="centerCrop"
+            android:maxDrawableWidth="@dimen/notification_right_icon_size"
+            android:maxDrawableHeight="@dimen/notification_right_icon_size"
             />
 
         <FrameLayout
diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml
index f163ed5..8b3b795 100644
--- a/core/res/res/layout/notification_template_right_icon.xml
+++ b/core/res/res/layout/notification_template_right_icon.xml
@@ -13,7 +13,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<ImageView
+<com.android.internal.widget.CachingIconView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/right_icon"
     android:layout_width="@dimen/notification_right_icon_size"
@@ -25,4 +25,6 @@
     android:clipToOutline="true"
     android:importantForAccessibility="no"
     android:scaleType="centerCrop"
+    android:maxDrawableWidth="@dimen/notification_right_icon_size"
+    android:maxDrawableHeight="@dimen/notification_right_icon_size"
     />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index da5f899..b3203ae 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5479,9 +5479,9 @@
             <enum name="none" value="0" />
             <!-- Use the least restrictive rule for line-breaking. -->
             <enum name="loose" value="1" />
-            <!-- Indicate breaking text with the most comment set of line-breaking rules. -->
+            <!-- Indicates breaking text with the most comment set of line-breaking rules. -->
             <enum name="normal" value="2" />
-            <!-- ndicates breaking text with the most strictest line-breaking rules. -->
+            <!-- Indicates breaking text with the most strictest line-breaking rules. -->
             <enum name="strict" value="3" />
         </attr>
         <!-- Specify the phrase-based line break can be used when calculating the text wrapping.-->
@@ -9807,4 +9807,12 @@
         of the supported locale. {@link android.app.LocaleConfig} -->
         <attr name="name" />
     </declare-styleable>
+
+    <!-- @hide -->
+    <declare-styleable name="CachingIconView">
+        <!-- Maximum width of displayed drawable. Drawables exceeding this size will be downsampled. -->
+        <attr name="maxDrawableWidth" format="dimension"/>
+        <!-- Maximum width of height drawable. Drawables exceeding this size will be downsampled. -->
+        <attr name="maxDrawableHeight" format="dimension"/>
+    </declare-styleable>
     </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7f16cdc..269aa1b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2335,7 +2335,7 @@
     <!-- Remote server that can provide NTP responses. -->
     <string translatable="false" name="config_ntpServer">time.android.com</string>
     <!-- Normal polling frequency in milliseconds -->
-    <integer name="config_ntpPollingInterval">86400000</integer>
+    <integer name="config_ntpPollingInterval">64800000</integer>
     <!-- Try-again polling interval in milliseconds, in case the network request failed -->
     <integer name="config_ntpPollingIntervalShorter">60000</integer>
     <!-- Number of times to try again with the shorter interval, before backing
@@ -2931,6 +2931,11 @@
     <!-- Apps that are authorized to access shared accounts, overridden by product overlays -->
     <string name="config_appsAuthorizedForSharedAccounts" translatable="false">;com.android.settings;</string>
 
+    <!-- Settings intelligence package name -->
+    <string name="config_settingsIntelligencePackageName" translatable="false">
+        com.android.settings.intelligence
+    </string>
+
     <!-- Flag indicating that the media framework should not allow changes or mute on any
          stream or global volumes. -->
     <bool name="config_useFixedVolume">false</bool>
@@ -2983,6 +2988,12 @@
 
     </string-array>
 
+    <!-- When migrating notification settings into the permission framework, whether all existing
+         apps should be marked as 'user-set' (true) or whether only the apps that have explicitly
+         modified notification settings should be marked as 'user-set' (false). Users will not see
+         system generated permission prompts for 'user-set' apps. -->
+    <bool name="config_notificationForceUserSetOnUpgrade">true</bool>
+
     <!-- Default Gravity setting for the system Toast view. Equivalent to: Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM -->
     <integer name="config_toastDefaultGravity">0x00000051</integer>
 
@@ -4130,9 +4141,9 @@
           This service must be trusted, as it can be activated without explicit consent of the user.
           If no service with the specified name exists on the device, cloudsearch will be disabled.
           Example: "com.android.intelligence/.CloudSearchService"
-          config_defaultCloudSearchService is for the single provider case.
+          config_defaultCloudSearchServices is for the multiple provider case.
     -->
-    <string name="config_defaultCloudSearchService" translatable="false"></string>
+    <string-array name="config_defaultCloudSearchServices"></string-array>
 
     <!-- The package name for the system's translation service.
      This service must be trusted, as it can be activated without explicit consent of the user.
@@ -5262,9 +5273,9 @@
 
     <bool name="config_cecPowerStateChangeOnActiveSourceLost_userConfigurable">true</bool>
     <bool name="config_cecPowerStateChangeOnActiveSourceLostNone_allowed">true</bool>
-    <bool name="config_cecPowerStateChangeOnActiveSourceLostNone_default">true</bool>
+    <bool name="config_cecPowerStateChangeOnActiveSourceLostNone_default">false</bool>
     <bool name="config_cecPowerStateChangeOnActiveSourceLostStandbyNow_allowed">true</bool>
-    <bool name="config_cecPowerStateChangeOnActiveSourceLostStandbyNow_default">false</bool>
+    <bool name="config_cecPowerStateChangeOnActiveSourceLostStandbyNow_default">true</bool>
 
     <bool name="config_cecSystemAudioControl_userConfigurable">true</bool>
     <bool name="config_cecSystemAudioControlEnabled_allowed">true</bool>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 1b9f7fe..44c5512 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -668,6 +668,9 @@
     <dimen name="lock_pattern_dot_line_width">22dp</dimen>
     <dimen name="lock_pattern_dot_size">14dp</dimen>
     <dimen name="lock_pattern_dot_size_activated">30dp</dimen>
+    <!-- How much of the cell space is classified as hit areas [0..1] where 1 means that hit area is
+         a circle with diameter equals to cell minimum side min(width, height). -->
+    <item type="dimen" format="float" name="lock_pattern_dot_hit_factor">0.6</item>
     <!-- Width of a gradient applied to a lock pattern line while its disappearing animation. -->
     <dimen name="lock_pattern_fade_away_gradient_width">8dp</dimen>
 
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 29eb0c0..082acbe 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -270,20 +270,8 @@
   <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_DRAG_CANCEL}. -->
   <item type="id" name="accessibilityActionDragCancel" />
 
-  <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SWIPE_LEFT}. -->
-  <item type="id" name="accessibilityActionSwipeLeft" />
-
-  <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SWIPE_RIGHT}. -->
-  <item type="id" name="accessibilityActionSwipeRight" />
-
-  <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SWIPE_UP}. -->
-  <item type="id" name="accessibilityActionSwipeUp" />
-
-  <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SWIPE_DOWN}. -->
-  <item type="id" name="accessibilityActionSwipeDown" />
-
-  <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SHOW_SUGGESTIONS}. -->
-  <item type="id" name="accessibilityActionShowSuggestions" />
+  <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SHOW_TEXT_SUGGESTIONS}. -->
+  <item type="id" name="accessibilityActionShowTextSuggestions" />
 
   <!-- View tag for remote views to store the index of the next child when adding nested remote views dynamically. -->
   <item type="id" name="remote_views_next_child" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public-final.xml
similarity index 97%
rename from core/res/res/values/public.xml
rename to core/res/res/values/public-final.xml
index 3467e1b..19a4842 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public-final.xml
@@ -3211,8 +3211,6 @@
   </staging-public-group-final>
 
   <public type="attr" name="shouldUseDefaultUnfoldTransition" id="0x0101064c" />
-  <public type="attr" name="lineBreakStyle" id="0x0101064d" />
-  <public type="attr" name="lineBreakWordStyle" id="0x0101064e" />
 
   <staging-public-group-final type="id" first-id="0x01fe0000">
     <public name="accessibilityActionDragStart" />
@@ -3224,147 +3222,4 @@
   <public type="id" name="accessibilityActionDragDrop" id="0x01020056" />
   <public type="id" name="accessibilityActionDragCancel" id="0x01020057" />
 
-  <!-- ===============================================================
-    Resources added in version T of the platform
-
-    NOTE: add <public> elements within a <staging-public-group> like so:
-
-    <staging-public-group type="attr" first-id="0x01ff0000">
-        <public name="exampleAttr1" />
-        <public name="exampleAttr2" />
-    </staging-public-group>
-
-    To add a new <staging-public-group> block, find the id value for the
-    last <staging-public-group> block defined for thie API level, and
-    subtract 0x00010000 from it to get to the id of the new block.
-
-    For example, if the block closest to the end of this file has an id
-    of 0x01ee0000, the id of the new block should be 0x01ed0000
-    (0x01ee0000 - 0x00010000 = 0x01ed0000).
-    =============================================================== -->
-  <eat-comment />
-
-  <staging-public-group type="attr" first-id="0x01df0000">
-    <public name="sharedUserMaxSdkVersion" />
-    <public name="requiredSplitTypes" />
-    <public name="splitTypes" />
-    <public name="canDisplayOnRemoteDevices" />
-    <public name="supportedTypes" />
-    <public name="resetEnabledSettingsOnAppDataCleared" />
-    <public name="supportsStylusHandwriting" />
-    <public name="showClockAndComplications" />
-    <!-- @hide @SystemApi -->
-    <public name="gameSessionService" />
-    <public name="supportsBatteryGameMode" />
-    <public name="supportsPerformanceGameMode" />
-    <public name="allowGameAngleDriver" />
-    <public name="allowGameDownscaling" />
-    <public name="allowGameFpsOverride" />
-    <public name="localeConfig" />
-    <public name="showBackground" />
-    <public name="useTargetActivityForQuickAccess"/>
-    <public name="inheritKeyStoreKeys" />
-    <public name="preferKeepClear" />
-    <public name="autoHandwritingEnabled" />
-    <public name="fromExtendLeft" />
-    <public name="fromExtendTop" />
-    <public name="fromExtendRight" />
-    <public name="fromExtendBottom" />
-    <public name="toExtendLeft" />
-    <public name="toExtendTop" />
-    <public name="toExtendRight" />
-    <public name="toExtendBottom" />
-    <public name="tileService" />
-    <public name="windowSplashScreenBehavior" />
-    <public name="allowUntrustedActivityEmbedding" />
-    <public name="knownActivityEmbeddingCerts" />
-    <public name="intro" />
-    <public name="enableOnBackInvokedCallback" />
-    <public name="supportsInlineSuggestionsWithTouchExploration" />
-  </staging-public-group>
-
-  <staging-public-group type="id" first-id="0x01de0000">
-    <public name="accessibilityActionSwipeLeft" />
-    <public name="accessibilityActionSwipeRight" />
-    <public name="accessibilityActionSwipeUp" />
-    <public name="accessibilityActionSwipeDown" />
-    <public name="accessibilityActionShowSuggestions" />
-    <public name="inputExtractAction" />
-    <public name="inputExtractAccessories" />
-  </staging-public-group>
-
-  <staging-public-group type="style" first-id="0x01dd0000">
-    <public name="TextAppearance.DeviceDefault.Headline" />
-  </staging-public-group>
-
-  <staging-public-group type="string" first-id="0x01dc0000">
-    <!-- @hide @SystemApi -->
-    <public name="config_systemSupervision" />
-    <!-- @hide @SystemApi -->
-    <public name="config_devicePolicyManagement" />
-    <!-- @hide @SystemApi -->
-    <public name="config_systemAppProtectionService" />
-    <!-- @hide @SystemApi @TestApi -->
-    <public name="config_systemAutomotiveCalendarSyncManager" />
-    <!-- @hide @SystemApi -->
-    <public name="config_defaultAutomotiveNavigation" />
-  </staging-public-group>
-
-  <staging-public-group type="dimen" first-id="0x01db0000">
-  </staging-public-group>
-
-  <staging-public-group type="color" first-id="0x01da0000">
-  </staging-public-group>
-
-  <staging-public-group type="array" first-id="0x01d90000">
-    <!-- @hide @SystemApi -->
-    <public name="config_optionalIpSecAlgorithms" />
-  </staging-public-group>
-
-  <staging-public-group type="drawable" first-id="0x01d80000">
-  </staging-public-group>
-
-  <staging-public-group type="layout" first-id="0x01d70000">
-  </staging-public-group>
-
-  <staging-public-group type="anim" first-id="0x01d60000">
-  </staging-public-group>
-
-  <staging-public-group type="animator" first-id="0x01d50000">
-  </staging-public-group>
-
-  <staging-public-group type="interpolator" first-id="0x01d40000">
-  </staging-public-group>
-
-  <staging-public-group type="mipmap" first-id="0x01d30000">
-  </staging-public-group>
-
-  <staging-public-group type="integer" first-id="0x01d20000">
-  </staging-public-group>
-
-  <staging-public-group type="transition" first-id="0x01d10000">
-  </staging-public-group>
-
-  <staging-public-group type="raw" first-id="0x01d00000">
-  </staging-public-group>
-
-  <staging-public-group type="bool" first-id="0x01cf0000">
-    <!-- @hide @TestApi -->
-    <public name="config_preventImeStartupUnlessTextEditor" />
-    <!-- @hide @SystemApi -->
-    <public name="config_enableQrCodeScannerOnLockScreen" />
-  </staging-public-group>
-
-  <staging-public-group type="fraction" first-id="0x01ce0000">
-  </staging-public-group>
-
-  <!-- ===============================================================
-       DO NOT ADD UN-GROUPED ITEMS HERE
-
-       Any new items (attrs, styles, ids, etc.) *must* be added in a
-       staging-public-group block, as the preceding comment explains.
-       Items added outside of a group may have their value recalculated
-       every time something new is added to this file.
-       =============================================================== -->
-
 </resources>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
new file mode 100644
index 0000000..0a4c4c0
--- /dev/null
+++ b/core/res/res/values/public-staging.xml
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Exposing a new resource:
+        To add a new entry, find the corresponding "staging-public-group" with the correct type for
+        your resource, and add a new entry to the BOTTOM of the list. This ensures that indexes
+        don't shift for previously added resources, and the new one will be appended to the end.
+
+        To add R.attr.exampleAttrName:
+            <staging-public-group type="attr" first-id="0x1ff0000">
+                <public name="previouslyAdded1"/>
+                <public name="previouslyAdded2"/>
+                <public name="exampleAttrName"/>
+            </staging-public-group>
+
+    Deleting a resource:
+        If a resource is no longer supported/used, it can be marked removed by renaming the
+        resource with a `removed_` prefix. This preserves the indexes of other resources so as not
+        to break apps that have compiled with their integers previously.
+
+        To remove R.attr.previouslyAdded2:
+            <staging-public-group type="attr" first-id="0x1ff0000">
+                <public name="previouslyAdded1"/>
+                <public name="removed_previouslyAdded2"/>
+                <public name="exampleAttrName"/>
+            </staging-public-group>
+
+        IMPORTANT: Deleting an entry is never allowed, even across branches or reverts. Please take
+        this into account before merging a change which edits this file. Small, isolated changes
+        which only add/remove resources is recommended to avoid reverts due to build/test failures.
+
+    Renaming a resource:
+        This is generally fine and can be done to the entry directly, with no other changes. But
+        note that any apps/tooling that resolve against resource names rather than IDs may break
+        as a result. This is uncommon, but not rare.
+
+    Finalizing a release's resources:
+        1. $ANDROID_BUILD_TOP/frameworks/base/tools/aapt2/tools/finalize_res.py \
+           $ANDROID_BUILD_TOP/frameworks/base/core/res/res/values/public-staging.xml \
+           $ANDROID_BUILD_TOP/frameworks/base/core/res/res/values/public-final.xml
+        2. Rename "NEXT" in the new public-staging.xml resources header to the next platform short
+           version code
+
+    Finalizing a release's resources (manually; only for reference):
+        1. Delete all "staging-public-group" blocks for the release with no entries inside them
+        2. Rename the remaining "staging-public-group" blocks for that release to
+           "staging-public-group-final"
+        3. Cut them out this file and place at the bottom of public-final.xml; also move the
+           "Resources added in version ? of the platform" header
+        4. Copy-paste all of the non-"removed_" resources outside of the staging blocks into being
+           siblings alongside them
+        5. Assign them final public IDs in the form of
+           <public type="attr" name="exampleAttrName" id="0x0101088a" />
+           by finding the last ID for that type and incrementing the last 4 characters by 1 in
+           hexadecimal
+        6. Back in this file, seed the next release's resources by adding "staging-public-group"
+           tags with their "first-id" value shifted by -0x00010000 from the lowest "first-id"
+           in the last used "staging-public-group-final"
+
+        Example:
+            Starting public-staging.xml:
+                <!\- ===============================================================
+                    Resources added in version ? of the platform
+                    =============================================================== -\>
+                <eat-comment />
+
+                <staging-public-group type="attr" first-id="0x01ff0000">
+                    <public name="exampleAttr1"/>
+                    <public name="removed_exampleAttr2"/>
+                    <public name="exampleAttr3"/>
+                </staging-public-group>
+
+                <staging-public-group type="id" first-id="0x01fe0000">
+                </staging-public-group>
+
+            Resulting public-final.xml:
+                <!\- ===============================================================
+                    Resources added in version ? of the platform
+                    =============================================================== -\>
+                <eat-comment />
+
+                <staging-public-group-final type="attr" first-id="0x01ff0000">
+                    <public name="exampleAttr1"/>
+                    <public name="removed_exampleAttr2"/>
+                    <public name="exampleAttr3"/>
+                </staging-public-group-final>
+
+                <public type="id" name="exampleAttr1" id="0x0101088a"/>
+                <public type="id" name="exampleAttr3" id="0x0101088b"/>
+
+            Resulting public-staging.xml:
+                <!\- ===============================================================
+                    Resources added in version (? + 1) of the platform
+                    =============================================================== -\>
+                <eat-comment />
+
+                <staging-public-group type="attr" first-id="0x01fd0000">
+                </staging-public-group>
+
+                <staging-public-group type="id" first-id="0x01fc0000">
+                </staging-public-group>
+-->
+<resources>
+
+  <!-- ===============================================================
+    Resources added in version T of the platform
+
+    NOTE: After this version of the platform is forked, changes cannot be made to the root
+    branch's groups for that release. Only merge changes to the forked platform branch.
+    =============================================================== -->
+  <eat-comment/>
+
+  <staging-public-group type="attr" first-id="0x01df0000">
+    <public name="sharedUserMaxSdkVersion" />
+    <public name="requiredSplitTypes" />
+    <public name="splitTypes" />
+    <public name="canDisplayOnRemoteDevices" />
+    <public name="supportedTypes" />
+    <public name="resetEnabledSettingsOnAppDataCleared" />
+    <public name="supportsStylusHandwriting" />
+    <public name="showClockAndComplications" />
+    <!-- @hide @SystemApi -->
+    <public name="gameSessionService" />
+    <public name="supportsBatteryGameMode" />
+    <public name="supportsPerformanceGameMode" />
+    <public name="allowGameAngleDriver" />
+    <public name="allowGameDownscaling" />
+    <public name="allowGameFpsOverride" />
+    <public name="localeConfig" />
+    <public name="showBackground" />
+    <public name="useTargetActivityForQuickAccess"/>
+    <public name="inheritKeyStoreKeys" />
+    <public name="preferKeepClear" />
+    <public name="autoHandwritingEnabled" />
+    <public name="fromExtendLeft" />
+    <public name="fromExtendTop" />
+    <public name="fromExtendRight" />
+    <public name="fromExtendBottom" />
+    <public name="toExtendLeft" />
+    <public name="toExtendTop" />
+    <public name="toExtendRight" />
+    <public name="toExtendBottom" />
+    <public name="tileService" />
+    <public name="windowSplashScreenBehavior" />
+    <public name="allowUntrustedActivityEmbedding" />
+    <public name="knownActivityEmbeddingCerts" />
+    <public name="intro" />
+    <public name="enableOnBackInvokedCallback" />
+    <public name="supportsInlineSuggestionsWithTouchExploration" />
+    <public name="lineBreakStyle" />
+    <public name="lineBreakWordStyle" />
+    <!-- @hide -->
+    <public name="maxDrawableWidth" />
+    <!-- @hide -->
+    <public name="maxDrawableHeight" />
+  </staging-public-group>
+
+  <staging-public-group type="id" first-id="0x01de0000">
+    <public name="removed_accessibilityActionSwipeLeft" />
+    <public name="removed_accessibilityActionSwipeRight" />
+    <public name="removed_accessibilityActionSwipeUp" />
+    <public name="removed_accessibilityActionSwipeDown" />
+    <public name="accessibilityActionShowTextSuggestions" />
+    <public name="inputExtractAction" />
+    <public name="inputExtractAccessories" />
+  </staging-public-group>
+
+  <staging-public-group type="style" first-id="0x01dd0000">
+    <public name="TextAppearance.DeviceDefault.Headline" />
+  </staging-public-group>
+
+  <staging-public-group type="string" first-id="0x01dc0000">
+    <!-- @hide @SystemApi -->
+    <public name="config_systemSupervision" />
+    <!-- @hide @SystemApi -->
+    <public name="config_devicePolicyManagement" />
+    <!-- @hide @SystemApi -->
+    <public name="config_systemAppProtectionService" />
+    <!-- @hide @SystemApi @TestApi -->
+    <public name="config_systemAutomotiveCalendarSyncManager" />
+    <!-- @hide @SystemApi -->
+    <public name="config_defaultAutomotiveNavigation" />
+  </staging-public-group>
+
+  <staging-public-group type="dimen" first-id="0x01db0000">
+  </staging-public-group>
+
+  <staging-public-group type="color" first-id="0x01da0000">
+  </staging-public-group>
+
+  <staging-public-group type="array" first-id="0x01d90000">
+    <!-- @hide @SystemApi -->
+    <public name="config_optionalIpSecAlgorithms" />
+  </staging-public-group>
+
+  <staging-public-group type="drawable" first-id="0x01d80000">
+  </staging-public-group>
+
+  <staging-public-group type="layout" first-id="0x01d70000">
+  </staging-public-group>
+
+  <staging-public-group type="anim" first-id="0x01d60000">
+  </staging-public-group>
+
+  <staging-public-group type="animator" first-id="0x01d50000">
+  </staging-public-group>
+
+  <staging-public-group type="interpolator" first-id="0x01d40000">
+  </staging-public-group>
+
+  <staging-public-group type="mipmap" first-id="0x01d30000">
+  </staging-public-group>
+
+  <staging-public-group type="integer" first-id="0x01d20000">
+  </staging-public-group>
+
+  <staging-public-group type="transition" first-id="0x01d10000">
+  </staging-public-group>
+
+  <staging-public-group type="raw" first-id="0x01d00000">
+  </staging-public-group>
+
+  <staging-public-group type="bool" first-id="0x01cf0000">
+    <!-- @hide @TestApi -->
+    <public name="config_preventImeStartupUnlessTextEditor" />
+    <!-- @hide @SystemApi -->
+    <public name="config_enableQrCodeScannerOnLockScreen" />
+  </staging-public-group>
+
+  <staging-public-group type="fraction" first-id="0x01ce0000">
+  </staging-public-group>
+
+</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 34bd2fb..4c71b3a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -234,9 +234,9 @@
     <!-- Displayed to tell the user that they should switch their network preference. -->
     <string name="NetworkPreferenceSwitchSummary">Try changing preferred network. Tap to change.</string>
     <!-- Displayed to tell the user that emergency calls might not be available. -->
-    <string name="EmergencyCallWarningTitle">Emergency calling unavailable</string>
+    <string name="EmergencyCallWarningTitle">Emergency calls may be unavailable</string>
     <!-- Displayed to tell the user that emergency calls might not be available. -->
-    <string name="EmergencyCallWarningSummary">Can\u2019t make emergency calls over Wi\u2011Fi</string>
+    <string name="EmergencyCallWarningSummary"><xliff:g id="spn" example="Operator">%s</xliff:g> doesn\'t support emergency calls over Wi-Fi. Tap for details.</string>
 
     <!-- Telephony notification channel name for a channel containing network alert notifications. -->
     <string name="notification_channel_network_alert">Alerts</string>
@@ -1248,14 +1248,13 @@
         Malicious apps may use this to erase or modify your call log.</string>
 
     <!-- Title of the body sensors permission, listed so the user can decide whether to allow the application to access body sensor data. [CHAR LIMIT=80] -->
-    <string name="permlab_bodySensors">access body sensors (like heart rate monitors)
-    </string>
+    <string name="permlab_bodySensors">Access body sensor data, like heart rate, while in use</string>
     <!-- Description of the body sensors permission, listed so the user can decide whether to allow the application to access data from body sensors. [CHAR LIMIT=NONE] -->
-    <string name="permdesc_bodySensors" product="default">Access to data from body sensors such as heart rate, temperature, blood oxygen percentage, etc.</string>
+    <string name="permdesc_bodySensors" product="default">Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in use.</string>
     <!-- Title of the background body sensors permission, listed so the user can decide whether to allow the application to access body sensor data in the background. [CHAR LIMIT=80] -->
-    <string name="permlab_bodySensors_background">access body sensors (like heart rate monitors) while in the background</string>
+    <string name="permlab_bodySensors_background">Access body sensor data, like heart rate, while in the background</string>
     <!-- Description of the background body sensors permission, listed so the user can decide whether to allow the application to access data from body sensors in the background. [CHAR LIMIT=NONE] -->
-    <string name="permdesc_bodySensors_background" product="default">Access to data from body sensors such as heart rate, temperature, blood oxygen percentage, etc. while in the background.</string>
+    <string name="permdesc_bodySensors_background" product="default">Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in the background.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_readCalendar">Read calendar events and details</string>
@@ -1919,9 +1918,9 @@
     <string name="permdesc_readMediaVideo">Allows the app to read video files from your shared storage.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can read from. [CHAR LIMIT=none] -->
-    <string name="permlab_readMediaImage">read image files from shared storage</string>
+    <string name="permlab_readMediaImages">read image files from shared storage</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can read from. [CHAR LIMIT=none] -->
-    <string name="permdesc_readMediaImage">Allows the app to read image files from your shared storage.</string>
+    <string name="permdesc_readMediaImages">Allows the app to read image files from your shared storage.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can write to. [CHAR LIMIT=none] -->
     <string name="permlab_sdcardWrite">modify or delete the contents of your shared storage</string>
@@ -2415,7 +2414,7 @@
     <!-- On the unlock pattern screen, shown at the top of the unlock screen to tell the user what to do. Below this text is the place for theu ser to draw the pattern. -->
     <string name="lockscreen_pattern_instructions">Draw pattern to unlock</string>
     <!-- Button at the bottom of the unlock screen to make an emergency call or access other emergency assistance functions. -->
-    <string name="lockscreen_emergency_call">Emergency call</string>
+    <string name="lockscreen_emergency_call">Emergency</string>
     <!-- Button at the bottom of the unlock screen that lets the user return to a call -->
     <string name="lockscreen_return_to_call">Return to call</string>
     <!-- Shown to confirm that the user entered their lock pattern correctly. -->
@@ -4095,10 +4094,20 @@
     <!-- Description of an application permission that lets it query all other packages. [CHAR LIMIT=NONE] -->
     <string name="permdesc_queryAllPackages">Allows an app to see all installed packages.</string>
 
-    <!-- Title of an application permission that lets it access SupplementalApis. [CHAR LIMIT=NONE] -->
-    <string name="permlab_accessSupplementalApi">access SupplementalApis</string>
-    <!-- Description of an application permission that lets it access SupplementalApis. [CHAR LIMIT=NONE]-->
-    <string name="permdesc_accessSupplementalApi">Allows an application to access SupplementalApis.</string>
+    <!-- Title of an application permission that lets it access AdServices Topics API. [CHAR LIMIT=NONE] -->
+    <string name="permlab_accessAdServicesTopics">access AdServices Topics API</string>
+    <!-- Description of an application permission that lets it access AdServices Topics API. [CHAR LIMIT=NONE]-->
+    <string name="permdesc_accessAdServicesTopics">Allows an application to access AdServices Topics API.</string>
+
+    <!-- Title of an application permission that lets it access AdServices Attribution APIs. [CHAR LIMIT=NONE] -->
+    <string name="permlab_accessAdServicesAttribution">access AdServices Attribution APIs</string>
+    <!-- Description of an application permission that lets it access AdServices Attribution APIs. [CHAR LIMIT=NONE]-->
+    <string name="permdesc_accessAdServicesAttribution">Allows an application to access AdServices Attribution APIs.</string>
+
+    <!-- Title of an application permission that lets it access AdServices Custom Audiences API. [CHAR LIMIT=NONE] -->
+    <string name="permlab_accessAdServicesCustomAudiences">access AdServices Custom Audiences API</string>
+    <!-- Description of an application permission that lets it access AdServices Custom Audiences API. [CHAR LIMIT=NONE]-->
+    <string name="permdesc_accessAdServicesCustomAudiences">Allows an application to access AdServices Custom Audiences  API.</string>
 
     <!-- Shown in the tutorial for tap twice for zoom control. -->
     <string name="tutorial_double_tap_to_zoom_message_short">Tap twice for zoom control</string>
@@ -5721,16 +5730,17 @@
     <!-- Title for the harmful app warning dialog. [CHAR LIMIT=40] -->
     <string name="harmful_app_warning_title">Harmful app detected</string>
 
-    <!-- Title for the log access confirmation dialog. [CHAR LIMIT=40] -->
-    <string name="log_access_confirmation_title">System log access request</string>
+    <!-- Title for the log access confirmation dialog. [CHAR LIMIT=NONE] -->
+    <string name="log_access_confirmation_title">Allow <xliff:g id="log_access_app_name" example="Example App">%s</xliff:g> to access all device logs?</string>
     <!-- Label for the allow button on the log access confirmation dialog. [CHAR LIMIT=20] -->
     <string name="log_access_confirmation_allow">Only this time</string>
     <!-- Label for the deny button on the log access confirmation dialog. [CHAR LIMIT=20] -->
     <string name="log_access_confirmation_deny">Don\u2019t allow</string>
 
     <!-- Content for the log access confirmation dialog. [CHAR LIMIT=NONE]-->
-    <string name="log_access_confirmation_body"><xliff:g id="log_access_app_name" example="Example App">%s</xliff:g> requests system logs for functional debugging.
-        These logs might contain information that apps and services on your device have written.</string>
+    <string name="log_access_confirmation_body">Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps you trust to access all device logs.
+        \n\nIf you don’t allow this app to access all device logs, it can still access its own logs and your device manufacturer may still be able to access some logs or info on your device. Learn more
+    </string>
 
     <!-- Privacy notice do not show [CHAR LIMIT=20] -->
     <string name="log_access_do_not_show_again">Don\u2019t show again</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 9553f95..7a9f520 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1499,5 +1499,43 @@
       <item name="textColor">#555555</item>
     </style>
 
+    <!-- The style for log access consent text -->
+    <style name="AllowLogAccess">
+        <item name="android:layout_width">332dp</item>
+        <item name="android:textSize">24sp</item>
+        <item name="android:textColor">@android:color/system_neutral1_900</item>
+        <item name="android:fontFamily">google-sans</item>
+    </style>
+
+    <style name="PrimaryAllowLogAccess">
+        <item name="android:layout_width">332dp</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:textColor">@android:color/system_neutral1_900</item>
+        <item name="android:fontFamily">google-sans</item>
+    </style>
+
+    <style name="PermissionGrantButtonTop"
+           parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored">
+        <item name="android:layout_width">332dp</item>
+        <item name="android:layout_height">56dp</item>
+        <item name="android:layout_marginTop">2dp</item>
+        <item name="android:layout_marginBottom">2dp</item>
+        <item name="android:fontFamily">google-sans-medium</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:textColor">@android:color/system_neutral1_900</item>
+        <item name="android:background">@drawable/grant_permissions_buttons_top</item>
+    </style>
+
+    <style name="PermissionGrantButtonBottom"
+           parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored">
+        <item name="android:layout_width">332dp</item>
+        <item name="android:layout_height">56dp</item>
+        <item name="android:layout_marginTop">2dp</item>
+        <item name="android:layout_marginBottom">2dp</item>
+        <item name="android:fontFamily">google-sans-medium</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:textColor">@android:color/system_neutral1_900</item>
+        <item name="android:background">@drawable/grant_permissions_buttons_bottom</item>
+    </style>
 
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index df3cbf3..1f0b22b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1325,6 +1325,7 @@
   <java-symbol type="dimen" name="lock_pattern_dot_line_width" />
   <java-symbol type="dimen" name="lock_pattern_dot_size" />
   <java-symbol type="dimen" name="lock_pattern_dot_size_activated" />
+  <java-symbol type="dimen" name="lock_pattern_dot_hit_factor" />
   <java-symbol type="dimen" name="lock_pattern_fade_away_gradient_width" />
   <java-symbol type="drawable" name="clock_dial" />
   <java-symbol type="drawable" name="clock_hand_hour" />
@@ -3677,7 +3678,7 @@
   <java-symbol type="string" name="notification_channel_network_status" />
   <java-symbol type="string" name="notification_channel_network_alerts" />
   <java-symbol type="string" name="notification_channel_network_available" />
-  <java-symbol type="string" name="config_defaultCloudSearchService" />
+  <java-symbol type="array" name="config_defaultCloudSearchServices" />
   <java-symbol type="string" name="notification_channel_vpn" />
   <java-symbol type="string" name="notification_channel_device_admin" />
   <java-symbol type="string" name="notification_channel_alerts" />
@@ -3883,6 +3884,10 @@
   <java-symbol type="string" name="log_access_confirmation_deny" />
   <java-symbol type="string" name="log_access_confirmation_title" />
   <java-symbol type="string" name="log_access_confirmation_body" />
+  <java-symbol type="layout" name="log_access_user_consent_dialog_permission" />
+  <java-symbol type="id" name="log_access_dialog_title" />
+  <java-symbol type="id" name="log_access_dialog_allow_button" />
+  <java-symbol type="id" name="log_access_dialog_deny_button" />
 
   <java-symbol type="string" name="config_defaultAssistantAccessComponent" />
 
@@ -4765,5 +4770,6 @@
   <java-symbol type="integer" name="config_bg_current_drain_exempted_types" />
   <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" />
 
 </resources>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
index 6a53f68..19bb718 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
@@ -188,6 +188,9 @@
                 case BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE:
                     label = "FGS";
                     break;
+                case BatteryConsumer.PROCESS_STATE_CACHED:
+                    label = "cached";
+                    break;
                 default:
                     continue;
             }
diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
index 23b12cf..fd08e3c 100644
--- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
+++ b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
@@ -242,13 +242,17 @@
                 BatteryConsumer.PROCESS_STATE_BACKGROUND);
         final BatteryConsumer.Key keyFgs = uidBuilder.getKey(BatteryConsumer.POWER_COMPONENT_CPU,
                 BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);
+        final BatteryConsumer.Key keyCached = uidBuilder.getKey(BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_CACHED);
 
         uidBuilder.setConsumedPower(keyFg, 9100, BatteryConsumer.POWER_MODEL_POWER_PROFILE)
                 .setUsageDurationMillis(keyFg, 8100)
                 .setConsumedPower(keyBg, 9200, BatteryConsumer.POWER_MODEL_MEASURED_ENERGY)
                 .setUsageDurationMillis(keyBg, 8200)
                 .setConsumedPower(keyFgs, 9300, BatteryConsumer.POWER_MODEL_MEASURED_ENERGY)
-                .setUsageDurationMillis(keyFgs, 8300);
+                .setUsageDurationMillis(keyFgs, 8300)
+                .setConsumedPower(keyCached, 9400, BatteryConsumer.POWER_MODEL_MEASURED_ENERGY)
+                .setUsageDurationMillis(keyFgs, 8400);
 
         builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid1)
                 .setPackageWithHighestDrain("myPackage1")
diff --git a/core/tests/coretests/res/drawable/big_a.png b/core/tests/coretests/res/drawable/big_a.png
new file mode 100644
index 0000000..dc059a3
--- /dev/null
+++ b/core/tests/coretests/res/drawable/big_a.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/communal_host_view.xml b/core/tests/coretests/res/layout/caching_icon_view_test_max_size.xml
similarity index 61%
copy from packages/SystemUI/res/layout/communal_host_view.xml
copy to core/tests/coretests/res/layout/caching_icon_view_test_max_size.xml
index cd9c260..9a03446 100644
--- a/packages/SystemUI/res/layout/communal_host_view.xml
+++ b/core/tests/coretests/res/layout/caching_icon_view_test_max_size.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2021 The Android Open Source Project
+  ~ 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.
@@ -15,9 +15,10 @@
   ~ limitations under the License.
   -->
 
-<!-- This is a view that shows general status information in Keyguard. -->
-<com.android.systemui.communal.CommunalHostView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/communal_host"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"/>
\ No newline at end of file
+<com.android.internal.widget.CachingIconView
+          xmlns:android="http://schemas.android.com/apk/res/android"
+          android:id="@+id/caching_icon_view"
+          android:layout_width="120dp"
+          android:layout_height="120dp"
+          android:maxDrawableWidth="80dp"
+          android:maxDrawableHeight="80dp" />
diff --git a/packages/SystemUI/res/layout/communal_host_view.xml b/core/tests/coretests/res/layout/caching_icon_view_test_no_max_size.xml
similarity index 62%
copy from packages/SystemUI/res/layout/communal_host_view.xml
copy to core/tests/coretests/res/layout/caching_icon_view_test_no_max_size.xml
index cd9c260..a213a97 100644
--- a/packages/SystemUI/res/layout/communal_host_view.xml
+++ b/core/tests/coretests/res/layout/caching_icon_view_test_no_max_size.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2021 The Android Open Source Project
+  ~ 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.
@@ -15,9 +15,8 @@
   ~ limitations under the License.
   -->
 
-<!-- This is a view that shows general status information in Keyguard. -->
-<com.android.systemui.communal.CommunalHostView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/communal_host"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"/>
\ No newline at end of file
+<com.android.internal.widget.CachingIconView
+          xmlns:android="http://schemas.android.com/apk/res/android"
+          android:id="@+id/caching_icon_view"
+          android:layout_width="120dp"
+          android:layout_height="120dp" />
diff --git a/core/tests/coretests/res/raw/obb_enc_file100_orig1.obb b/core/tests/coretests/res/raw/obb_enc_file100_orig1.obb
deleted file mode 100644
index 373b8e4..0000000
--- a/core/tests/coretests/res/raw/obb_enc_file100_orig1.obb
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/res/raw/obb_enc_file100_orig3.obb b/core/tests/coretests/res/raw/obb_enc_file100_orig3.obb
deleted file mode 100644
index aa531d8..0000000
--- a/core/tests/coretests/res/raw/obb_enc_file100_orig3.obb
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 5c9044c..beadc446 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -424,6 +424,7 @@
 
         @Override
         public void bindApplication(String s, ApplicationInfo applicationInfo,
+                String sdkSandboxClientAppPackage,
                 ProviderInfoList list, ComponentName componentName, ProfilerInfo profilerInfo,
                 Bundle bundle, IInstrumentationWatcher iInstrumentationWatcher,
                 IUiAutomationConnection iUiAutomationConnection, int i, boolean b, boolean b1,
diff --git a/core/tests/coretests/src/android/graphics/drawable/IconTest.java b/core/tests/coretests/src/android/graphics/drawable/IconTest.java
index 2bdcc28..75390a2 100644
--- a/core/tests/coretests/src/android/graphics/drawable/IconTest.java
+++ b/core/tests/coretests/src/android/graphics/drawable/IconTest.java
@@ -180,6 +180,61 @@
         }
     }
 
+    /**
+     * Icon resource test that ensures we can load and draw non-bitmaps. (In this case,
+     * stat_sys_adb is assumed, and asserted, to be a vector drawable.)
+     */
+    @SmallTest
+    public void testWithStatSysAdbResource() throws Exception {
+        // establish reference bitmap
+        final float dp = getContext().getResources().getDisplayMetrics().density;
+        final int stat_sys_adb_width = (int) (24 * dp);
+        final int stat_sys_adb_height = (int) (24 * dp);
+
+        final Drawable stat_sys_adb = getContext()
+                .getDrawable(com.android.internal.R.drawable.stat_sys_adb);
+        if (!(stat_sys_adb instanceof VectorDrawable)) {
+            fail("stat_sys_adb is a " + stat_sys_adb.toString()
+                    + ", not a VectorDrawable; stat_sys_adb malformed");
+        }
+
+        if (stat_sys_adb.getIntrinsicWidth() != stat_sys_adb_width) {
+            fail("intrinsic width of stat_sys_adb is not 24dp; stat_sys_adb malformed");
+        }
+        if (stat_sys_adb.getIntrinsicHeight() != stat_sys_adb_height) {
+            fail("intrinsic height of stat_sys_adb is not 24dp; stat_sys_adb malformed");
+        }
+        final Bitmap referenceBitmap = Bitmap.createBitmap(
+                stat_sys_adb_width,
+                stat_sys_adb_height,
+                Bitmap.Config.ARGB_8888);
+        stat_sys_adb.setBounds(0, 0, stat_sys_adb_width, stat_sys_adb_height);
+        stat_sys_adb.draw(new Canvas(referenceBitmap));
+
+        final Icon im1 = Icon.createWithResource(getContext(),
+                com.android.internal.R.drawable.stat_sys_adb);
+        final Drawable draw1 = im1.loadDrawable(getContext());
+
+        assertEquals(stat_sys_adb.getIntrinsicWidth(), draw1.getIntrinsicWidth());
+        assertEquals(stat_sys_adb.getIntrinsicHeight(), draw1.getIntrinsicHeight());
+        assertEquals(im1.getResId(), com.android.internal.R.drawable.stat_sys_adb);
+
+        final Bitmap test1 = Bitmap.createBitmap(
+                draw1.getIntrinsicWidth(),
+                draw1.getIntrinsicHeight(),
+                Bitmap.Config.ARGB_8888);
+        draw1.setBounds(0, 0, test1.getWidth(), test1.getHeight());
+        draw1.draw(new Canvas(test1));
+
+        final File dir = getContext().getExternalFilesDir(null);
+        test1.compress(Bitmap.CompressFormat.PNG, 100,
+                new FileOutputStream(new File(dir, "testWithVectorDrawableResource-test.png")));
+        if (!equalBitmaps(referenceBitmap, test1)) {
+            findBitmapDifferences(referenceBitmap, test1);
+            fail("testWithFile: file1 differs, check " + dir);
+        }
+    }
+
     @SmallTest
     public void testWithFile() throws Exception {
         final Bitmap bit1 = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape))
diff --git a/core/tests/coretests/src/android/os/IpcDataCacheTest.java b/core/tests/coretests/src/android/os/IpcDataCacheTest.java
new file mode 100644
index 0000000..fa7d721
--- /dev/null
+++ b/core/tests/coretests/src/android/os/IpcDataCacheTest.java
@@ -0,0 +1,312 @@
+/*
+ * 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.os;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test for verifying the behavior of {@link IpcDataCache}.  This test does
+ * not use any actual binder calls - it is entirely self-contained.  This test also relies
+ * on the test mode of {@link IpcDataCache} because Android SELinux rules do
+ * not grant test processes the permission to set system properties.
+ * <p>
+ * Build/Install/Run:
+ *  atest FrameworksCoreTests:IpcDataCacheTest
+ */
+@SmallTest
+public class IpcDataCacheTest {
+
+    // Configuration for creating caches
+    private static final String MODULE = IpcDataCache.MODULE_TEST;
+    private static final String API = "testApi";
+
+    // This class is a proxy for binder calls.  It contains a counter that increments
+    // every time the class is queried.
+    private static class ServerProxy {
+        // The number of times this class was queried.
+        private int mCount = 0;
+
+        // A single query.  The key behavior is that the query count is incremented.
+        boolean query(int x) {
+            mCount++;
+            return value(x);
+        }
+
+        // Return the expected value of an input, without incrementing the query count.
+        boolean value(int x) {
+            return x % 3 == 0;
+        }
+
+        // Verify the count.
+        void verify(int x) {
+            assertEquals(x, mCount);
+        }
+    }
+
+    // The functions for querying the server.
+    private static class ServerQuery
+            extends IpcDataCache.QueryHandler<Integer, Boolean> {
+        private final ServerProxy mServer;
+
+        ServerQuery(ServerProxy server) {
+            mServer = server;
+        }
+
+        @Override
+        public Boolean apply(Integer x) {
+            return mServer.query(x);
+        }
+        @Override
+        public boolean shouldBypassCache(Integer x) {
+            return x % 13 == 0;
+        }
+    }
+
+    // Clear the test mode after every test, in case this process is used for other
+    // tests. This also resets the test property map.
+    @After
+    public void tearDown() throws Exception {
+        IpcDataCache.setTestMode(false);
+    }
+
+    // This test is disabled pending an sepolicy change that allows any app to set the
+    // test property.
+    @Test
+    public void testBasicCache() {
+
+        // A stand-in for the binder.  The test verifies that calls are passed through to
+        // this class properly.
+        ServerProxy tester = new ServerProxy();
+
+        // Create a cache that uses simple arithmetic to computer its values.
+        IpcDataCache<Integer, Boolean> testCache =
+                new IpcDataCache<>(4, MODULE, API, "testCache1",
+                        new ServerQuery(tester));
+
+        IpcDataCache.setTestMode(true);
+        testCache.testPropertyName();
+
+        tester.verify(0);
+        assertEquals(tester.value(3), testCache.query(3));
+        tester.verify(1);
+        assertEquals(tester.value(3), testCache.query(3));
+        tester.verify(2);
+        testCache.invalidateCache();
+        assertEquals(tester.value(3), testCache.query(3));
+        tester.verify(3);
+        assertEquals(tester.value(5), testCache.query(5));
+        tester.verify(4);
+        assertEquals(tester.value(5), testCache.query(5));
+        tester.verify(4);
+        assertEquals(tester.value(3), testCache.query(3));
+        tester.verify(4);
+
+        // Invalidate the cache, and verify that the next read on 3 goes to the server.
+        testCache.invalidateCache();
+        assertEquals(tester.value(3), testCache.query(3));
+        tester.verify(5);
+
+        // Test bypass.  The query for 13 always bypasses the cache.
+        assertEquals(tester.value(12), testCache.query(12));
+        assertEquals(tester.value(13), testCache.query(13));
+        assertEquals(tester.value(14), testCache.query(14));
+        tester.verify(8);
+        assertEquals(tester.value(12), testCache.query(12));
+        assertEquals(tester.value(13), testCache.query(13));
+        assertEquals(tester.value(14), testCache.query(14));
+        tester.verify(9);
+    }
+
+    @Test
+    public void testDisableCache() {
+
+        // A stand-in for the binder.  The test verifies that calls are passed through to
+        // this class properly.
+        ServerProxy tester = new ServerProxy();
+
+        // Three caches, all using the same system property but one uses a different name.
+        IpcDataCache<Integer, Boolean> cache1 =
+                new IpcDataCache<>(4, MODULE, API, "cacheA",
+                        new ServerQuery(tester));
+        IpcDataCache<Integer, Boolean> cache2 =
+                new IpcDataCache<>(4, MODULE, API, "cacheA",
+                        new ServerQuery(tester));
+        IpcDataCache<Integer, Boolean> cache3 =
+                new IpcDataCache<>(4, MODULE, API, "cacheB",
+                        new ServerQuery(tester));
+
+        // Caches are enabled upon creation.
+        assertEquals(false, cache1.getDisabledState());
+        assertEquals(false, cache2.getDisabledState());
+        assertEquals(false, cache3.getDisabledState());
+
+        // Disable the cache1 instance.  Only cache1 is disabled
+        cache1.disableInstance();
+        assertEquals(true, cache1.getDisabledState());
+        assertEquals(false, cache2.getDisabledState());
+        assertEquals(false, cache3.getDisabledState());
+
+        // Disable cache1.  This will disable cache1 and cache2 because they share the
+        // same name.  cache3 has a different name and will not be disabled.
+        cache1.disableForCurrentProcess();
+        assertEquals(true, cache1.getDisabledState());
+        assertEquals(true, cache2.getDisabledState());
+        assertEquals(false, cache3.getDisabledState());
+
+        // Create a new cache1.  Verify that the new instance is disabled.
+        cache1 = new IpcDataCache<>(4, MODULE, API, "cacheA",
+                new ServerQuery(tester));
+        assertEquals(true, cache1.getDisabledState());
+
+        // Remove the record of caches being locally disabled.  This is a clean-up step.
+        cache1.forgetDisableLocal();
+        assertEquals(true, cache1.getDisabledState());
+        assertEquals(true, cache2.getDisabledState());
+        assertEquals(false, cache3.getDisabledState());
+
+        // Create a new cache1.  Verify that the new instance is not disabled.
+        cache1 = new IpcDataCache<>(4, MODULE, API, "cacheA",
+                new ServerQuery(tester));
+        assertEquals(false, cache1.getDisabledState());
+    }
+
+    private static class TestQuery
+            extends IpcDataCache.QueryHandler<Integer, String> {
+
+        private int mRecomputeCount = 0;
+
+        @Override
+        public String apply(Integer qv) {
+            mRecomputeCount += 1;
+            return "foo" + qv.toString();
+        }
+
+        int getRecomputeCount() {
+            return mRecomputeCount;
+        }
+    }
+
+    private static class TestCache extends IpcDataCache<Integer, String> {
+        private final TestQuery mQuery;
+
+        TestCache() {
+            this(MODULE, API);
+        }
+
+        TestCache(String module, String api) {
+            this(module, api, new TestQuery());
+        }
+
+        TestCache(String module, String api, TestQuery query) {
+            super(4, module, api, "testCache7", query);
+            mQuery = query;
+            setTestMode(true);
+            testPropertyName();
+        }
+
+        int getRecomputeCount() {
+            return mQuery.getRecomputeCount();
+        }
+    }
+
+    @Test
+    public void testCacheRecompute() {
+        TestCache cache = new TestCache();
+        cache.invalidateCache();
+        assertEquals(cache.isDisabled(), false);
+        assertEquals("foo5", cache.query(5));
+        assertEquals(1, cache.getRecomputeCount());
+        assertEquals("foo5", cache.query(5));
+        assertEquals(1, cache.getRecomputeCount());
+        assertEquals("foo6", cache.query(6));
+        assertEquals(2, cache.getRecomputeCount());
+        cache.invalidateCache();
+        assertEquals("foo5", cache.query(5));
+        assertEquals("foo5", cache.query(5));
+        assertEquals(3, cache.getRecomputeCount());
+        // Invalidate the cache with a direct call to the property.
+        IpcDataCache.invalidateCache(MODULE, API);
+        assertEquals("foo5", cache.query(5));
+        assertEquals("foo5", cache.query(5));
+        assertEquals(4, cache.getRecomputeCount());
+    }
+
+    @Test
+    public void testCacheInitialState() {
+        TestCache cache = new TestCache();
+        assertEquals("foo5", cache.query(5));
+        assertEquals("foo5", cache.query(5));
+        assertEquals(2, cache.getRecomputeCount());
+        cache.invalidateCache();
+        assertEquals("foo5", cache.query(5));
+        assertEquals("foo5", cache.query(5));
+        assertEquals(3, cache.getRecomputeCount());
+    }
+
+    @Test
+    public void testCachePropertyUnset() {
+        final String UNSET_API = "otherApi";
+        TestCache cache = new TestCache(MODULE, UNSET_API);
+        assertEquals("foo5", cache.query(5));
+        assertEquals("foo5", cache.query(5));
+        assertEquals(2, cache.getRecomputeCount());
+    }
+
+    @Test
+    public void testCacheDisableState() {
+        TestCache cache = new TestCache();
+        assertEquals("foo5", cache.query(5));
+        assertEquals("foo5", cache.query(5));
+        assertEquals(2, cache.getRecomputeCount());
+        cache.invalidateCache();
+        assertEquals("foo5", cache.query(5));
+        assertEquals("foo5", cache.query(5));
+        assertEquals(3, cache.getRecomputeCount());
+        cache.disableSystemWide();
+        assertEquals("foo5", cache.query(5));
+        assertEquals("foo5", cache.query(5));
+        assertEquals(5, cache.getRecomputeCount());
+        cache.invalidateCache();  // Should not reenable
+        assertEquals("foo5", cache.query(5));
+        assertEquals("foo5", cache.query(5));
+        assertEquals(7, cache.getRecomputeCount());
+    }
+
+    @Test
+    public void testLocalProcessDisable() {
+        TestCache cache = new TestCache();
+        assertEquals(cache.isDisabled(), false);
+        cache.invalidateCache();
+        assertEquals("foo5", cache.query(5));
+        assertEquals(1, cache.getRecomputeCount());
+        assertEquals("foo5", cache.query(5));
+        assertEquals(1, cache.getRecomputeCount());
+        assertEquals(cache.isDisabled(), false);
+        cache.disableForCurrentProcess();
+        assertEquals(cache.isDisabled(), true);
+        assertEquals("foo5", cache.query(5));
+        assertEquals("foo5", cache.query(5));
+        assertEquals(3, cache.getRecomputeCount());
+    }
+}
diff --git a/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java b/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
index e6660f3..d01d29b 100644
--- a/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
+++ b/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
@@ -55,11 +55,7 @@
     protected static String OBB_FILE_1_CONTENTS_1 = "OneToOneThousandInts.bin";
     protected static String OBB_FILE_2 = "obb_file2.obb";
     protected static String OBB_FILE_3 = "obb_file3.obb";
-    protected static String OBB_FILE_1_PASSWORD = "password1";
-    protected static String OBB_FILE_1_ENCRYPTED = "obb_enc_file100_orig1.obb";
     protected static String OBB_FILE_2_UNSIGNED = "obb_file2_nosign.obb";
-    protected static String OBB_FILE_3_PASSWORD = "password3";
-    protected static String OBB_FILE_3_ENCRYPTED = "obb_enc_file100_orig3.obb";
     protected static String OBB_FILE_3_BAD_PACKAGENAME = "obb_file3_bad_packagename.obb";
 
     protected static boolean FORCE = true;
@@ -227,22 +223,21 @@
      * Mounts an OBB file
      *
      * @param obbFilePath The full path to the OBB file to mount
-     * @param key (optional) The key to use to unencrypt the OBB; pass null for no encryption
      * @param expectedState The expected state resulting from trying to mount the OBB
      * @return A {@link String} representing the normalized path to OBB file that was mounted
      */
-    protected String mountObb(String obbFilePath, String key, int expectedState) {
-        return doMountObb(obbFilePath, key, expectedState);
+    protected String mountObb(String obbFilePath, int expectedState) {
+        return doMountObb(obbFilePath, expectedState);
     }
 
     /**
-     * Mounts an OBB file with default options (no encryption, mounting succeeds)
+     * Mounts an OBB file with default options.
      *
      * @param obbFilePath The full path to the OBB file to mount
      * @return A {@link String} representing the normalized path to OBB file that was mounted
      */
     protected String mountObb(String obbFilePath) {
-        return doMountObb(obbFilePath, null, OnObbStateChangeListener.MOUNTED);
+        return doMountObb(obbFilePath, OnObbStateChangeListener.MOUNTED);
     }
 
     /**
@@ -279,13 +274,13 @@
      * @return true if the listener was signaled of a state change by the system; else a fail()
      *      is triggered if we timed out
      */
-    protected String doMountObb_noThrow(String obbFilePath, String key, int expectedState) {
-        Log.i(LOG_TAG, "doMountObb() on " + obbFilePath + " using key: " + key);
+    protected String doMountObb_noThrow(String obbFilePath, int expectedState) {
+        Log.i(LOG_TAG, "doMountObb() on " + obbFilePath);
         assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
         assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
 
         ObbListener obbListener = new ObbListener();
-        boolean success = mSm.mountObb(obbFilePath, key, obbListener);
+        boolean success = mSm.mountObb(obbFilePath, null, obbListener);
         success &= obbFilePath.equals(doWaitForObbStateChange(obbListener));
         success &= (expectedState == obbListener.state());
 
@@ -307,17 +302,16 @@
      * Mounts an OBB file without throwing and synchronously waits for it to finish mounting
      *
      * @param obbFilePath The full path to the OBB file to mount
-     * @param key (optional) The key to use to unencrypt the OBB; pass null for no encryption
      * @param expectedState The expected state resulting from trying to mount the OBB
      * @return A {@link String} representing the actual normalized path to OBB file that was
      *      mounted, or null if the mounting failed
      */
-    protected String doMountObb(String obbFilePath, String key, int expectedState) {
-        Log.i(LOG_TAG, "doMountObb() on " + obbFilePath + " using key: " + key);
+    protected String doMountObb(String obbFilePath, int expectedState) {
+        Log.i(LOG_TAG, "doMountObb() on " + obbFilePath);
         assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
 
         ObbListener obbListener = new ObbListener();
-        assertTrue("mountObb call failed", mSm.mountObb(obbFilePath, key, obbListener));
+        assertTrue("mountObb call failed", mSm.mountObb(obbFilePath, null, obbListener));
         assertTrue("Failed to get OBB mount status change for file: " + obbFilePath,
                 doWaitForObbStateChange(obbListener));
         assertEquals("OBB mount state not what was expected!", expectedState,
diff --git a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
index 62f2ac2..ecd2f76 100644
--- a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
+++ b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
@@ -83,58 +83,6 @@
     }
 
     /**
-     * Tests mounting a single encrypted OBB file and verifies its contents.
-     */
-    @LargeTest
-    public void testMountSingleEncryptedObb() throws Exception {
-        final File file = createObbFile(OBB_FILE_3_ENCRYPTED, R.raw.obb_enc_file100_orig3);
-        String filePath = file.getAbsolutePath();
-        mountObb(filePath, OBB_FILE_3_PASSWORD, OnObbStateChangeListener.MOUNTED);
-        verifyObb3Contents(filePath);
-        unmountObb(filePath, DONT_FORCE);
-    }
-
-    /**
-     * Tests mounting a single encrypted OBB file using an invalid password.
-     */
-    @LargeTest
-    public void testMountSingleEncryptedObbInvalidPassword() throws Exception {
-        final File file = createObbFile("bad password@$%#@^*(!&)", R.raw.obb_enc_file100_orig3);
-        String filePath = file.getAbsolutePath();
-        mountObb(filePath, OBB_FILE_1_PASSWORD, OnObbStateChangeListener.ERROR_COULD_NOT_MOUNT);
-    }
-
-    /**
-     * Tests simultaneously mounting 2 encrypted OBBs with different keys and verifies contents.
-     */
-    @LargeTest
-    public void testMountTwoEncryptedObb() throws Exception {
-        File file3 = null;
-        File file1 = null;
-        try {
-            file3 = createObbFile(OBB_FILE_3_ENCRYPTED, R.raw.obb_enc_file100_orig3);
-            String filePath3 = file3.getAbsolutePath();
-            mountObb(filePath3, OBB_FILE_3_PASSWORD, OnObbStateChangeListener.MOUNTED);
-            verifyObb3Contents(filePath3);
-
-            file1 = createObbFile(OBB_FILE_1_ENCRYPTED, R.raw.obb_enc_file100_orig1);
-            String filePath1 = file1.getAbsolutePath();
-            mountObb(filePath1, OBB_FILE_1_PASSWORD, OnObbStateChangeListener.MOUNTED);
-            verifyObb1Contents(filePath1);
-
-            unmountObb(filePath3, DONT_FORCE);
-            unmountObb(filePath1, DONT_FORCE);
-        } finally {
-            if (file3 != null) {
-                file3.delete();
-            }
-            if (file1 != null) {
-                file1.delete();
-            }
-        }
-    }
-
-    /**
      * Tests mounting a single OBB that isn't signed.
      */
     @LargeTest
@@ -142,7 +90,7 @@
         final File file = createObbFile(OBB_FILE_2_UNSIGNED, R.raw.obb_file2_nosign);
         String filePath = file.getAbsolutePath();
         try {
-            mountObb(filePath, OBB_FILE_2_UNSIGNED, OnObbStateChangeListener.ERROR_INTERNAL);
+            mountObb(filePath, OnObbStateChangeListener.ERROR_INTERNAL);
             fail("mountObb should've failed with an exception");
         } catch (IllegalArgumentException e) {
             // Expected
@@ -156,8 +104,7 @@
     public void testMountBadPackageNameObb() throws Exception {
         final File file = createObbFile(OBB_FILE_3_BAD_PACKAGENAME, R.raw.obb_file3_bad_packagename);
         String filePath = file.getAbsolutePath();
-        mountObb(filePath, OBB_FILE_3_BAD_PACKAGENAME,
-                OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
+        mountObb(filePath, OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
     }
 
     /**
@@ -169,7 +116,7 @@
         String filePath = file.getAbsolutePath();
         mountObb(filePath);
         verifyObb1Contents(filePath);
-        mountObb(filePath, null, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
+        mountObb(filePath, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
         verifyObb1Contents(filePath);
         unmountObb(filePath, DONT_FORCE);
     }
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 227a8657..c504f0c 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -30,6 +30,7 @@
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.InsetsState.LAST_TYPE;
+import static android.view.ViewRootImpl.CAPTION_ON_SHELL;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.statusBars;
@@ -758,6 +759,11 @@
 
     @Test
     public void testCaptionInsetsStateAssemble() {
+        if (CAPTION_ON_SHELL) {
+            // For this case, the test is covered by WindowContainerInsetsSourceProviderTest, This
+            // test can be removed after the caption is moved to shell completely.
+            return;
+        }
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             mController.onFrameChanged(new Rect(0, 0, 100, 300));
             final InsetsState state = new InsetsState(mController.getState(), true);
@@ -769,6 +775,7 @@
             assertEquals(captionFrame, currentState.peekSource(ITYPE_CAPTION_BAR).getFrame());
             assertTrue(currentState.equals(state, true /* excludingCaptionInsets*/,
                     true /* excludeInvisibleIme */));
+            // Test update to remove the caption bar
             mController.setCaptionInsetsHeight(0);
             mController.onStateChanged(state);
             // The caption bar source should not be there at all, because we don't add empty
@@ -779,6 +786,11 @@
 
     @Test
     public void testNotifyCaptionInsetsOnlyChange() {
+        if (CAPTION_ON_SHELL) {
+            // For this case, the test is covered by WindowContainerInsetsSourceProviderTest, This
+            // test can be removed after the caption is moved to shell completely.
+            return;
+        }
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             final InsetsState state = new InsetsState(mController.getState(), true);
             reset(mTestHost);
diff --git a/core/tests/coretests/src/android/view/MotionEventTest.java b/core/tests/coretests/src/android/view/MotionEventTest.java
index 78a8f7b..c4c983d 100644
--- a/core/tests/coretests/src/android/view/MotionEventTest.java
+++ b/core/tests/coretests/src/android/view/MotionEventTest.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import static android.view.InputDevice.SOURCE_CLASS_POINTER;
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_POINTER_DOWN;
 import static android.view.MotionEvent.TOOL_TYPE_FINGER;
@@ -214,4 +215,27 @@
         rotInvalid.transform(mat);
         assertEquals(-1, rotInvalid.getSurfaceRotation());
     }
+
+    @Test
+    public void testUsesPointerSourceByDefault() {
+        final MotionEvent event = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */,
+                ACTION_DOWN, 0 /* x */, 0 /* y */, 0 /* metaState */);
+        assertTrue(event.isFromSource(SOURCE_CLASS_POINTER));
+    }
+
+    @Test
+    public void testLocationOffsetOnlyAppliedToNonPointerSources() {
+        final MotionEvent event = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */,
+                ACTION_DOWN, 10 /* x */, 20 /* y */, 0 /* metaState */);
+        event.offsetLocation(40, 50);
+
+        // The offset should be applied since a pointer source is used by default.
+        assertEquals(50, (int) event.getX());
+        assertEquals(70, (int) event.getY());
+
+        // The offset should not be applied if the source is changed to a non-pointer source.
+        event.setSource(InputDevice.SOURCE_JOYSTICK);
+        assertEquals(10, (int) event.getX());
+        assertEquals(20, (int) event.getY());
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index 2817728f..e7a23f2 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -39,6 +39,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
 
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
@@ -52,6 +53,7 @@
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.espresso.Espresso;
+import androidx.test.espresso.NoMatchingViewException;
 import androidx.test.rule.ActivityTestRule;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -750,6 +752,34 @@
     }
 
     @Test
+    public void testMiniResolver_noCurrentProfileTarget() {
+        ResolverActivity.ENABLE_TABBED_VIEW = true;
+        markWorkProfileUserAvailable();
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTest(0);
+        List<ResolvedComponentInfo> workResolvedComponentInfos =
+                createResolvedComponentsForTest(1);
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+        Intent sendIntent = createSendImageIntent();
+        sendIntent.setType("TestType");
+
+        mActivityRule.launchActivity(sendIntent);
+        waitForIdle();
+
+        // Need to ensure mini resolver doesn't trigger here.
+        assertNotMiniResolver();
+    }
+
+    private void assertNotMiniResolver() {
+        try {
+            onView(withId(R.id.open_cross_profile)).check(matches(isDisplayed()));
+        } catch (NoMatchingViewException e) {
+            return;
+        }
+        fail("Mini resolver present but shouldn't be");
+    }
+
+    @Test
     public void testWorkTab_noAppsAvailable_workOff_noAppsAvailableEmptyStateShown() {
         // enable the work tab feature flag
         ResolverActivity.ENABLE_TABBED_VIEW = true;
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index f5cbffb..7ccb9d9 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -17,6 +17,8 @@
 package com.android.internal.os;
 
 import static android.os.BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS;
+import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;
+import static android.os.BatteryStats.RADIO_ACCESS_TECHNOLOGY_COUNT;
 import static android.os.BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR;
 import static android.os.BatteryStats.STATS_SINCE_CHARGED;
 import static android.os.BatteryStats.WAKE_TYPE_PARTIAL;
@@ -24,7 +26,10 @@
 import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU;
 import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY;
 
+import static org.mockito.Mockito.mock;
+
 import android.app.ActivityManager;
+import android.app.usage.NetworkStatsManager;
 import android.os.BatteryStats;
 import android.os.BatteryStats.HistoryItem;
 import android.os.BatteryStats.Uid.Sensor;
@@ -34,6 +39,7 @@
 import android.telephony.Annotation;
 import android.telephony.CellSignalStrength;
 import android.telephony.DataConnectionRealTimeInfo;
+import android.telephony.ModemActivityInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.util.SparseIntArray;
@@ -48,6 +54,8 @@
 
 import junit.framework.TestCase;
 
+import org.mockito.Mock;
+
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
@@ -72,6 +80,13 @@
     private static final int ISOLATED_UID = UserHandle.getUid(0, ISOLATED_APP_ID);
     private static final WorkSource WS = new WorkSource(UID);
 
+    enum ModemState {
+        SLEEP, IDLE, RECEIVING, TRANSMITTING
+    }
+
+    @Mock
+    NetworkStatsManager mNetworkStatsManager;
+
     /**
      * Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked.
      */
@@ -1173,69 +1188,29 @@
     }
 
     @SmallTest
-    public void testGetPerStateActiveRadioDurationMs() {
+    public void testGetPerStateActiveRadioDurationMs_noModemActivity() {
         final MockClock clock = new MockClock(); // holds realtime and uptime in ms
         final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
-        final int ratCount = BatteryStats.RADIO_ACCESS_TECHNOLOGY_COUNT;
+        final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT;
         final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1;
         final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
 
         final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
+        final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount];
+        final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
         for (int rat = 0; rat < ratCount; rat++) {
             for (int freq = 0; freq < frequencyCount; freq++) {
+                // Should have no RX data without Modem Activity Info
+                expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
                 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
                     expectedDurationsMs[rat][freq][txLvl] = 0;
+                    // Should have no TX data without Modem Activity Info
+                    expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
                 }
             }
         }
 
-        class ModemAndBatteryState {
-            public long currentTimeMs = 100;
-            public boolean onBattery = false;
-            public boolean modemActive = false;
-            @Annotation.NetworkType
-            public int currentNetworkDataType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-            @BatteryStats.RadioAccessTechnology
-            public int currentRat = BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER;
-            @ServiceState.FrequencyRange
-            public int currentFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
-            public SparseIntArray currentSignalStrengths = new SparseIntArray();
-
-            void setOnBattery(boolean onBattery) {
-                this.onBattery = onBattery;
-                bi.updateTimeBasesLocked(onBattery, Display.STATE_OFF, currentTimeMs * 1000,
-                        currentTimeMs * 1000);
-            }
-
-            void setModemActive(boolean active) {
-                modemActive = active;
-                final int state = active ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
-                        : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
-                bi.noteMobileRadioPowerStateLocked(state, currentTimeMs * 1000_000L, UID);
-            }
-
-            void setRatType(@Annotation.NetworkType int dataType,
-                    @BatteryStats.RadioAccessTechnology int rat) {
-                currentNetworkDataType = dataType;
-                currentRat = rat;
-                bi.notePhoneDataConnectionStateLocked(dataType, true, ServiceState.STATE_IN_SERVICE,
-                        currentFrequencyRange);
-            }
-
-            void setFrequencyRange(@ServiceState.FrequencyRange int frequency) {
-                currentFrequencyRange = frequency;
-                bi.notePhoneDataConnectionStateLocked(currentNetworkDataType, true,
-                        ServiceState.STATE_IN_SERVICE, frequency);
-            }
-
-            void setSignalStrength(@BatteryStats.RadioAccessTechnology int rat, int strength) {
-                currentSignalStrengths.put(rat, strength);
-                final int size = currentSignalStrengths.size();
-                final int newestGenSignalStrength = currentSignalStrengths.valueAt(size - 1);
-                bi.notePhoneSignalStrengthLocked(newestGenSignalStrength, currentSignalStrengths);
-            }
-        }
-        final ModemAndBatteryState state = new ModemAndBatteryState();
+        final ModemAndBatteryState state = new ModemAndBatteryState(bi, null);
 
         IntConsumer incrementTime = inc -> {
             state.currentTimeMs += inc;
@@ -1253,6 +1228,7 @@
             expectedDurationsMs[currentRat][currentFrequencyRange][currentSignalStrength] += inc;
         };
 
+
         state.setOnBattery(false);
         state.setModemActive(false);
         state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN,
@@ -1260,95 +1236,367 @@
         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN);
         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
                 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         // While not on battery, the timers should not increase.
         state.setModemActive(true);
         incrementTime.accept(100);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
         incrementTime.accept(200);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
                 CellSignalStrength.SIGNAL_STRENGTH_GOOD);
         incrementTime.accept(500);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE);
         incrementTime.accept(300);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         state.setRatType(TelephonyManager.NETWORK_TYPE_LTE,
                 BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE);
         incrementTime.accept(400);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
                 CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
         incrementTime.accept(500);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         // When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should
         // start counting up.
         state.setOnBattery(true);
         incrementTime.accept(600);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
-
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
         // Changing LTE signal strength should be tracked.
         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
                 CellSignalStrength.SIGNAL_STRENGTH_POOR);
         incrementTime.accept(700);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
                 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
         incrementTime.accept(800);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
                 CellSignalStrength.SIGNAL_STRENGTH_GOOD);
         incrementTime.accept(900);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
                 CellSignalStrength.SIGNAL_STRENGTH_GREAT);
         incrementTime.accept(1000);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         // Change in the signal strength of nonactive RAT should not affect anything.
         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
                 CellSignalStrength.SIGNAL_STRENGTH_POOR);
         incrementTime.accept(1100);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         // Changing to OTHER Rat should start tracking the poor signal strength.
         state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA,
                 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER);
         incrementTime.accept(1200);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         // Noting frequency change should not affect non NR Rat.
         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH);
         incrementTime.accept(1300);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         // Now the NR Rat, HIGH frequency range, good signal strength should start counting.
         state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
         incrementTime.accept(1400);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         // Noting frequency change should not affect non NR Rat.
         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW);
         incrementTime.accept(1500);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
 
         // Modem no longer active, should not be tracking any more.
         state.setModemActive(false);
         incrementTime.accept(1500);
-        checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+    }
 
+    @SmallTest
+    public void testGetPerStateActiveRadioDurationMs_withModemActivity() {
+        final MockClock clock = new MockClock(); // holds realtime and uptime in ms
+        final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
+        bi.setPowerProfile(mock(PowerProfile.class));
+        final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT;
+        final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1;
+        final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
+
+        final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
+        final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount];
+        final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
+        for (int rat = 0; rat < ratCount; rat++) {
+            for (int freq = 0; freq < frequencyCount; freq++) {
+                if (rat != RADIO_ACCESS_TECHNOLOGY_NR
+                        && freq != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+                    // Only the NR RAT should have per frequency data.
+                    expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
+                } else {
+                    expectedRxDurationsMs[rat][freq] = 0;
+                }
+                expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
+
+                for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
+                    expectedDurationsMs[rat][freq][txLvl] = 0;
+
+                    if (rat != RADIO_ACCESS_TECHNOLOGY_NR
+                            && freq != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+                        // Only the NR RAT should have per frequency data.
+                        expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
+                    } else {
+                        expectedTxDurationsMs[rat][freq][txLvl] = 0;
+                    }
+                    expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
+                }
+            }
+        }
+
+        final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, new int[txLevelCount], 0L);
+        final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai);
+
+        IntConsumer incrementTime = inc -> {
+            state.currentTimeMs += inc;
+            clock.realtime = clock.uptime = state.currentTimeMs;
+
+            // If the device is not on battery, no timers should increment.
+            if (!state.onBattery) return;
+            // If the modem is not active, no timers should increment.
+            if (!state.modemActive) return;
+
+            final int currRat = state.currentRat;
+            final int currFreqRange =
+                    currRat == RADIO_ACCESS_TECHNOLOGY_NR ? state.currentFrequencyRange : 0;
+            int currSignalStrength = state.currentSignalStrengths.get(currRat);
+
+            expectedDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
+
+            // Evaluate the HAL provided time in states.
+            switch (state.modemState) {
+                case SLEEP:
+                    long sleepMs = state.modemActivityInfo.getSleepTimeMillis();
+                    state.modemActivityInfo.setSleepTimeMillis(sleepMs + inc);
+                    break;
+                case IDLE:
+                    long idleMs = state.modemActivityInfo.getIdleTimeMillis();
+                    state.modemActivityInfo.setIdleTimeMillis(idleMs + inc);
+                    break;
+                case RECEIVING:
+                    long rxMs = state.modemActivityInfo.getReceiveTimeMillis();
+                    state.modemActivityInfo.setReceiveTimeMillis(rxMs + inc);
+                    expectedRxDurationsMs[currRat][currFreqRange] += inc;
+                    break;
+                case TRANSMITTING:
+                    int[] txMs = state.modemActivityInfo.getTransmitTimeMillis();
+                    txMs[currSignalStrength] += inc;
+                    state.modemActivityInfo.setTransmitTimeMillis(txMs);
+                    expectedTxDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
+                    break;
+            }
+        };
+
+        state.setOnBattery(false);
+        state.setModemActive(false);
+        state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN,
+                BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER);
+        state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN);
+        state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+                CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        // While not on battery, the timers should not increase.
+        state.setModemActive(true);
+        incrementTime.accept(100);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
+        incrementTime.accept(200);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
+                CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+        incrementTime.accept(500);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE);
+        incrementTime.accept(300);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        state.setRatType(TelephonyManager.NETWORK_TYPE_LTE,
+                BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE);
+        incrementTime.accept(400);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+                CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
+        incrementTime.accept(500);
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        // Data will now be available.
+        for (int rat = 0; rat < ratCount; rat++) {
+            for (int freq = 0; freq < frequencyCount; freq++) {
+                if (rat == RADIO_ACCESS_TECHNOLOGY_NR
+                        || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+                    // Only the NR RAT should have per frequency data.
+                    expectedRxDurationsMs[rat][freq] = 0;
+                }
+                for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
+                    if (rat == RADIO_ACCESS_TECHNOLOGY_NR
+                            || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+                        // Only the NR RAT should have per frequency data.
+                        expectedTxDurationsMs[rat][freq][txLvl] = 0;
+                    }
+                }
+            }
+        }
+
+        // When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should
+        // start counting up.
+        state.setOnBattery(true);
+        incrementTime.accept(300);
+        state.setModemState(ModemState.RECEIVING);
+        incrementTime.accept(500);
+        state.setModemState(ModemState.TRANSMITTING);
+        incrementTime.accept(600);
+        state.noteModemControllerActivity();
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+        // Changing LTE signal strength should be tracked.
+        state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+                CellSignalStrength.SIGNAL_STRENGTH_POOR);
+        incrementTime.accept(300);
+        state.setModemState(ModemState.SLEEP);
+        incrementTime.accept(1000);
+        state.setModemState(ModemState.RECEIVING);
+        incrementTime.accept(700);
+        state.noteModemControllerActivity();
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+                CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
+        incrementTime.accept(800);
+        state.setModemState(ModemState.TRANSMITTING);
+        incrementTime.accept(222);
+        state.setModemState(ModemState.IDLE);
+        incrementTime.accept(111);
+        state.setModemState(ModemState.RECEIVING);
+        incrementTime.accept(7777);
+        state.noteModemControllerActivity();
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+                CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+        incrementTime.accept(88);
+        state.setModemState(ModemState.TRANSMITTING);
+        incrementTime.accept(900);
+        state.noteModemControllerActivity();
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+                CellSignalStrength.SIGNAL_STRENGTH_GREAT);
+        incrementTime.accept(123);
+        state.setModemState(ModemState.RECEIVING);
+        incrementTime.accept(333);
+        state.setModemState(ModemState.TRANSMITTING);
+        incrementTime.accept(1000);
+        state.setModemState(ModemState.RECEIVING);
+        incrementTime.accept(555);
+        state.noteModemControllerActivity();
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        // Change in the signal strength of nonactive RAT should not affect anything.
+        state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+                CellSignalStrength.SIGNAL_STRENGTH_POOR);
+        incrementTime.accept(631);
+        state.setModemState(ModemState.TRANSMITTING);
+        incrementTime.accept(321);
+        state.setModemState(ModemState.RECEIVING);
+        incrementTime.accept(99);
+        state.noteModemControllerActivity();
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        // Changing to OTHER Rat should start tracking the poor signal strength.
+        state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA,
+                BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER);
+        incrementTime.accept(1200);
+        state.noteModemControllerActivity();
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        // Noting frequency change should not affect non NR Rat.
+        state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH);
+        incrementTime.accept(444);
+        state.setModemState(ModemState.TRANSMITTING);
+        incrementTime.accept(1300);
+        state.noteModemControllerActivity();
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        // Now the NR Rat, HIGH frequency range, good signal strength should start counting.
+        state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
+        incrementTime.accept(1400);
+        state.noteModemControllerActivity();
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        // Frequency changed to low.
+        state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW);
+        incrementTime.accept(852);
+        state.setModemState(ModemState.RECEIVING);
+        incrementTime.accept(157);
+        state.setModemState(ModemState.TRANSMITTING);
+        incrementTime.accept(1500);
+        state.noteModemControllerActivity();
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
+
+        // Modem no longer active, should not be tracking any more.
+        state.setModemActive(false);
+        incrementTime.accept(1500);
+        state.noteModemControllerActivity();
+        checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+                expectedTxDurationsMs, bi, state.currentTimeMs);
     }
 
     private void setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi) {
@@ -1426,28 +1674,124 @@
     }
 
     private void checkPerStateActiveRadioDurations(long[][][] expectedDurationsMs,
+            long[][] expectedRxDurationsMs, long[][][] expectedTxDurationsMs,
             BatteryStatsImpl bi, long currentTimeMs) {
         for (int rat = 0; rat < expectedDurationsMs.length; rat++) {
             final long[][] expectedRatDurationsMs = expectedDurationsMs[rat];
             for (int freq = 0; freq < expectedRatDurationsMs.length; freq++) {
+                final long expectedRxDurationMs = expectedRxDurationsMs[rat][freq];
+
+                // Build a verbose fail message, just in case.
+                final StringBuilder rxFailSb = new StringBuilder();
+                rxFailSb.append("Wrong time in Rx state for RAT:");
+                rxFailSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]);
+                rxFailSb.append(", frequency:");
+                rxFailSb.append(ServiceState.frequencyRangeToString(freq));
+                assertEquals(rxFailSb.toString(), expectedRxDurationMs,
+                        bi.getActiveRxRadioDurationMs(rat, freq, currentTimeMs));
+
                 final long[] expectedFreqDurationsMs = expectedRatDurationsMs[freq];
                 for (int strength = 0; strength < expectedFreqDurationsMs.length; strength++) {
                     final long expectedSignalStrengthDurationMs = expectedFreqDurationsMs[strength];
+                    final long expectedTxDurationMs = expectedTxDurationsMs[rat][freq][strength];
                     final long actualDurationMs = bi.getActiveRadioDurationMs(rat, freq,
                             strength, currentTimeMs);
 
-                    // Build a verbose fail message, just in case.
-                    final StringBuilder sb = new StringBuilder();
-                    sb.append("Wrong time in state for RAT:");
-                    sb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]);
-                    sb.append(", frequency:");
-                    sb.append(ServiceState.frequencyRangeToString(freq));
-                    sb.append(", strength:");
-                    sb.append(strength);
+                    final StringBuilder failSb = new StringBuilder();
+                    failSb.append("Wrong time in state for RAT:");
+                    failSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]);
+                    failSb.append(", frequency:");
+                    failSb.append(ServiceState.frequencyRangeToString(freq));
+                    failSb.append(", strength:");
+                    failSb.append(strength);
+                    assertEquals(failSb.toString(), expectedSignalStrengthDurationMs,
+                            actualDurationMs);
 
-                    assertEquals(sb.toString(), expectedSignalStrengthDurationMs, actualDurationMs);
+                    final StringBuilder txFailSb = new StringBuilder();
+                    txFailSb.append("Wrong time in Tx state for RAT:");
+                    txFailSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]);
+                    txFailSb.append(", frequency:");
+                    txFailSb.append(ServiceState.frequencyRangeToString(freq));
+                    txFailSb.append(", strength:");
+                    txFailSb.append(strength);
+                    assertEquals(txFailSb.toString(), expectedTxDurationMs,
+                            bi.getActiveTxRadioDurationMs(rat, freq, strength, currentTimeMs));
                 }
             }
         }
     }
+
+    private class ModemAndBatteryState {
+        public long currentTimeMs = 100;
+        public boolean onBattery = false;
+        public boolean modemActive = false;
+        @Annotation.NetworkType
+        public int currentNetworkDataType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        @BatteryStats.RadioAccessTechnology
+        public int currentRat = BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER;
+        @ServiceState.FrequencyRange
+        public int currentFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
+        public SparseIntArray currentSignalStrengths = new SparseIntArray();
+        public ModemState modemState = ModemState.SLEEP;
+        public ModemActivityInfo modemActivityInfo;
+
+        private final MockBatteryStatsImpl mBsi;
+
+        ModemAndBatteryState(MockBatteryStatsImpl bsi, ModemActivityInfo mai) {
+            mBsi = bsi;
+            modemActivityInfo = mai;
+        }
+
+        void setOnBattery(boolean onBattery) {
+            this.onBattery = onBattery;
+            mBsi.updateTimeBasesLocked(onBattery, Display.STATE_OFF, currentTimeMs * 1000,
+                    currentTimeMs * 1000);
+            mBsi.setOnBatteryInternal(onBattery);
+            noteModemControllerActivity();
+        }
+
+        void setModemActive(boolean active) {
+            modemActive = active;
+            final int state = active ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
+                    : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
+            mBsi.noteMobileRadioPowerStateLocked(state, currentTimeMs * 1000_000L, UID);
+            noteModemControllerActivity();
+        }
+
+        void setRatType(@Annotation.NetworkType int dataType,
+                @BatteryStats.RadioAccessTechnology int rat) {
+            currentNetworkDataType = dataType;
+            currentRat = rat;
+            mBsi.notePhoneDataConnectionStateLocked(dataType, true, ServiceState.STATE_IN_SERVICE,
+                    currentFrequencyRange);
+        }
+
+        void setFrequencyRange(@ServiceState.FrequencyRange int frequency) {
+            currentFrequencyRange = frequency;
+            mBsi.notePhoneDataConnectionStateLocked(currentNetworkDataType, true,
+                    ServiceState.STATE_IN_SERVICE, frequency);
+        }
+
+        void setSignalStrength(@BatteryStats.RadioAccessTechnology int rat, int strength) {
+            currentSignalStrengths.put(rat, strength);
+            final int size = currentSignalStrengths.size();
+            final int newestGenSignalStrength = currentSignalStrengths.valueAt(size - 1);
+            mBsi.notePhoneSignalStrengthLocked(newestGenSignalStrength, currentSignalStrengths);
+        }
+
+        void setModemState(ModemState state) {
+            modemState = state;
+        }
+
+        void noteModemControllerActivity() {
+            if (modemActivityInfo == null) return;
+            modemActivityInfo.setTimestamp(currentTimeMs);
+            ModemActivityInfo copy = new ModemActivityInfo(modemActivityInfo.getTimestampMillis(),
+                    modemActivityInfo.getSleepTimeMillis(), modemActivityInfo.getIdleTimeMillis(),
+                    modemActivityInfo.getTransmitTimeMillis().clone(),
+                    modemActivityInfo.getReceiveTimeMillis());
+            mBsi.noteModemControllerActivity(copy, POWER_DATA_UNAVAILABLE,
+                    currentTimeMs, currentTimeMs, mNetworkStatsManager);
+        }
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
index 0e394c1..bfb3449 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
@@ -30,6 +30,7 @@
 public class BatteryStatsSensorTest extends TestCase {
 
     private static final int UID = 10500;
+    private static final int UID_2 = 10501; // second uid for testing pool usage
     private static final int SENSOR_ID = -10000;
 
     @SmallTest
@@ -239,7 +240,6 @@
 
     @SmallTest
     public void testPooledBackgroundUsage() throws Exception {
-        final int UID_2 = 20000; // second uid for testing pool usage
         final MockClock clocks = new MockClock();
         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
         bi.mForceOnBattery = true;
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
index 5adc9bd..483224c 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
@@ -20,6 +20,7 @@
 import static android.os.BatteryConsumer.POWER_MODEL_MEASURED_ENERGY;
 import static android.os.BatteryConsumer.POWER_MODEL_UNDEFINED;
 import static android.os.BatteryConsumer.PROCESS_STATE_BACKGROUND;
+import static android.os.BatteryConsumer.PROCESS_STATE_CACHED;
 import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND;
 import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE;
 
@@ -83,7 +84,7 @@
         final Parcel parcel = Parcel.obtain();
         parcel.writeParcelable(outBatteryUsageStats, 0);
 
-        assertThat(parcel.dataSize()).isLessThan(7000);
+        assertThat(parcel.dataSize()).isLessThan(8000);
 
         parcel.setDataPosition(0);
 
@@ -155,10 +156,11 @@
         assertThat(dump).contains("cpu(fg): 2333 apps: 1333 duration: 3s 332ms");
         assertThat(dump).contains("cpu(bg): 2444 apps: 1444 duration: 4s 442ms");
         assertThat(dump).contains("cpu(fgs): 2555 apps: 1555 duration: 5s 552ms");
+        assertThat(dump).contains("cpu(cached): 123 apps: 123 duration: 456ms");
         assertThat(dump).contains("FOO: 20200 apps: 10200 duration: 20s 400ms");
-        assertThat(dump).contains("UID 271: 1200 fg: 1777 bg: 1888 fgs: 1999 ( screen=300 "
-                + "cpu=400 (600ms) cpu:fg=1777 (7s 771ms) cpu:bg=1888 (8s 881ms) "
-                + "cpu:fgs=1999 (9s 991ms) FOO=500 )");
+        assertThat(dump).contains("UID 271: 1200 fg: 1777 bg: 1888 fgs: 1999 cached: 123 "
+                + "( screen=300 cpu=400 (600ms) cpu:fg=1777 (7s 771ms) cpu:bg=1888 (8s 881ms) "
+                + "cpu:fgs=1999 (9s 991ms) cpu:cached=123 (456ms) FOO=500 )");
         assertThat(dump).contains("User 42: 30.0 ( cpu=10.0 (30ms) FOO=20.0 )");
     }
 
@@ -193,13 +195,15 @@
                         5321, 7432, 423, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 745,
                         POWER_MODEL_UNDEFINED,
                         956, 1167, 1478,
-                        true, 3554, 3776, 3998, 3554, 15542, 3776, 17762, 3998, 19982);
+                        true, 3554, 3776, 3998, 444, 3554, 15542, 3776, 17762, 3998, 19982,
+                        444, 1110);
             } else if (uidBatteryConsumer.getUid() == APP_UID2) {
                 assertUidBatteryConsumer(uidBatteryConsumer, 1332, "bar",
                         1111, 2222, 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
                         BatteryConsumer.POWER_MODEL_POWER_PROFILE,
                         555, 666, 777,
-                        true, 1777, 1888, 1999, 1777, 7771, 1888, 8881, 1999, 9991);
+                        true, 1777, 1888, 1999, 321, 1777, 7771, 1888, 8881, 1999, 9991,
+                        321, 654);
             } else {
                 fail("Unexpected UID " + uidBatteryConsumer.getUid());
             }
@@ -267,17 +271,17 @@
                 1000, 2000,
                 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
                 BatteryConsumer.POWER_MODEL_POWER_PROFILE, 500, 600, 800,
-                1777, 7771, 1888, 8881, 1999, 9991);
+                1777, 7771, 1888, 8881, 1999, 9991, 123, 456);
 
         addAggregateBatteryConsumer(builder,
                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, 0,
                 10100, 10200, 10300, 10400,
-                1333, 3331, 1444, 4441, 1555, 5551);
+                1333, 3331, 1444, 4441, 1555, 5551, 123, 456);
 
         addAggregateBatteryConsumer(builder,
                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, 30000,
                 20100, 20200, 20300, 20400,
-                2333, 3332, 2444, 4442, 2555, 5552);
+                2333, 3332, 2444, 4442, 2555, 5552, 123, 456);
 
         if (includeUserBatteryConsumer) {
             builder.getOrCreateUserBatteryConsumerBuilder(USER_ID)
@@ -310,23 +314,23 @@
                 4321, 5432,
                 123, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 345, POWER_MODEL_MEASURED_ENERGY,
                 456, 567, 678,
-                1777, 7771, 1888, 8881, 1999, 9991);
+                1777, 7771, 1888, 8881, 1999, 9991, 321, 654);
 
         addUidBatteryConsumer(builder, batteryStats, APP_UID2, "bar",
                 1111, 2222,
                 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
                 BatteryConsumer.POWER_MODEL_POWER_PROFILE, 555, 666, 777,
-                1777, 7771, 1888, 8881, 1999, 9991);
+                1777, 7771, 1888, 8881, 1999, 9991, 321, 654);
 
         addAggregateBatteryConsumer(builder,
                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, 0,
                 10123, 10234, 10345, 10456,
-                4333, 3334, 5444, 4445, 6555, 5556);
+                4333, 3334, 5444, 4445, 6555, 5556, 321, 654);
 
         addAggregateBatteryConsumer(builder,
                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, 12345,
                 20111, 20222, 20333, 20444,
-                7333, 3337, 8444, 4448, 9555, 5559);
+                7333, 3337, 8444, 4448, 9555, 5559, 123, 456);
 
         return builder;
     }
@@ -337,7 +341,7 @@
             int screenPowerModel, double cpuPower, int cpuPowerModel, double customComponentPower,
             int cpuDuration, int customComponentDuration, double cpuPowerForeground,
             int cpuDurationForeground, double cpuPowerBackground, int cpuDurationBackground,
-            double cpuPowerFgs, int cpuDurationFgs) {
+            double cpuPowerFgs, int cpuDurationFgs, double cpuPowerCached, long cpuDurationCached) {
         final BatteryStatsImpl.Uid batteryStatsUid = batteryStats.getUidStatsLocked(uid);
         final UidBatteryConsumer.Builder uidBuilder =
                 builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid);
@@ -365,6 +369,9 @@
             final BatteryConsumer.Key cpuFgsKey = uidBuilder.getKey(
                     BatteryConsumer.POWER_COMPONENT_CPU,
                     BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);
+            final BatteryConsumer.Key cachedKey = uidBuilder.getKey(
+                    BatteryConsumer.POWER_COMPONENT_CPU,
+                    BatteryConsumer.PROCESS_STATE_CACHED);
             uidBuilder
                     .setConsumedPower(cpuFgKey, cpuPowerForeground,
                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
@@ -374,7 +381,10 @@
                     .setUsageDurationMillis(cpuBgKey, cpuDurationBackground)
                     .setConsumedPower(cpuFgsKey, cpuPowerFgs,
                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
-                    .setUsageDurationMillis(cpuFgsKey, cpuDurationFgs);
+                    .setUsageDurationMillis(cpuFgsKey, cpuDurationFgs)
+                    .setConsumedPower(cachedKey, cpuPowerCached,
+                            BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+                    .setUsageDurationMillis(cachedKey, cpuDurationCached);
         }
     }
 
@@ -382,7 +392,7 @@
             double consumedPower, int cpuPower, int customComponentPower, int cpuDuration,
             int customComponentDuration, double cpuPowerForeground, long cpuDurationForeground,
             double cpuPowerBackground, long cpuDurationBackground, double cpuPowerFgs,
-            long cpuDurationFgs) {
+            long cpuDurationFgs, double cpuPowerCached, long cpuDurationCached) {
         final AggregateBatteryConsumer.Builder aggBuilder =
                 builder.getAggregateBatteryConsumerBuilder(scope)
                         .setConsumedPower(consumedPower)
@@ -406,6 +416,9 @@
             final BatteryConsumer.Key cpuFgsKey = aggBuilder.getKey(
                     BatteryConsumer.POWER_COMPONENT_CPU,
                     BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);
+            final BatteryConsumer.Key cpuCachedKey = aggBuilder.getKey(
+                    BatteryConsumer.POWER_COMPONENT_CPU,
+                    BatteryConsumer.PROCESS_STATE_CACHED);
             aggBuilder
                     .setConsumedPower(cpuFgKey, cpuPowerForeground,
                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
@@ -415,7 +428,10 @@
                     .setUsageDurationMillis(cpuBgKey, cpuDurationBackground)
                     .setConsumedPower(cpuFgsKey, cpuPowerFgs,
                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
-                    .setUsageDurationMillis(cpuFgsKey, cpuDurationFgs);
+                    .setUsageDurationMillis(cpuFgsKey, cpuDurationFgs)
+                    .setConsumedPower(cpuCachedKey, cpuPowerCached,
+                            BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+                    .setUsageDurationMillis(cpuCachedKey, cpuDurationCached);
         }
     }
 
@@ -432,7 +448,7 @@
                         1000, 2000, 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
                         BatteryConsumer.POWER_MODEL_POWER_PROFILE,
                         500, 600, 800,
-                        true, 1777, 1888, 1999, 1777, 7771, 1888, 8881, 1999, 9991);
+                        true, 1777, 1888, 1999, 123, 1777, 7771, 1888, 8881, 1999, 9991, 123, 456);
             } else {
                 fail("Unexpected UID " + uidBatteryConsumer.getUid());
             }
@@ -484,8 +500,10 @@
             int cpuPowerModel, double customComponentPower, int cpuDuration,
             int customComponentDuration, boolean processStateDataIncluded,
             double totalPowerForeground, double totalPowerBackground, double totalPowerFgs,
-            double cpuPowerForeground, int cpuDurationForeground, double cpuPowerBackground,
-            int cpuDurationBackground, double cpuPowerFgs, int cpuDurationFgs) {
+            double totalPowerCached, double cpuPowerForeground, int cpuDurationForeground,
+            double cpuPowerBackground,
+            int cpuDurationBackground, double cpuPowerFgs, int cpuDurationFgs,
+            int cpuPowerCached, int cpuDurationCached) {
         assertThat(uidBatteryConsumer.getConsumedPower()).isEqualTo(consumedPower);
         assertThat(uidBatteryConsumer.getPackageWithHighestDrain()).isEqualTo(
                 packageWithHighestDrain);
@@ -525,6 +543,10 @@
                     new BatteryConsumer.Dimensions(POWER_COMPONENT_ANY,
                             PROCESS_STATE_FOREGROUND_SERVICE)))
                     .isEqualTo(totalPowerFgs);
+            assertThat(uidBatteryConsumer.getConsumedPower(
+                    new BatteryConsumer.Dimensions(POWER_COMPONENT_ANY,
+                            PROCESS_STATE_CACHED)))
+                    .isEqualTo(totalPowerCached);
         }
 
         final BatteryConsumer.Key cpuFgKey = uidBatteryConsumer.getKey(
@@ -563,6 +585,19 @@
         } else {
             assertThat(cpuFgsKey).isNotNull();
         }
+
+        final BatteryConsumer.Key cachedKey = uidBatteryConsumer.getKey(
+                BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_CACHED);
+        if (processStateDataIncluded) {
+            assertThat(cachedKey).isNotNull();
+            assertThat(uidBatteryConsumer.getConsumedPower(cachedKey))
+                    .isEqualTo(cpuPowerCached);
+            assertThat(uidBatteryConsumer.getUsageDurationMillis(cachedKey))
+                    .isEqualTo(cpuDurationCached);
+        } else {
+            assertThat(cpuFgsKey).isNotNull();
+        }
     }
 
     private void assertUserBatteryConsumer(UserBatteryConsumer userBatteryConsumer,
diff --git a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
index 448f666..fdbf071 100644
--- a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
@@ -145,10 +145,14 @@
         final BatteryConsumer.Key fgs = uidConsumer.getKey(
                 BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
                 BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);
+        final BatteryConsumer.Key cached = uidConsumer.getKey(
+                BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
+                BatteryConsumer.PROCESS_STATE_CACHED);
 
         assertThat(uidConsumer.getConsumedPower(foreground)).isWithin(PRECISION).of(0.081);
         assertThat(uidConsumer.getConsumedPower(background)).isWithin(PRECISION).of(0.0416666);
         assertThat(uidConsumer.getConsumedPower(fgs)).isWithin(PRECISION).of(0);
+        assertThat(uidConsumer.getConsumedPower(cached)).isWithin(PRECISION).of(0);
     }
 
     @Test
@@ -261,10 +265,14 @@
         final BatteryConsumer.Key fgs = uidConsumer.getKey(
                 BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
                 BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);
+        final BatteryConsumer.Key cached = uidConsumer.getKey(
+                BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
+                BatteryConsumer.PROCESS_STATE_CACHED);
 
         assertThat(uidConsumer.getConsumedPower(foreground)).isWithin(PRECISION).of(0.4965352);
         assertThat(uidConsumer.getConsumedPower(background)).isWithin(PRECISION).of(0.3255208);
         assertThat(uidConsumer.getConsumedPower(fgs)).isWithin(PRECISION).of(0);
+        assertThat(uidConsumer.getConsumedPower(cached)).isWithin(PRECISION).of(0);
     }
 
 
diff --git a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
index b89e8bc..ec45a01 100644
--- a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
@@ -232,7 +232,7 @@
         assertThat(entry3.handlerClassName).isEqualTo(
                 "com.android.internal.os.LooperStatsTest$TestHandlerSecond");
         assertThat(entry3.messageName).startsWith(
-                "com.android.internal.os.LooperStatsTest$$ExternalSyntheticLambda4");
+                "com.android.internal.os.LooperStatsTest$$ExternalSyntheticLambda5");
         assertThat(entry3.messageCount).isEqualTo(1);
         assertThat(entry3.recordedMessageCount).isEqualTo(1);
         assertThat(entry3.exceptionCount).isEqualTo(0);
diff --git a/core/tests/coretests/src/com/android/internal/widget/CachingIconViewTest.java b/core/tests/coretests/src/com/android/internal/widget/CachingIconViewTest.java
new file mode 100644
index 0000000..0d4b449
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/widget/CachingIconViewTest.java
@@ -0,0 +1,250 @@
+/*
+ * 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.internal.widget;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.graphics.drawable.InsetDrawable;
+import android.net.Uri;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CachingIconViewTest {
+
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+    }
+
+    @Test
+    public void customDrawable_setImageIcon_skipsResizeSuccessfully() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageIcon(Icon.createWithResource(mContext, R.drawable.custom_drawable));
+        Drawable drawable = view.getDrawable();
+        assertThat(drawable).isInstanceOf(InsetDrawable.class);
+    }
+
+    @Test
+    public void customDrawable_setImageIconAsync_skipsResizeSuccessfully() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageIconAsync(Icon.createWithResource(mContext, R.drawable.custom_drawable)).run();
+        Drawable drawable = view.getDrawable();
+        assertThat(drawable).isInstanceOf(InsetDrawable.class);
+    }
+
+    @Test
+    public void customDrawable_setImageResource_skipsResizeSuccessfully() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageResource(R.drawable.custom_drawable);
+        Drawable drawable = view.getDrawable();
+        assertThat(drawable).isInstanceOf(InsetDrawable.class);
+    }
+
+    @Test
+    public void customDrawable_setImageResourceAsync_skipsResizeSuccessfully() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageResourceAsync(R.drawable.custom_drawable).run();
+        Drawable drawable = view.getDrawable();
+        assertThat(drawable).isInstanceOf(InsetDrawable.class);
+    }
+
+    @Test
+    public void customDrawable_setImageUri_skipsResizeSuccessfully() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageURI(Uri.parse(
+                "android.resource://com.android.frameworks.coretests/"
+                        + R.drawable.custom_drawable));
+        Drawable drawable = view.getDrawable();
+        assertThat(drawable).isInstanceOf(InsetDrawable.class);
+    }
+
+    @Test
+    public void customDrawable_setImageUriAsync_skipsResizeSuccessfully() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageURIAsync(Uri.parse(
+                "android.resource://com.android.frameworks.coretests/"
+                        + R.drawable.custom_drawable)).run();
+        Drawable drawable = view.getDrawable();
+        assertThat(drawable).isInstanceOf(InsetDrawable.class);
+    }
+
+    @Test
+    public void maxDrawableDimensionsSet_setImageIcon_resizesImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageIcon(Icon.createWithResource(mContext, R.drawable.big_a));
+
+        assertDrawableResized(view);
+    }
+
+    @Test
+    public void maxDrawableWithNoDimensionsSet_setImageIcon_doesNotResizeImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_no_max_size, null);
+        view.setImageIcon(Icon.createWithResource(mContext, R.drawable.big_a));
+
+        assertDrawableNotResized(view);
+    }
+
+    @Test
+    public void maxDrawableDimensionsSet_setImageIconAsync_resizesImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageIconAsync(Icon.createWithResource(mContext, R.drawable.big_a)).run();
+
+        assertDrawableResized(view);
+    }
+
+    @Test
+    public void maxDrawableWithNoDimensionsSet_setImageIconAsync_doesNotResizeImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_no_max_size, null);
+        view.setImageIconAsync(Icon.createWithResource(mContext, R.drawable.big_a)).run();
+
+        assertDrawableNotResized(view);
+    }
+
+    @Test
+    public void maxDrawableDimensionsSet_setImageResource_resizesImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageResource(R.drawable.big_a);
+
+        assertDrawableResized(view);
+    }
+
+    @Test
+    public void maxDrawableWithNoDimensionsSet_setImageResource_doesNotResizeImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_no_max_size, null);
+        view.setImageResource(R.drawable.big_a);
+
+        assertDrawableNotResized(view);
+    }
+
+    @Test
+    public void maxDrawableDimensionsSet_setImageResourceAsync_resizesImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageResourceAsync(R.drawable.big_a).run();
+
+        assertDrawableResized(view);
+    }
+
+    @Test
+    public void maxDrawableWithNoDimensionsSet_setImageResourceAsync_doesNotResizeImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_no_max_size, null);
+        view.setImageResourceAsync(R.drawable.big_a).run();
+
+        assertDrawableNotResized(view);
+    }
+
+    @Test
+    public void maxDrawableDimensionsSet_setImageUri_resizesImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageURI(Uri.parse(
+                "android.resource://com.android.frameworks.coretests/" + R.drawable.big_a));
+
+        assertDrawableResized(view);
+    }
+
+    @Test
+    public void maxDrawableWithNoDimensionsSet_setImageUri_doesNotResizeImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_no_max_size, null);
+        view.setImageURI(Uri.parse(
+                "android.resource://com.android.frameworks.coretests/" + R.drawable.big_a));
+
+        assertDrawableNotResized(view);
+    }
+
+    @Test
+    public void maxDrawableDimensionsSet_setImageUriAsync_resizesImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_max_size, null);
+        view.setImageURIAsync(Uri.parse(
+                "android.resource://com.android.frameworks.coretests/" + R.drawable.big_a)).run();
+
+        assertDrawableResized(view);
+    }
+
+    @Test
+    public void maxDrawableWithNoDimensionsSet_setImageUriAsync_doesNotResizeImageIcon() {
+        CachingIconView view = (CachingIconView) LayoutInflater.from(mContext).inflate(
+                R.layout.caching_icon_view_test_no_max_size, null);
+        view.setImageURIAsync(Uri.parse(
+                "android.resource://com.android.frameworks.coretests/" + R.drawable.big_a)).run();
+
+        assertDrawableNotResized(view);
+    }
+
+
+    private void assertDrawableResized(@Nullable CachingIconView view) {
+        assertThat(view).isNotNull();
+        int maxSize =
+                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80f,
+                        mContext.getResources().getDisplayMetrics());
+        assertThat(view.getMaxDrawableHeight()).isEqualTo(maxSize);
+        assertThat(view.getMaxDrawableWidth()).isEqualTo(maxSize);
+
+        Drawable drawable = view.getDrawable();
+        assertThat(drawable).isInstanceOf(BitmapDrawable.class);
+        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
+        assertThat(bitmapDrawable.getBitmap().getWidth()).isLessThan(maxSize + 1);
+        assertThat(bitmapDrawable.getBitmap().getHeight()).isLessThan(maxSize + 1);
+    }
+
+    private void assertDrawableNotResized(@Nullable CachingIconView view) {
+        assertThat(view).isNotNull();
+        int maxSize =
+                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80f,
+                        mContext.getResources().getDisplayMetrics());
+        assertThat(view.getMaxDrawableHeight()).isEqualTo(-1);
+        assertThat(view.getMaxDrawableWidth()).isEqualTo(-1);
+
+        Drawable drawable = view.getDrawable();
+        assertThat(drawable).isInstanceOf(BitmapDrawable.class);
+        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
+        assertThat(bitmapDrawable.getBitmap().getWidth()).isGreaterThan(maxSize);
+        assertThat(bitmapDrawable.getBitmap().getHeight()).isGreaterThan(maxSize);
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java b/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java
new file mode 100644
index 0000000..8dcb4a2
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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.internal.widget;
+
+import android.content.Context;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+
+import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.frameworks.coretests.R;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+
+@RunWith(AndroidJUnit4ClassRunner.class)
+public class LocalImageResolverTest {
+
+    private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
+
+    @Test
+    public void resolveImage_largeBitmapIcon_defaultSize_resizeToDefaultSize() throws
+            IOException {
+        Icon icon = Icon.createWithBitmap(
+                BitmapFactory.decodeResource(mContext.getResources(), R.drawable.big_a));
+        Drawable d = LocalImageResolver.resolveImage(icon, mContext);
+
+        assertThat(d).isInstanceOf(BitmapDrawable.class);
+        BitmapDrawable bd = (BitmapDrawable) d;
+        // No isLessOrEqualThan sadly.
+        assertThat(bd.getBitmap().getWidth()).isLessThan(
+                LocalImageResolver.DEFAULT_MAX_SAFE_ICON_SIZE_PX + 1);
+        assertThat(bd.getBitmap().getHeight()).isLessThan(
+                LocalImageResolver.DEFAULT_MAX_SAFE_ICON_SIZE_PX + 1);
+    }
+
+    @Test
+    public void resolveImage_largeAdaptiveBitmapIcon_defaultSize_resizeToDefaultSize() throws
+            IOException {
+        Icon icon = Icon.createWithAdaptiveBitmap(
+                BitmapFactory.decodeResource(mContext.getResources(), R.drawable.big_a));
+        Drawable d = LocalImageResolver.resolveImage(icon, mContext);
+
+        assertThat(d).isInstanceOf(AdaptiveIconDrawable.class);
+        BitmapDrawable bd = (BitmapDrawable) ((AdaptiveIconDrawable) d).getForeground();
+        // No isLessOrEqualThan sadly.
+        assertThat(bd.getBitmap().getWidth()).isLessThan(
+                LocalImageResolver.DEFAULT_MAX_SAFE_ICON_SIZE_PX + 1);
+        assertThat(bd.getBitmap().getHeight()).isLessThan(
+                LocalImageResolver.DEFAULT_MAX_SAFE_ICON_SIZE_PX + 1);
+    }
+
+    @Test
+    public void resolveImage_largeResourceIcon_defaultSize_resizeToDefaultSize() throws
+            IOException {
+        Icon icon = Icon.createWithResource(mContext, R.drawable.big_a);
+        Drawable d = LocalImageResolver.resolveImage(icon, mContext);
+
+        assertThat(d).isInstanceOf(BitmapDrawable.class);
+        BitmapDrawable bd = (BitmapDrawable) d;
+        // No isLessOrEqualThan sadly.
+        assertThat(bd.getBitmap().getWidth()).isLessThan(
+                LocalImageResolver.DEFAULT_MAX_SAFE_ICON_SIZE_PX + 1);
+        assertThat(bd.getBitmap().getHeight()).isLessThan(
+                LocalImageResolver.DEFAULT_MAX_SAFE_ICON_SIZE_PX + 1);
+    }
+
+    @Test
+    public void resolveImage_largeResourceIcon_passedSize_resizeToDefinedSize() throws
+            IOException {
+        Icon icon = Icon.createWithResource(mContext, R.drawable.big_a);
+        Drawable d = LocalImageResolver.resolveImage(icon, mContext, 100, 50);
+
+        assertThat(d).isInstanceOf(BitmapDrawable.class);
+        BitmapDrawable bd = (BitmapDrawable) d;
+        assertThat(bd.getBitmap().getWidth()).isLessThan(101);
+        assertThat(bd.getBitmap().getHeight()).isLessThan(51);
+    }
+
+    @Test
+    public void resolveImage_largeBitmapIcon_passedSize_resizeToDefinedSize() throws
+            IOException {
+        Icon icon = Icon.createWithBitmap(
+                BitmapFactory.decodeResource(mContext.getResources(), R.drawable.big_a));
+        Drawable d = LocalImageResolver.resolveImage(icon, mContext, 100, 50);
+
+        assertThat(d).isInstanceOf(BitmapDrawable.class);
+        BitmapDrawable bd = (BitmapDrawable) d;
+        assertThat(bd.getBitmap().getWidth()).isLessThan(101);
+        assertThat(bd.getBitmap().getHeight()).isLessThan(51);
+    }
+
+    @Test
+    public void resolveImage_largeAdaptiveBitmapIcon_passedSize_resizeToDefinedSize() throws
+            IOException {
+        Icon icon = Icon.createWithAdaptiveBitmap(
+                BitmapFactory.decodeResource(mContext.getResources(), R.drawable.big_a));
+        Drawable d = LocalImageResolver.resolveImage(icon, mContext, 100, 50);
+
+        assertThat(d).isInstanceOf(AdaptiveIconDrawable.class);
+        BitmapDrawable bd = (BitmapDrawable) ((AdaptiveIconDrawable) d).getForeground();
+        assertThat(bd.getBitmap().getWidth()).isLessThan(101);
+        assertThat(bd.getBitmap().getHeight()).isLessThan(51);
+    }
+
+
+    @Test
+    public void resolveImage_smallResourceIcon_defaultSize_untouched() throws IOException {
+        Icon icon = Icon.createWithResource(mContext, R.drawable.test32x24);
+        Drawable d = LocalImageResolver.resolveImage(icon, mContext);
+
+        assertThat(d).isInstanceOf(BitmapDrawable.class);
+        BitmapDrawable bd = (BitmapDrawable) d;
+        assertThat(bd.getBitmap().getWidth()).isEqualTo(32);
+        assertThat(bd.getBitmap().getHeight()).isEqualTo(24);
+    }
+
+    @Test
+    public void resolveImage_smallBitmapIcon_defaultSize_untouched() throws IOException {
+        Icon icon = Icon.createWithBitmap(
+                BitmapFactory.decodeResource(mContext.getResources(), R.drawable.test32x24));
+        final int originalWidth = icon.getBitmap().getWidth();
+        final int originalHeight = icon.getBitmap().getHeight();
+
+        Drawable d = LocalImageResolver.resolveImage(icon, mContext);
+
+        assertThat(d).isInstanceOf(BitmapDrawable.class);
+        BitmapDrawable bd = (BitmapDrawable) d;
+        assertThat(bd.getBitmap().getWidth()).isEqualTo(originalWidth);
+        assertThat(bd.getBitmap().getHeight()).isEqualTo(originalHeight);
+    }
+
+    @Test
+    public void resolveImage_smallAdaptiveBitmapIcon_defaultSize_untouched() throws IOException {
+        Icon icon = Icon.createWithAdaptiveBitmap(
+                BitmapFactory.decodeResource(mContext.getResources(), R.drawable.test32x24));
+        final int originalWidth = icon.getBitmap().getWidth();
+        final int originalHeight = icon.getBitmap().getHeight();
+
+        Drawable d = LocalImageResolver.resolveImage(icon, mContext);
+        assertThat(d).isInstanceOf(AdaptiveIconDrawable.class);
+        BitmapDrawable bd = (BitmapDrawable) ((AdaptiveIconDrawable) d).getForeground();
+        assertThat(bd.getBitmap().getWidth()).isEqualTo(originalWidth);
+        assertThat(bd.getBitmap().getHeight()).isEqualTo(originalHeight);
+
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/widget/LockPatternViewTest.java b/core/tests/coretests/src/com/android/internal/widget/LockPatternViewTest.java
new file mode 100644
index 0000000..8ba4966
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/widget/LockPatternViewTest.java
@@ -0,0 +1,247 @@
+/*
+ * 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.internal.widget;
+
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
+import android.content.Context;
+
+import androidx.test.annotation.UiThreadTest;
+
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toolbar;
+
+
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.rule.UiThreadTestRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import com.android.internal.R;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+@RunWith(Parameterized.class)
+@SmallTest
+public class LockPatternViewTest {
+
+    @Rule
+    public UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();
+
+    private final int mViewSize;
+    private final float mDefaultError;
+    private final float mDot1x;
+    private final float mDot1y;
+    private final float mDot2x;
+    private final float mDot2y;
+    private final float mDot3x;
+    private final float mDot3y;
+    private final float mDot5x;
+    private final float mDot5y;
+    private final float mDot7x;
+    private final float mDot7y;
+    private final float mDot9x;
+    private final float mDot9y;
+
+    private Context mContext;
+    private LockPatternView mLockPatternView;
+    @Mock
+    private LockPatternView.OnPatternListener mPatternListener;
+    @Captor
+    private ArgumentCaptor<List<LockPatternView.Cell>> mCellsArgumentCaptor;
+
+    public LockPatternViewTest(int viewSize) {
+        mViewSize = viewSize;
+        float cellSize = viewSize / 3f;
+        mDefaultError = cellSize * 0.2f;
+        mDot1x = cellSize / 2f;
+        mDot1y = cellSize / 2f;
+        mDot2x = cellSize + mDot1x;
+        mDot2y = mDot1y;
+        mDot3x = cellSize + mDot2x;
+        mDot3y = mDot1y;
+        // dot4 is skipped as redundant
+        mDot5x = cellSize + mDot1x;
+        mDot5y = cellSize + mDot1y;
+        // dot6 is skipped as redundant
+        mDot7x = mDot1x;
+        mDot7y = cellSize * 2 + mDot1y;
+        // dot8 is skipped as redundant
+        mDot9x = cellSize * 2 + mDot7x;
+        mDot9y = mDot7y;
+    }
+
+    @Parameterized.Parameters
+    public static Collection primeNumbers() {
+        return Arrays.asList(192, 512, 768, 1024);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mContext = InstrumentationRegistry.getContext();
+        mLockPatternView = new LockPatternView(mContext, null);
+        int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(mViewSize,
+                View.MeasureSpec.EXACTLY);
+        int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(mViewSize,
+                View.MeasureSpec.EXACTLY);
+        mLockPatternView.measure(widthMeasureSpec, heightMeasureSpec);
+        mLockPatternView.layout(0, 0, mLockPatternView.getMeasuredWidth(),
+                mLockPatternView.getMeasuredHeight());
+    }
+
+    @UiThreadTest
+    @Test
+    public void downStartsPattern() {
+        mLockPatternView.setOnPatternListener(mPatternListener);
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, mDot1x, mDot1y, 1));
+        verify(mPatternListener).onPatternStart();
+    }
+
+    @UiThreadTest
+    @Test
+    public void up_completesPattern() {
+        mLockPatternView.setOnPatternListener(mPatternListener);
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, mDot1x, mDot1y, 1));
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, mDot1x, mDot1y, 1));
+        verify(mPatternListener).onPatternDetected(any());
+    }
+
+    @UiThreadTest
+    @Test
+    public void moveToDot_hitsDot() {
+        mLockPatternView.setOnPatternListener(mPatternListener);
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 1f, 1f, 1));
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, mDot1x, mDot1y, 1));
+        verify(mPatternListener).onPatternStart();
+    }
+
+    @UiThreadTest
+    @Test
+    public void moveOutside_doesNotHitsDot() {
+        mLockPatternView.setOnPatternListener(mPatternListener);
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 1f, 1f, 1));
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 2f, 2f, 1));
+        verify(mPatternListener, never()).onPatternStart();
+    }
+
+    @UiThreadTest
+    @Test
+    public void moveAlongTwoDots_hitsTwo() {
+        mLockPatternView.setOnPatternListener(mPatternListener);
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 1f, 1f, 1));
+        makeMove(mDot1x, mDot1y, mDot2x, mDot2y, 6);
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 3, MotionEvent.ACTION_UP, mDot2x, mDot2y, 1));
+
+        verify(mPatternListener).onPatternDetected(mCellsArgumentCaptor.capture());
+        List<LockPatternView.Cell> patternCells = mCellsArgumentCaptor.getValue();
+        assertThat(patternCells, hasSize(2));
+        assertThat(patternCells,
+                contains(LockPatternView.Cell.of(0, 0), LockPatternView.Cell.of(0, 1)));
+    }
+
+    @UiThreadTest
+    @Test
+    public void moveAlongTwoDotsDiagonally_hitsTwo() {
+        mLockPatternView.setOnPatternListener(mPatternListener);
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 1f, 1f, 1));
+        makeMove(mDot1x, mDot1y, mDot5x, mDot5y, 6);
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 3, MotionEvent.ACTION_UP, mDot5x, mDot5y, 1));
+
+        verify(mPatternListener).onPatternDetected(mCellsArgumentCaptor.capture());
+        List<LockPatternView.Cell> patternCells = mCellsArgumentCaptor.getValue();
+        assertThat(patternCells, hasSize(2));
+        assertThat(patternCells,
+                contains(LockPatternView.Cell.of(0, 0), LockPatternView.Cell.of(1, 1)));
+    }
+
+    @UiThreadTest
+    @Test
+    public void moveAlongZPattern_hitsDots() {
+        mLockPatternView.setOnPatternListener(mPatternListener);
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 1f, 1f, 1));
+        makeMove(mDot1x, mDot1y, mDot3x + mDefaultError, mDot3y, 10);
+        makeMove(mDot3x - mDefaultError, mDot3y, mDot7x, mDot7y, 10);
+        makeMove(mDot7x, mDot7y - mDefaultError, mDot9x, mDot9y - mDefaultError, 10);
+        mLockPatternView.onTouchEvent(
+                MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, mViewSize - mDefaultError,
+                        mViewSize - mDefaultError, 1));
+
+        verify(mPatternListener).onPatternDetected(mCellsArgumentCaptor.capture());
+        List<LockPatternView.Cell> patternCells = mCellsArgumentCaptor.getValue();
+        assertThat(patternCells, hasSize(7));
+        assertThat(patternCells,
+                contains(LockPatternView.Cell.of(0, 0),
+                        LockPatternView.Cell.of(0, 1),
+                        LockPatternView.Cell.of(0, 2),
+                        LockPatternView.Cell.of(1, 1),
+                        LockPatternView.Cell.of(2, 0),
+                        LockPatternView.Cell.of(2, 1),
+                        LockPatternView.Cell.of(2, 2)));
+    }
+
+    private void makeMove(float xFrom, float yFrom, float xTo, float yTo, int numberOfSteps) {
+        for (int i = 0; i < numberOfSteps; i++) {
+            float progress = i / (numberOfSteps - 1f);
+            float rest = 1f - progress;
+            mLockPatternView.onTouchEvent(
+                    MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
+                            /* x= */ xFrom * rest + xTo * progress,
+                            /* y= */ yFrom * rest + yTo * progress,
+                            1));
+        }
+    }
+}
diff --git a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
index b659f37..940ca96 100644
--- a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
@@ -19,14 +19,20 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.pm.UserInfo;
@@ -50,6 +56,7 @@
 import org.mockito.Mockito;
 
 import java.nio.charset.StandardCharsets;
+import java.util.List;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -164,6 +171,16 @@
         verify(ils).isWeakEscrowTokenValid(eq(testHandle), eq(testToken), eq(testUserId));
     }
 
+    @Test
+    public void testGetEnabledTrustAgentsNotNull() throws RemoteException {
+        int testUserId = 10;
+        ILockSettings ils = createTestLockSettings();
+        when(ils.getString(anyString(), any(), anyInt())).thenReturn("");
+        List<ComponentName> trustAgents = mLockPatternUtils.getEnabledTrustAgents(testUserId);
+        assertNotNull(trustAgents);
+        assertEquals(0, trustAgents.size());
+    }
+
     private ILockSettings createTestLockSettings() {
         final Context context = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
         mLockPatternUtils = spy(new LockPatternUtils(context));
diff --git a/data/etc/com.android.launcher3.xml b/data/etc/com.android.launcher3.xml
index 598d202..36a5134 100644
--- a/data/etc/com.android.launcher3.xml
+++ b/data/etc/com.android.launcher3.xml
@@ -16,6 +16,7 @@
   -->
 <permissions>
     <privapp-permissions package="com.android.launcher3">
+        <permission name="android.permission.ALLOW_SLIPPERY_TOUCHES"/>
         <permission name="android.permission.BIND_APPWIDGET"/>
         <permission name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"/>
         <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index ae350ec..2d1db71 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -17,6 +17,7 @@
 <permissions>
     <privapp-permissions package="com.android.systemui">
         <permission name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
+        <permission name="android.permission.ALLOW_SLIPPERY_TOUCHES"/>
         <permission name="android.permission.BATTERY_STATS"/>
         <permission name="android.permission.BIND_APPWIDGET"/>
         <permission name="android.permission.BLUETOOTH_PRIVILEGED"/>
@@ -75,5 +76,8 @@
         <permission name="android.permission.FORCE_STOP_PACKAGES" />
         <permission name="android.permission.ACCESS_FPS_COUNTER" />
         <permission name="android.permission.CHANGE_CONFIGURATION" />
+        <permission name="android.permission.LOG_COMPAT_CHANGE" />
+        <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
+        <permission name="android.permission.READ_DEVICE_CONFIG" />
     </privapp-permissions>
 </permissions>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 88920c8..a829339 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -241,7 +241,7 @@
     </split-permission>
     <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
                       targetSdk="33">
-        <new-permission name="android.permission.READ_MEDIA_IMAGE" />
+        <new-permission name="android.permission.READ_MEDIA_IMAGES" />
     </split-permission>
     <split-permission name="android.permission.BLUETOOTH"
                       targetSdk="31">
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 3c64cf5..3e91eed 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -237,27 +237,6 @@
         <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
     </privapp-permissions>
 
-    <privapp-permissions package="com.android.providers.media.module">
-        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
-        <permission name="android.permission.MANAGE_USERS"/>
-        <permission name="android.permission.USE_RESERVED_DISK"/>
-        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
-        <permission name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
-        <permission name="android.permission.WATCH_APPOPS"/>
-        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
-        <permission name="android.permission.UPDATE_DEVICE_STATS"/>
-        <!-- Permissions required for reading and logging compat changes -->
-        <permission name="android.permission.LOG_COMPAT_CHANGE" />
-        <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
-        <permission name="android.permission.REGISTER_STATS_PULL_ATOM" />
-        <!-- Permissions required for reading DeviceConfig -->
-        <permission name="android.permission.READ_DEVICE_CONFIG" />
-        <permission name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND"/>
-        <permission name="android.permission.MODIFY_QUIET_MODE"/>
-        <!-- Permissions required to check if an app is in the foreground or not during IO -->
-        <permission name="android.permission.PACKAGE_USAGE_STATS"/>
-    </privapp-permissions>
-
     <privapp-permissions package="com.android.providers.telephony">
         <permission name="android.permission.INTERACT_ACROSS_USERS"/>
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
@@ -473,10 +452,11 @@
         <permission name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS" />
         <permission name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" />
         <permission name="android.permission.NEARBY_WIFI_DEVICES" />
+        <permission name="android.permission.MANAGE_WIFI_INTERFACES" />
         <permission name="android.permission.OVERRIDE_WIFI_CONFIG" />
         <!-- Permission needed for CTS test - ConcurrencyTest#testP2pExternalApprover
-             P2P external approver API sets require MANAGE_WIFI_AUTO_JOIN permission. -->
-        <permission name="android.permission.MANAGE_WIFI_AUTO_JOIN" />
+             P2P external approver API sets require MANAGE_WIFI_NETWORK_SELECTION permission. -->
+        <permission name="android.permission.MANAGE_WIFI_NETWORK_SELECTION" />
         <!-- Permission required for CTS test CarrierMessagingServiceWrapperTest -->
         <permission name="android.permission.BIND_CARRIER_SERVICES"/>
         <!-- Permission required for CTS test - MusicRecognitionManagerTest -->
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index df2b2a3..e898f57 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1309,6 +1309,12 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-711194343": {
+      "message": "Setting Activity.mLauncherTaskBehind to false. Activity=%s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_BACK_PREVIEW",
+      "at": "com\/android\/server\/wm\/BackNavigationController.java"
+    },
     "-706481945": {
       "message": "TaskFragment parent info changed name=%s parentTaskId=%d",
       "level": "VERBOSE",
@@ -2587,6 +2593,12 @@
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/WindowState.java"
     },
+    "599897753": {
+      "message": "Previous Activity is %s. Back type is %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_BACK_PREVIEW",
+      "at": "com\/android\/server\/wm\/BackNavigationController.java"
+    },
     "600140673": {
       "message": "checkBootAnimationComplete: Waiting for anim complete",
       "level": "INFO",
@@ -2671,12 +2683,6 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "664667685": {
-      "message": "Activity %s: enableOnBackInvokedCallback=false. Returning null BackNavigationInfo.",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
     "665256544": {
       "message": "All windows drawn!",
       "level": "DEBUG",
@@ -2887,6 +2893,12 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/TaskFragment.java"
     },
+    "948208142": {
+      "message": "Setting Activity.mLauncherTaskBehind to true. Activity=%s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_BACK_PREVIEW",
+      "at": "com\/android\/server\/wm\/BackNavigationController.java"
+    },
     "950074526": {
       "message": "setLockTaskMode: Can't lock due to auth",
       "level": "WARN",
@@ -3103,6 +3115,12 @@
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/DisplayContent.java"
     },
+    "1172542963": {
+      "message": "onBackNavigationDone backType=%s, task=%s, prevTaskTopActivity=%s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_BACK_PREVIEW",
+      "at": "com\/android\/server\/wm\/BackNavigationController.java"
+    },
     "1178653181": {
       "message": "Old wallpaper still the target.",
       "level": "VERBOSE",
@@ -3415,11 +3433,11 @@
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
-    "1554795024": {
-      "message": "Previous Activity is %s",
+    "1544805551": {
+      "message": "Skipping app transition animation. task=%s",
       "level": "DEBUG",
       "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
+      "at": "com\/android\/server\/wm\/Task.java"
     },
     "1557732761": {
       "message": "For Intent %s bringing to top: %s",
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 7e68bc0..1a522bd 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -291,6 +291,14 @@
     }
 
     /**
+     * @return {@code true} if the rectangle is valid (left <= right and top <= bottom).
+     * @hide
+     */
+    public boolean isValid() {
+        return left <= right && top <= bottom;
+    }
+
+    /**
      * @return the rectangle's width. This does not check for a valid rectangle
      * (i.e. left <= right) so the result may be negative.
      */
diff --git a/graphics/java/android/graphics/RuntimeShader.java b/graphics/java/android/graphics/RuntimeShader.java
index 2ff888b..6abe34b 100644
--- a/graphics/java/android/graphics/RuntimeShader.java
+++ b/graphics/java/android/graphics/RuntimeShader.java
@@ -19,12 +19,228 @@
 import android.annotation.ColorInt;
 import android.annotation.ColorLong;
 import android.annotation.NonNull;
+import android.view.Window;
 
 import libcore.util.NativeAllocationRegistry;
 
 /**
- * Shader that calculates per-pixel color via a user defined Android Graphics Shading Language
- * (AGSL) function.
+ * <p>A {@link RuntimeShader} calculates a per-pixel color based on the output of a user defined
+ * Android Graphics Shading Language (AGSL) function.</p>
+ *
+ * <h3>Android Graphics Shading Language</h3>
+ * <p>The AGSL syntax is very similar to OpenGL ES Shading Language, but there are some important
+ * differences that are highlighted here. Most of these differences are summed up in one basic fact:
+ * <b>With GPU shading languages, you are programming a stage of the GPU pipeline. With AGSL, you
+ * are programming a stage of the {@link Canvas} or {@link RenderNode} drawing pipeline.</b></p>
+ *
+ * <p>In particular, a GLSL fragment shader controls the entire behavior of the GPU between the
+ * rasterizer and the blending hardware. That shader does all of the work to compute a color, and
+ * the color it generates is exactly what is fed to the blending stage of the pipeline.</p>
+ *
+ * <p>In contrast, AGSL functions exist as part of a larger pipeline. When you issue a
+ * {@link Canvas} drawing operation, Android (generally) assembles a single GPU fragment shader to
+ * do all of the required work. This shader typically includes several pieces. For example, it might
+ * include:</p>
+ * <ul>
+ *  <li>Evaluating whether a pixel falls inside or outside of the shape being drawn (or on the
+ *  border, where it might apply antialiasing).</li>
+ *  <li>Evaluating whether a pixel falls inside or outside of the clipping region (again, with
+ *  possible antialiasing logic for border pixels).</li>
+ *  <li>Logic for the {@link Shader}, {@link ColorFilter}, and {@link BlendMode} on the
+ *  {@link Paint}.</li>
+ *  <li>Color space conversion code, as part of Android’s color management.</li>
+ * </ul>
+ *
+ * <p>A {@link RuntimeShader}, like other {@link Shader} types, effectively contributes a function
+ * to the GPU’s fragment shader.</p>
+ *
+ * <h3>AGSL Shader Execution</h3>
+ * <p>Just like a GLSL shader, an AGSL shader begins execution in a main function. Unlike GLSL, the
+ * function receives as an input parameter the position of the pixel within the {@link Canvas} or
+ * {@link RenderNode} coordinate space (similar to gl_fragCoord) and returns the color to be shaded
+ * as a vec4 (similar to out vec4 color or gl_FragColor in GLSL).</p>
+ *
+ * <pre class="prettyprint">
+ * vec4 main(vec2 canvas_coordinates);
+ * </pre>
+ *
+ * <p>AGSL and GLSL use different coordinate spaces by default. In GLSL, the fragment coordinate
+ * (fragCoord) is relative to the lower left. AGSL matches the screen coordinate system of the
+ * Android {@link Canvas} which has its origin as the upper left corner. This means that the
+ * coordinates provided as a parameter in the main function are local to the canvas with the
+ * exception of any {@link Shader#getLocalMatrix(Matrix)} transformations applied to this shader.
+ * Additionally, if the shader is invoked by another using {@link #setInputShader(String, Shader)},
+ * then that parent shader may modify the input coordinates arbitrarily.</p>
+ *
+ * <h3>AGSL and Color Spaces</h3>
+ * <p>Android Graphics and by extension {@link RuntimeShader} are color managed.  The working
+ * {@link ColorSpace} for an AGSL shader is defined to be the color space of the destination, which
+ * in most cases is determined by {@link Window#setColorMode(int)}.</p>
+ *
+ * <p>When authoring an AGSL shader, you won’t know what the working color space is. For many
+ * effects, this is fine because by default color inputs are automatically converted into the
+ * working color space. For certain effects, it may be important to do some math in a fixed, known
+ * color space. A common example is lighting – to get physically accurate lighting, math should be
+ * done in a linear color space. To help with this, AGSL provides two intrinsic functions that
+ * convert colors between the working color space and the
+ * {@link ColorSpace.Named#LINEAR_EXTENDED_SRGB} color space:
+ *
+ * <pre class="prettyprint">
+ * vec3 toLinearSrgb(vec3 color);
+ * vec3 fromLinearSrgb(vec3 color);</pre>
+ *
+ * <h3>AGSL and Premultiplied Alpha</h3>
+ * <p>When dealing with transparent colors, there are two (common) possible representations:
+ * straight (unassociated) alpha and premultiplied (associated) alpha. In ASGL the color returned
+ * by the main function is expected to be premultiplied.  AGSL’s use of premultiplied alpha
+ * implies:
+ * </p>
+ *
+ * <ul>
+ *  <li>If your AGSL shader will return transparent colors, be sure to multiply the RGB by A.  The
+ *  resulting color should be [R*A, G*A, B*A, A], not [R, G, B, A].</li>
+ *  <li>For more complex shaders, you must understand which of your colors are premultiplied vs.
+ *  straight. Many operations don’t make sense if you mix both kinds of color together.</li>
+ * </ul>
+ *
+ * <h3>Uniforms</h3>
+ * <p>AGSL, like GLSL, exposes the concept of uniforms. An AGSL uniform is defined as a read-only,
+ * global variable that is accessible by the AGSL code and is initialized by a number of setter
+ * methods on {@link RuntimeShader}. AGSL exposes two primitive uniform data types (float, int) and
+ * two specialized types (colors, shaders) that are outlined below.</p>
+ *
+ * <h4>Primitive Uniforms</h4>
+ * <p>There are two primitive uniform types supported by AGSL, float and int. For these types and
+ * uniforms representing a grouping of these types, like arrays and matrices, there are
+ * corresponding {@link RuntimeShader} methods to initialize them.
+ * <table border="2" width="85%" align="center" cellpadding="5">
+ *     <thead>
+ *         <tr><th>Java Type</th> <th>AGSL Type</th> <th>Method</th> </tr>
+ *     </thead>
+ *
+ *     <tbody>
+ *     <tr>
+ *         <td rowspan="4">Floats</td>
+ *         <td>float</td>
+ *         <td>{@link RuntimeShader#setFloatUniform(String, float)}</td>
+ *     </tr>
+ *     <tr>
+ *         <td>vec2</td>
+ *         <td>{@link RuntimeShader#setFloatUniform(String, float, float)}</td>
+ *     </tr>
+ *     <tr>
+ *         <td>vec3</td>
+ *         <td>{@link RuntimeShader#setFloatUniform(String, float, float, float)}</td>
+ *     </tr>
+ *     <tr>
+ *         <td>vec4</td>
+ *         <td>{@link RuntimeShader#setFloatUniform(String, float, float, float, float)}</td>
+ *     </tr>
+ *     <tr>
+ *         <td rowspan="4">Integers</td>
+ *         <td>int</td>
+ *         <td>{@link RuntimeShader#setIntUniform(String, int)}</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ivec2</td>
+ *         <td>{@link RuntimeShader#setIntUniform(String, int, int)}</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ivec3</td>
+ *         <td>{@link RuntimeShader#setIntUniform(String, int, int, int)}</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ivec4</td>
+ *         <td>{@link RuntimeShader#setIntUniform(String, int, int, int, int)}</td>
+ *     </tr>
+ *     <tr>
+ *         <td rowspan="2">Matrices and Arrays</td>
+ *         <td>mat2, mat3, and mat4, and float[]</td>
+ *         <td>{@link RuntimeShader#setFloatUniform(String, float[])}</td>
+ *     </tr>
+ *     <tr>
+ *         <td>int[]</td>
+ *         <td>{@link RuntimeShader#setIntUniform(String, int[])}</td>
+ *     </tr>
+ *     </tbody>
+ * </table>
+ *
+ * For example, a simple AGSL shader making use of a float uniform to modulate the transparency
+ * of the output color would look like:</p>
+ *
+ * <pre class="prettyprint">
+ * uniform float alpha;
+ * vec4 main(vec2 canvas_coordinates) {
+ *     vec3 red = vec3(1.0, 0.0, 0.0);
+ *     return vec4(red * alpha, alpha);
+ * }</pre>
+ *
+ * <p>After creating a {@link RuntimeShader} with that program the uniform can then be initialized
+ * and updated per frame by calling {@link RuntimeShader#setFloatUniform(String, float)} with the
+ * value of alpha.  The value of a primitive uniform defaults to 0 if it is declared in the AGSL
+ * shader but not initialized.</p>
+ *
+ * <h4>Color Uniforms</h4>
+ * <p>AGSL doesn't know if uniform variables contain colors, it won't automatically convert them to
+ * the working colorspace of the shader at runtime.  However, you can label your vec4 uniform with
+ * the "layout(color)" qualifier which lets Android know that the uniform will be used as a color.
+ * Doing so allows AGSL to transform the uniform value to the working color space. In AGSL, declare
+ * the uniform like this:
+ *
+ * <pre class="prettyprint">
+ * layout(color) uniform vec4 inputColorA;
+ * layout(color) uniform vec4 inputColorB;
+ * vec4 main(vec2 canvas_coordinates) {
+ *     // blend the two colors together and return the resulting color
+ *     return mix(inputColorA, inputColorB, 0.5);
+ * }</pre>
+ *
+ * <p>After creating a {@link RuntimeShader} with that program the uniforms can
+ * then be initialized and updated per frame by calling
+ * {@link RuntimeShader#setColorUniform(String, int)},
+ * {@link RuntimeShader#setColorUniform(String, long)}, or
+ * {@link RuntimeShader#setColorUniform(String, Color)} with the desired colors.  The value of a
+ * color uniform is undefined if it is declared in the AGSL shader but not initialized.</p>
+ *
+ * <h4>Shader Uniforms</h4>
+ * In GLSL, a fragment shader can sample a texture. For AGSL instead of sampling textures you can
+ * sample from any {@link Shader}, which includes but is not limited to {@link BitmapShader}. To
+ * make it clear that you are operating on an {@link Shader} object there is no "sample"
+ * method. Instead, the shader uniform has an "eval()" method. This distinction enables AGSL shaders
+ * to sample from existing bitmap and gradient shaders as well as other {@link RuntimeShader}
+ * objects.  In AGSL, declare the uniform like this:
+ *
+ * <pre class="prettyprint">
+ * uniform shader myShader;
+ * vec4 main(vec2 canvas_coordinates) {
+ *     // swap the red and blue color channels when sampling from myShader
+ *     return myShader.sample(canvas_coordinates).bgra;
+ * }</pre>
+ *
+ * <p>After creating a {@link RuntimeShader} with that program the shader uniform can
+ * then be initialized and updated per frame by calling
+ * {@link RuntimeShader#setInputShader(String, Shader)} with the desired shader. The value of a
+ * shader uniform is undefined if it is declared in the AGSL shader but not initialized.</p>
+ *
+ * <p>Although most {@link BitmapShader}s contain colors that should be color managed, some contain
+ * data that isn’t actually colors. This includes bitmaps storing normals, material properties
+ * (e.g. roughness), heightmaps, or any other purely mathematical data that happens to be stored in
+ * a bitmap. When using these kinds of shaders in AGSL, you probably want to initialize them with
+ * {@link #setInputBuffer(String, BitmapShader)}. Shaders initialized this way work much like
+ * a regular {@link BitmapShader} (including filtering and tiling), with a few major differences:
+ * <ul>
+ *  <li>No color space transformation is applied (the color space of the bitmap is ignored).</li>
+ *  <li>Bitmaps that return false for {@link Bitmap#isPremultiplied()} are not automatically
+ *  premultiplied.</li>
+ * </ul>
+ *
+ * <p>In addition, when sampling from a {@link BitmapShader} be aware that the shader does not use
+ * normalized coordinates (like a texture in GLSL). It uses (0, 0) in the upper-left corner, and
+ * (width, height) in the bottom-right corner. Normally, this is exactly what you want. If you’re
+ * evaluating the shader with coordinates based on the ones passed to your AGSL program, the scale
+ * is correct. However, if you want to adjust those coordinates (to do some kind of re-mapping of
+ * the bitmap), remember that the coordinates are local to the canvas.</p>
+ *
  */
 public class RuntimeShader extends Shader {
 
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index ffaa4ea..c1addbf 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -1098,19 +1098,16 @@
         }
 
         // Draw the appropriate mask anchored to (0,0).
+        final int saveCount = mMaskCanvas.save();
         final int left = bounds.left;
         final int top = bounds.top;
-        if (mState.mRippleStyle == STYLE_SOLID) {
-            mMaskCanvas.translate(-left, -top);
-        }
+        mMaskCanvas.translate(-left, -top);
         if (maskType == MASK_EXPLICIT) {
             drawMask(mMaskCanvas);
         } else if (maskType == MASK_CONTENT) {
             drawContent(mMaskCanvas);
         }
-        if (mState.mRippleStyle == STYLE_SOLID) {
-            mMaskCanvas.translate(left, top);
-        }
+        mMaskCanvas.restoreToCount(saveCount);
         if (mState.mRippleStyle == STYLE_PATTERNED) {
             for (int i = 0; i < mRunningAnimations.size(); i++) {
                 mRunningAnimations.get(i).getProperties().getShader().setShader(mMaskShader);
@@ -1210,9 +1207,13 @@
         updateMaskShaderIfNeeded();
 
         // Position the shader to account for canvas translation.
-        if (mMaskShader != null && mState.mRippleStyle == STYLE_SOLID) {
+        if (mMaskShader != null) {
             final Rect bounds = getBounds();
-            mMaskMatrix.setTranslate(bounds.left - x, bounds.top - y);
+            if (mState.mRippleStyle == STYLE_PATTERNED) {
+                mMaskMatrix.setTranslate(bounds.left, bounds.top);
+            } else {
+                mMaskMatrix.setTranslate(bounds.left - x, bounds.top - y);
+            }
             mMaskShader.setLocalMatrix(mMaskMatrix);
         }
 
diff --git a/graphics/java/android/graphics/text/LineBreakConfig.java b/graphics/java/android/graphics/text/LineBreakConfig.java
index cffdf28..d083e44 100644
--- a/graphics/java/android/graphics/text/LineBreakConfig.java
+++ b/graphics/java/android/graphics/text/LineBreakConfig.java
@@ -26,7 +26,7 @@
 /**
  * Indicates the strategies can be used when calculating the text wrapping.
  *
- * See <a href="https://drafts.csswg.org/css-text/#line-break-property">the line-break property</a>
+ * See <a href="https://www.w3.org/TR/css-text-3/#line-break-property">the line-break property</a>
  */
 public final class LineBreakConfig {
 
@@ -78,21 +78,87 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface LineBreakWordStyle {}
 
-    private @LineBreakStyle int mLineBreakStyle = LINE_BREAK_STYLE_NONE;
-    private @LineBreakWordStyle int mLineBreakWordStyle = LINE_BREAK_WORD_STYLE_NONE;
+    /**
+     * A builder for creating {@link LineBreakConfig}.
+     */
+    public static final class Builder {
+        // The line break style for the LineBreakConfig.
+        private @LineBreakStyle int mLineBreakStyle = LineBreakConfig.LINE_BREAK_STYLE_NONE;
 
-    public LineBreakConfig() {
+        // The line break word style for the LineBreakConfig.
+        private @LineBreakWordStyle int mLineBreakWordStyle =
+                LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE;
+
+        /**
+         * Builder constructor with line break parameters.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Set the line break style.
+         *
+         * @param lineBreakStyle the new line break style.
+         * @return this Builder
+         */
+        public @NonNull Builder setLineBreakStyle(@LineBreakStyle int lineBreakStyle) {
+            mLineBreakStyle = lineBreakStyle;
+            return this;
+        }
+
+        /**
+         * Set the line break word style.
+         *
+         * @param lineBreakWordStyle the new line break word style.
+         * @return this Builder
+         */
+        public @NonNull Builder setLineBreakWordStyle(@LineBreakWordStyle int lineBreakWordStyle) {
+            mLineBreakWordStyle = lineBreakWordStyle;
+            return this;
+        }
+
+        /**
+         * Build the {@link LineBreakConfig}
+         *
+         * @return the LineBreakConfig instance.
+         */
+        public @NonNull LineBreakConfig build() {
+            return new LineBreakConfig(mLineBreakStyle, mLineBreakWordStyle);
+        }
     }
 
     /**
-     * Set the line break configuration.
+     * Create the LineBreakConfig instance.
      *
-     * @param lineBreakConfig the new line break configuration.
+     * @param lineBreakStyle the line break style for text wrapping.
+     * @param lineBreakWordStyle the line break word style for text wrapping.
+     * @return the {@link LineBreakConfig} instance.
+     * @hide
      */
-    public void set(@NonNull LineBreakConfig lineBreakConfig) {
-        Objects.requireNonNull(lineBreakConfig);
-        mLineBreakStyle = lineBreakConfig.getLineBreakStyle();
-        mLineBreakWordStyle = lineBreakConfig.getLineBreakWordStyle();
+    public static @NonNull LineBreakConfig getLineBreakConfig(@LineBreakStyle int lineBreakStyle,
+            @LineBreakWordStyle int lineBreakWordStyle) {
+        LineBreakConfig.Builder builder = new LineBreakConfig.Builder();
+        return builder.setLineBreakStyle(lineBreakStyle)
+                .setLineBreakWordStyle(lineBreakWordStyle)
+                .build();
+    }
+
+    /** @hide */
+    public static final LineBreakConfig NONE =
+            new Builder().setLineBreakStyle(LINE_BREAK_STYLE_NONE)
+                    .setLineBreakWordStyle(LINE_BREAK_WORD_STYLE_NONE).build();
+
+    private final @LineBreakStyle int mLineBreakStyle;
+    private final @LineBreakWordStyle int mLineBreakWordStyle;
+
+    /**
+     * Constructor with the line break parameters.
+     * Use the {@link LineBreakConfig.Builder} to create the LineBreakConfig instance.
+     */
+    private LineBreakConfig(@LineBreakStyle int lineBreakStyle,
+            @LineBreakWordStyle int lineBreakWordStyle) {
+        mLineBreakStyle = lineBreakStyle;
+        mLineBreakWordStyle = lineBreakWordStyle;
     }
 
     /**
@@ -105,15 +171,6 @@
     }
 
     /**
-     * Set the line break style.
-     *
-     * @param lineBreakStyle the new line break style.
-     */
-    public void setLineBreakStyle(@LineBreakStyle int lineBreakStyle) {
-        mLineBreakStyle = lineBreakStyle;
-    }
-
-    /**
      * Get the line break word style.
      *
      * @return The current line break word style to be used for the text wrapping.
@@ -122,15 +179,6 @@
         return mLineBreakWordStyle;
     }
 
-    /**
-     * Set the line break word style.
-     *
-     * @param lineBreakWordStyle the new line break word style.
-     */
-    public void setLineBreakWordStyle(@LineBreakWordStyle int lineBreakWordStyle) {
-        mLineBreakWordStyle = lineBreakWordStyle;
-    }
-
     @Override
     public boolean equals(Object o) {
         if (o == null) return false;
diff --git a/identity/java/android/security/identity/CredentialDataRequest.java b/identity/java/android/security/identity/CredentialDataRequest.java
index 2a47a02..3482384 100644
--- a/identity/java/android/security/identity/CredentialDataRequest.java
+++ b/identity/java/android/security/identity/CredentialDataRequest.java
@@ -153,7 +153,15 @@
         /**
          * Sets whether to allow using an authentication key which use count has been exceeded.
          *
-         * By default this is set to true.
+         * <p>This is useful in situations where the application hasn't had a chance to renew
+         * authentication keys, for example if the device hasn't been connected to the Internet or
+         * if the issuing authority server has been down.
+         *
+         * <p>The reason this could be useful is that the privacy risk of reusing an authentication
+         * key for a credential presentation could be significantly smaller compared to the
+         * inconvenience of not being able to present the credential at all.
+         *
+         * <p>By default this is set to true.
          *
          * @param allowUsingExhaustedKeys whether to allow using an authentication key which use
          *                                count has been exceeded if no other key is available.
@@ -167,7 +175,16 @@
         /**
          * Sets whether to allow using an authentication key which is expired.
          *
-         * By default this is set to false.
+         * <p>This is useful in situations where the application hasn't had a chance to renew
+         * authentication keys, for example if the device hasn't been connected to the Internet or
+         * if the issuing authority server has been down.
+         *
+         * <p>The reason this could be useful is that many verifiers are likely to accept a
+         * credential presentation using an expired authentication key (the credential itself
+         * wouldn't be expired) and it's likely better for the holder to be able to do this than
+         * not present their credential at all.
+         *
+         * <p>By default this is set to false.
          *
          * @param allowUsingExpiredKeys whether to allow using an authentication key which is
          *                              expired if no other key is available.
@@ -181,7 +198,12 @@
         /**
          * Sets whether to increment the use-count for the authentication key used.
          *
-         * By default this is set to true.
+         * <p>Not incrementing the use-count for an authentication key is useful in situations
+         * where the authentication key is known with certainty to not be leaked. For example,
+         * consider an application doing a credential presentation for the sole purpose of
+         * displaying the credential data to the user (not for verification).
+         *
+         * <p>By default this is set to true.
          *
          * @param incrementUseCount whether to increment the use count of the authentication
          *                          key used.
diff --git a/identity/java/android/security/identity/PresentationSession.java b/identity/java/android/security/identity/PresentationSession.java
index afaafce..6cde611 100644
--- a/identity/java/android/security/identity/PresentationSession.java
+++ b/identity/java/android/security/identity/PresentationSession.java
@@ -26,6 +26,9 @@
 /**
  * Class for presenting multiple documents to a remote verifier.
  *
+ * <p>This should be used for all interactions with a remote verifier instead of the now deprecated
+ * {@link IdentityCredential#getEntries(byte[], Map, byte[], byte[])} method.
+ *
  * Use {@link IdentityCredentialStore#createPresentationSession(int)} to create a {@link
  * PresentationSession} instance.
  */
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index 31dd10a..e7961c9 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -108,6 +108,16 @@
         }
     }
 
+    /**
+     * XDH represents Curve 25519 providers.
+     */
+    public static class XDH extends AndroidKeyStoreKeyPairGeneratorSpi {
+        // XDH is treated as EC.
+        public XDH() {
+            super(KeymasterDefs.KM_ALGORITHM_EC);
+        }
+    }
+
     /*
      * These must be kept in sync with system/security/keystore/defaults.h
      */
@@ -242,6 +252,23 @@
                 } catch (NullPointerException | IllegalArgumentException e) {
                     throw new InvalidAlgorithmParameterException(e);
                 }
+            } else if (params instanceof NamedParameterSpec) {
+                NamedParameterSpec namedSpec = (NamedParameterSpec) params;
+                // Android Keystore cannot support initialization from a NamedParameterSpec
+                // because an alias for the key is needed (a KeyGenParameterSpec cannot be
+                // constructed).
+                if (namedSpec.getName().equalsIgnoreCase(NamedParameterSpec.X25519.getName())
+                        || namedSpec.getName().equalsIgnoreCase(
+                        NamedParameterSpec.ED25519.getName())) {
+                    throw new IllegalArgumentException(
+                            "This KeyPairGenerator cannot be initialized using NamedParameterSpec."
+                                    + " use " + KeyGenParameterSpec.class.getName() + " or "
+                                    + KeyPairGeneratorSpec.class.getName());
+                } else {
+                    throw new InvalidAlgorithmParameterException(
+                            "Unsupported algorithm specified via NamedParameterSpec: "
+                            + namedSpec.getName());
+                }
             } else {
                 throw new InvalidAlgorithmParameterException(
                         "Unsupported params class: " + params.getClass().getName()
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index 358104f..d31499e 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -83,16 +83,12 @@
         // java.security.KeyPairGenerator
         put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$EC");
         put("KeyPairGenerator.RSA", PACKAGE_NAME +  ".AndroidKeyStoreKeyPairGeneratorSpi$RSA");
-        put("KeyPairGenerator." + X25519_ALIAS,
-                PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA");
-        put("KeyPairGenerator." + ED25519_OID,
-                PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA");
+        put("KeyPairGenerator.XDH", PACKAGE_NAME +  ".AndroidKeyStoreKeyPairGeneratorSpi$XDH");
 
         // java.security.KeyFactory
         putKeyFactoryImpl("EC");
         putKeyFactoryImpl("RSA");
-        putKeyFactoryImpl(X25519_ALIAS);
-        putKeyFactoryImpl(ED25519_OID);
+        putKeyFactoryImpl("XDH");
 
         // javax.crypto.KeyGenerator
         put("KeyGenerator.AES", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$AES");
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java
deleted file mode 100644
index eb94297..0000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonDisplayFeature.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.common;
-
-import static androidx.window.util.ExtensionHelper.isZero;
-
-import android.annotation.Nullable;
-import android.graphics.Rect;
-
-import androidx.annotation.NonNull;
-
-import java.util.Objects;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/** Wrapper for both Extension and Sidecar versions of DisplayFeature. */
-final class CommonDisplayFeature implements DisplayFeature {
-    private static final Pattern FEATURE_PATTERN =
-            Pattern.compile("([a-z]+)-\\[(\\d+),(\\d+),(\\d+),(\\d+)]-?(flat|half-opened)?");
-
-    private static final String FEATURE_TYPE_FOLD = "fold";
-    private static final String FEATURE_TYPE_HINGE = "hinge";
-
-    private static final String PATTERN_STATE_FLAT = "flat";
-    private static final String PATTERN_STATE_HALF_OPENED = "half-opened";
-
-    // TODO(b/183049815): Support feature strings that include the state of the feature.
-
-    /**
-     * Parses a display feature from a string.
-     *
-     * @throws IllegalArgumentException if the provided string is improperly formatted or could not
-     *                                  otherwise be parsed.
-     * @see #FEATURE_PATTERN
-     */
-    @NonNull
-    static CommonDisplayFeature parseFromString(@NonNull String string) {
-        Matcher featureMatcher = FEATURE_PATTERN.matcher(string);
-        if (!featureMatcher.matches()) {
-            throw new IllegalArgumentException("Malformed feature description format: " + string);
-        }
-        try {
-            String featureType = featureMatcher.group(1);
-            featureType = featureType == null ? "" : featureType;
-            int type;
-            switch (featureType) {
-                case FEATURE_TYPE_FOLD:
-                    type = 1 /* TYPE_FOLD */;
-                    break;
-                case FEATURE_TYPE_HINGE:
-                    type = 2 /* TYPE_HINGE */;
-                    break;
-                default: {
-                    throw new IllegalArgumentException("Malformed feature type: " + featureType);
-                }
-            }
-
-            int left = Integer.parseInt(featureMatcher.group(2));
-            int top = Integer.parseInt(featureMatcher.group(3));
-            int right = Integer.parseInt(featureMatcher.group(4));
-            int bottom = Integer.parseInt(featureMatcher.group(5));
-            Rect featureRect = new Rect(left, top, right, bottom);
-            if (isZero(featureRect)) {
-                throw new IllegalArgumentException("Feature has empty bounds: " + string);
-            }
-            String stateString = featureMatcher.group(6);
-            stateString = stateString == null ? "" : stateString;
-            Integer state;
-            switch (stateString) {
-                case PATTERN_STATE_FLAT:
-                    state = COMMON_STATE_FLAT;
-                    break;
-                case PATTERN_STATE_HALF_OPENED:
-                    state = COMMON_STATE_HALF_OPENED;
-                    break;
-                default:
-                    state = null;
-                    break;
-            }
-            return new CommonDisplayFeature(type, state, featureRect);
-        } catch (NumberFormatException e) {
-            throw new IllegalArgumentException("Malformed feature description: " + string, e);
-        }
-    }
-
-    private final int mType;
-    @Nullable
-    private final Integer mState;
-    @NonNull
-    private final Rect mRect;
-
-    CommonDisplayFeature(int type, @Nullable Integer state, @NonNull Rect rect) {
-        assertValidState(state);
-        this.mType = type;
-        this.mState = state;
-        if (rect.width() == 0 && rect.height() == 0) {
-            throw new IllegalArgumentException(
-                    "Display feature rectangle cannot have zero width and height simultaneously.");
-        }
-        this.mRect = rect;
-    }
-
-    public int getType() {
-        return mType;
-    }
-
-    /** Returns the state of the feature, or {@code null} if the feature has no state. */
-    @Nullable
-    public Integer getState() {
-        return mState;
-    }
-
-    @NonNull
-    public Rect getRect() {
-        return mRect;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        CommonDisplayFeature that = (CommonDisplayFeature) o;
-        return mType == that.mType
-                && Objects.equals(mState, that.mState)
-                && mRect.equals(that.mRect);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mType, mState, mRect);
-    }
-
-    private static void assertValidState(@Nullable Integer state) {
-        if (state != null && state != COMMON_STATE_FLAT && state != COMMON_STATE_HALF_OPENED) {
-            throw new IllegalArgumentException("Invalid state: " + state
-                    + "must be either COMMON_STATE_FLAT or COMMON_STATE_HALF_OPENED");
-        }
-    }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
new file mode 100644
index 0000000..1c49881
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window.common;
+
+import static androidx.window.util.ExtensionHelper.isZero;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.graphics.Rect;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/** A representation of a folding feature for both Extension and Sidecar.
+ * For Sidecar this is the same as combining {@link androidx.window.sidecar.SidecarDeviceState} and
+ * {@link androidx.window.sidecar.SidecarDisplayFeature}. For Extensions this is the mirror of
+ * {@link androidx.window.extensions.layout.FoldingFeature}.
+ */
+public final class CommonFoldingFeature {
+
+    private static final boolean DEBUG = false;
+
+    public static final String TAG = CommonFoldingFeature.class.getSimpleName();
+
+    /**
+     * A common type to represent a hinge where the screen is continuous.
+     */
+    public static final int COMMON_TYPE_FOLD = 1;
+
+    /**
+     * A common type to represent a hinge where there is a physical gap separating multiple
+     * displays.
+     */
+    public static final int COMMON_TYPE_HINGE = 2;
+
+    @IntDef({COMMON_TYPE_FOLD, COMMON_TYPE_HINGE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {
+    }
+
+    /**
+     * A common state to represent when the state is not known. One example is if the device is
+     * closed. We do not emit this value for developers but is useful for implementation reasons.
+     */
+    public static final int COMMON_STATE_UNKNOWN = -1;
+
+    /**
+     * A common state to represent a FLAT hinge. This is needed because the definitions in Sidecar
+     * and Extensions do not match exactly.
+     */
+    public static final int COMMON_STATE_FLAT = 3;
+    /**
+     * A common state to represent a HALF_OPENED hinge. This is needed because the definitions in
+     * Sidecar and Extensions do not match exactly.
+     */
+    public static final int COMMON_STATE_HALF_OPENED = 2;
+
+    /**
+     * The possible states for a folding hinge.
+     */
+    @IntDef({COMMON_STATE_UNKNOWN, COMMON_STATE_FLAT, COMMON_STATE_HALF_OPENED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface State {
+    }
+
+    private static final Pattern FEATURE_PATTERN =
+            Pattern.compile("([a-z]+)-\\[(\\d+),(\\d+),(\\d+),(\\d+)]-?(flat|half-opened)?");
+
+    private static final String FEATURE_TYPE_FOLD = "fold";
+    private static final String FEATURE_TYPE_HINGE = "hinge";
+
+    private static final String PATTERN_STATE_FLAT = "flat";
+    private static final String PATTERN_STATE_HALF_OPENED = "half-opened";
+
+    /**
+     * Parse a {@link List} of {@link CommonFoldingFeature} from a {@link String}.
+     * @param value a {@link String} representation of multiple {@link CommonFoldingFeature}
+     *              separated by a ":".
+     * @param hingeState a global fallback value for a {@link CommonFoldingFeature} if one is not
+     *                   specified in the input.
+     * @throws IllegalArgumentException if the provided string is improperly formatted or could not
+     * otherwise be parsed.
+     * @see #FEATURE_PATTERN
+     * @return {@link List} of {@link CommonFoldingFeature}.
+     */
+    static List<CommonFoldingFeature> parseListFromString(@NonNull String value,
+            @State int hingeState) {
+        List<CommonFoldingFeature> features = new ArrayList<>();
+        String[] featureStrings =  value.split(";");
+        for (String featureString : featureStrings) {
+            CommonFoldingFeature feature;
+            try {
+                feature = CommonFoldingFeature.parseFromString(featureString, hingeState);
+            } catch (IllegalArgumentException e) {
+                if (DEBUG) {
+                    Log.w(TAG, "Failed to parse display feature: " + featureString, e);
+                }
+                continue;
+            }
+            features.add(feature);
+        }
+        return features;
+    }
+
+    /**
+     * Parses a display feature from a string.
+     *
+     * @param string A {@link String} representation of a {@link CommonFoldingFeature}.
+     * @param hingeState A fallback value for the {@link State} if it is not specified in the input.
+     * @throws IllegalArgumentException if the provided string is improperly formatted or could not
+     *                                  otherwise be parsed.
+     * @return {@link CommonFoldingFeature} represented by the {@link String} value.
+     * @see #FEATURE_PATTERN
+     */
+    @NonNull
+    private static CommonFoldingFeature parseFromString(@NonNull String string,
+            @State int hingeState) {
+        Matcher featureMatcher = FEATURE_PATTERN.matcher(string);
+        if (!featureMatcher.matches()) {
+            throw new IllegalArgumentException("Malformed feature description format: " + string);
+        }
+        try {
+            String featureType = featureMatcher.group(1);
+            featureType = featureType == null ? "" : featureType;
+            int type;
+            switch (featureType) {
+                case FEATURE_TYPE_FOLD:
+                    type = COMMON_TYPE_FOLD;
+                    break;
+                case FEATURE_TYPE_HINGE:
+                    type = COMMON_TYPE_HINGE;
+                    break;
+                default: {
+                    throw new IllegalArgumentException("Malformed feature type: " + featureType);
+                }
+            }
+
+            int left = Integer.parseInt(featureMatcher.group(2));
+            int top = Integer.parseInt(featureMatcher.group(3));
+            int right = Integer.parseInt(featureMatcher.group(4));
+            int bottom = Integer.parseInt(featureMatcher.group(5));
+            Rect featureRect = new Rect(left, top, right, bottom);
+            if (isZero(featureRect)) {
+                throw new IllegalArgumentException("Feature has empty bounds: " + string);
+            }
+            String stateString = featureMatcher.group(6);
+            stateString = stateString == null ? "" : stateString;
+            final int state;
+            switch (stateString) {
+                case PATTERN_STATE_FLAT:
+                    state = COMMON_STATE_FLAT;
+                    break;
+                case PATTERN_STATE_HALF_OPENED:
+                    state = COMMON_STATE_HALF_OPENED;
+                    break;
+                default:
+                    state = hingeState;
+                    break;
+            }
+            return new CommonFoldingFeature(type, state, featureRect);
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException("Malformed feature description: " + string, e);
+        }
+    }
+
+    private final int mType;
+    @Nullable
+    private final int mState;
+    @NonNull
+    private final Rect mRect;
+
+    CommonFoldingFeature(int type, int state, @NonNull Rect rect) {
+        assertValidState(state);
+        this.mType = type;
+        this.mState = state;
+        if (rect.width() == 0 && rect.height() == 0) {
+            throw new IllegalArgumentException(
+                    "Display feature rectangle cannot have zero width and height simultaneously.");
+        }
+        this.mRect = rect;
+    }
+
+    /** Returns the type of the feature. */
+    @Type
+    public int getType() {
+        return mType;
+    }
+
+    /** Returns the state of the feature.*/
+    @State
+    public int getState() {
+        return mState;
+    }
+
+    /** Returns the bounds of the feature. */
+    @NonNull
+    public Rect getRect() {
+        return mRect;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        CommonFoldingFeature that = (CommonFoldingFeature) o;
+        return mType == that.mType
+                && Objects.equals(mState, that.mState)
+                && mRect.equals(that.mRect);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mType, mState, mRect);
+    }
+
+    private static void assertValidState(@Nullable Integer state) {
+        if (state != null && state != COMMON_STATE_FLAT && state != COMMON_STATE_HALF_OPENED) {
+            throw new IllegalArgumentException("Invalid state: " + state
+                    + "must be either COMMON_STATE_FLAT or COMMON_STATE_HALF_OPENED");
+        }
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
similarity index 72%
rename from libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java
rename to libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index fa9a5a8..6987401 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerPostureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -18,11 +18,15 @@
 
 import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
 
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
+import static androidx.window.common.CommonFoldingFeature.parseListFromString;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.hardware.devicestate.DeviceStateManager;
 import android.hardware.devicestate.DeviceStateManager.DeviceStateCallback;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseIntArray;
 
@@ -30,6 +34,7 @@
 
 import com.android.internal.R;
 
+import java.util.List;
 import java.util.Optional;
 
 /**
@@ -37,10 +42,13 @@
  * by mapping the state returned from {@link DeviceStateManager} to values provided in the resources
  * config at {@link R.array#config_device_state_postures}.
  */
-public final class DeviceStateManagerPostureProducer extends BaseDataProducer<Integer> {
-    private static final String TAG = "ConfigDevicePostureProducer";
+public final class DeviceStateManagerFoldingFeatureProducer extends
+        BaseDataProducer<List<CommonFoldingFeature>> {
+    private static final String TAG =
+            DeviceStateManagerFoldingFeatureProducer.class.getSimpleName();
     private static final boolean DEBUG = false;
 
+    private final Context mContext;
     private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();
 
     private int mCurrentDeviceState = INVALID_DEVICE_STATE;
@@ -50,7 +58,8 @@
         notifyDataChanged();
     };
 
-    public DeviceStateManagerPostureProducer(@NonNull Context context) {
+    public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context) {
+        mContext = context;
         String[] deviceStatePosturePairs = context.getResources()
                 .getStringArray(R.array.config_device_state_postures);
         for (String deviceStatePosturePair : deviceStatePosturePairs) {
@@ -86,8 +95,17 @@
 
     @Override
     @Nullable
-    public Optional<Integer> getData() {
-        final int posture = mDeviceStateToPostureMap.get(mCurrentDeviceState, -1);
-        return posture != -1 ? Optional.of(posture) : Optional.empty();
+    public Optional<List<CommonFoldingFeature>> getData() {
+        final int globalHingeState = globalHingeState();
+        String displayFeaturesString = mContext.getResources().getString(
+                R.string.config_display_features);
+        if (TextUtils.isEmpty(displayFeaturesString)) {
+            return Optional.empty();
+        }
+        return Optional.of(parseListFromString(displayFeaturesString, globalHingeState));
+    }
+
+    private int globalHingeState() {
+        return mDeviceStateToPostureMap.get(mCurrentDeviceState, COMMON_STATE_UNKNOWN);
     }
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java
deleted file mode 100644
index 5736418..0000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DisplayFeature.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.common;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.graphics.Rect;
-
-import androidx.annotation.NonNull;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/** Wrapper for both Extension and Sidecar versions of DisplayFeature. */
-public interface DisplayFeature {
-    /** Returns the type of the feature. */
-    int getType();
-
-    /** Returns the state of the feature, or {@code null} if the feature has no state. */
-    @Nullable
-    @State
-    Integer getState();
-
-    /** Returns the bounds of the feature. */
-    @NonNull
-    Rect getRect();
-
-    /**
-     * A common state to represent a FLAT hinge. This is needed because the definitions in Sidecar
-     * and Extensions do not match exactly.
-     */
-    int COMMON_STATE_FLAT = 3;
-    /**
-     * A common state to represent a HALF_OPENED hinge. This is needed because the definitions in
-     * Sidecar and Extensions do not match exactly.
-     */
-    int COMMON_STATE_HALF_OPENED = 2;
-
-    /**
-     * The possible states for a folding hinge.
-     */
-    @IntDef({COMMON_STATE_FLAT, COMMON_STATE_HALF_OPENED})
-    @Retention(RetentionPolicy.SOURCE)
-    @interface State {}
-
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/EmptyLifecycleCallbacksAdapter.java b/libs/WindowManager/Jetpack/src/androidx/window/common/EmptyLifecycleCallbacksAdapter.java
new file mode 100644
index 0000000..d923a46
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/EmptyLifecycleCallbacksAdapter.java
@@ -0,0 +1,55 @@
+/*
+ * 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 androidx.window.common;
+
+import android.app.Activity;
+import android.app.Application;
+import android.os.Bundle;
+
+/**
+ * An empty implementation of {@link Application.ActivityLifecycleCallbacks} derived classes can
+ * implement the methods necessary.
+ */
+public class EmptyLifecycleCallbacksAdapter implements Application.ActivityLifecycleCallbacks {
+    @Override
+    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+    }
+
+    @Override
+    public void onActivityStarted(Activity activity) {
+    }
+
+    @Override
+    public void onActivityResumed(Activity activity) {
+    }
+
+    @Override
+    public void onActivityPaused(Activity activity) {
+    }
+
+    @Override
+    public void onActivityStopped(Activity activity) {
+    }
+
+    @Override
+    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
+    }
+
+    @Override
+    public void onActivityDestroyed(Activity activity) {
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java
deleted file mode 100644
index cd2cadc..0000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/ResourceConfigDisplayFeatureProducer.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.common;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.window.util.BaseDataProducer;
-
-import com.android.internal.R;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/**
- * Implementation of {@link androidx.window.util.DataProducer} that produces
- * {@link CommonDisplayFeature} parsed from a string stored in the resources config at
- * {@link R.string#config_display_features}.
- */
-public final class ResourceConfigDisplayFeatureProducer extends
-        BaseDataProducer<List<DisplayFeature>> {
-    private static final boolean DEBUG = false;
-    private static final String TAG = "ResourceConfigDisplayFeatureProducer";
-
-    private final Context mContext;
-
-    public ResourceConfigDisplayFeatureProducer(@NonNull Context context) {
-        mContext = context;
-    }
-
-    @Override
-    @Nullable
-    public Optional<List<DisplayFeature>> getData() {
-        String displayFeaturesString = mContext.getResources().getString(
-                R.string.config_display_features);
-        if (TextUtils.isEmpty(displayFeaturesString)) {
-            return Optional.empty();
-        }
-
-        List<DisplayFeature> features = new ArrayList<>();
-        String[] featureStrings =  displayFeaturesString.split(";");
-        for (String featureString : featureStrings) {
-            CommonDisplayFeature feature;
-            try {
-                feature = CommonDisplayFeature.parseFromString(featureString);
-            } catch (IllegalArgumentException e) {
-                if (DEBUG) {
-                    Log.w(TAG, "Failed to parse display feature: " + featureString, e);
-                }
-                continue;
-            }
-            features.add(feature);
-        }
-        return Optional.of(features);
-    }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java
deleted file mode 100644
index 2026df3..0000000
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDevicePostureProducer.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.common;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.Settings;
-
-import androidx.window.util.BaseDataProducer;
-
-import java.util.Optional;
-
-/**
- * Implementation of {@link androidx.window.util.DataProducer} that provides the device posture
- * as an {@link Integer} from a value stored in {@link Settings}.
- */
-public final class SettingsDevicePostureProducer extends BaseDataProducer<Integer> {
-    private static final String DEVICE_POSTURE = "device_posture";
-
-    private final Uri mDevicePostureUri =
-            Settings.Global.getUriFor(DEVICE_POSTURE);
-
-    private final ContentResolver mResolver;
-    private final ContentObserver mObserver;
-    private boolean mRegisteredObservers;
-
-    public SettingsDevicePostureProducer(@NonNull Context context) {
-        mResolver = context.getContentResolver();
-        mObserver = new SettingsObserver();
-    }
-
-    @Override
-    @Nullable
-    public Optional<Integer> getData() {
-        int posture = Settings.Global.getInt(mResolver, DEVICE_POSTURE, -1);
-        return posture == -1 ? Optional.empty() : Optional.of(posture);
-    }
-
-    /**
-     * Registers settings observers, if needed. When settings observers are registered for this
-     * producer callbacks for changes in data will be triggered.
-     */
-    public void registerObserversIfNeeded() {
-        if (mRegisteredObservers) {
-            return;
-        }
-        mRegisteredObservers = true;
-        mResolver.registerContentObserver(mDevicePostureUri, false /* notifyForDescendants */,
-                mObserver /* ContentObserver */);
-    }
-
-    /**
-     * Unregisters settings observers, if needed. When settings observers are unregistered for this
-     * producer callbacks for changes in data will not be triggered.
-     */
-    public void unregisterObserversIfNeeded() {
-        if (!mRegisteredObservers) {
-            return;
-        }
-        mRegisteredObservers = false;
-        mResolver.unregisterContentObserver(mObserver);
-    }
-
-    private final class SettingsObserver extends ContentObserver {
-        SettingsObserver() {
-            super(new Handler(Looper.getMainLooper()));
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            if (mDevicePostureUri.equals(uri)) {
-                notifyDataChanged();
-            }
-        }
-    }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
index 0406626..e9d213e 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
@@ -16,8 +16,10 @@
 
 package androidx.window.common;
 
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
+import static androidx.window.common.CommonFoldingFeature.parseListFromString;
+
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
@@ -26,22 +28,19 @@
 import android.os.Looper;
 import android.provider.Settings;
 import android.text.TextUtils;
-import android.util.Log;
 
 import androidx.window.util.BaseDataProducer;
 
-import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 
 /**
  * Implementation of {@link androidx.window.util.DataProducer} that produces
- * {@link CommonDisplayFeature} parsed from a string stored in {@link Settings}.
+ * {@link CommonFoldingFeature} parsed from a string stored in {@link Settings}.
  */
 public final class SettingsDisplayFeatureProducer
-        extends BaseDataProducer<List<DisplayFeature>> {
-    private static final boolean DEBUG = false;
-    private static final String TAG = "SettingsDisplayFeatureProducer";
+        extends BaseDataProducer<List<CommonFoldingFeature>> {
     private static final String DISPLAY_FEATURES = "display_features";
 
     private final Uri mDisplayFeaturesUri =
@@ -57,32 +56,17 @@
     }
 
     @Override
-    @Nullable
-    public Optional<List<DisplayFeature>> getData() {
+    @NonNull
+    public Optional<List<CommonFoldingFeature>> getData() {
         String displayFeaturesString = Settings.Global.getString(mResolver, DISPLAY_FEATURES);
         if (displayFeaturesString == null) {
             return Optional.empty();
         }
 
-        List<DisplayFeature> features = new ArrayList<>();
         if (TextUtils.isEmpty(displayFeaturesString)) {
-            return Optional.of(features);
+            return Optional.of(Collections.emptyList());
         }
-        String[] featureStrings =  displayFeaturesString.split(";");
-
-        for (String featureString : featureStrings) {
-            CommonDisplayFeature feature;
-            try {
-                feature = CommonDisplayFeature.parseFromString(featureString);
-            } catch (IllegalArgumentException e) {
-                if (DEBUG) {
-                    Log.w(TAG, "Failed to parse display feature: " + featureString, e);
-                }
-                continue;
-            }
-            features.add(feature);
-        }
-        return Optional.of(features);
+        return Optional.of(parseListFromString(displayFeaturesString, COMMON_STATE_UNKNOWN));
     }
 
     /**
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 6d83833..1d2b938 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -28,7 +28,6 @@
 import android.app.ActivityClient;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
-import android.app.Application.ActivityLifecycleCallbacks;
 import android.app.Instrumentation;
 import android.content.Context;
 import android.content.Intent;
@@ -41,6 +40,8 @@
 import android.window.TaskFragmentInfo;
 import android.window.WindowContainerTransaction;
 
+import androidx.window.common.EmptyLifecycleCallbacksAdapter;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -763,11 +764,7 @@
         return shouldRetainAssociatedContainer(finishingContainer, associatedContainer);
     }
 
-    private final class LifecycleCallbacks implements ActivityLifecycleCallbacks {
-
-        @Override
-        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
-        }
+    private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter {
 
         @Override
         public void onActivityPostCreated(Activity activity, Bundle savedInstanceState) {
@@ -779,30 +776,6 @@
         }
 
         @Override
-        public void onActivityStarted(Activity activity) {
-        }
-
-        @Override
-        public void onActivityResumed(Activity activity) {
-        }
-
-        @Override
-        public void onActivityPaused(Activity activity) {
-        }
-
-        @Override
-        public void onActivityStopped(Activity activity) {
-        }
-
-        @Override
-        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
-        }
-
-        @Override
-        public void onActivityDestroyed(Activity activity) {
-        }
-
-        @Override
         public void onActivityConfigurationChanged(Activity activity) {
             SplitController.this.onActivityConfigurationChanged(activity);
         }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationAdapter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationAdapter.java
index 89d7a40..b3becad 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationAdapter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationAdapter.java
@@ -33,6 +33,12 @@
  * The base adapter can be used for {@link RemoteAnimationTarget} that is simple open/close.
  */
 class TaskFragmentAnimationAdapter {
+
+    /**
+     * If {@link #mOverrideLayer} is set to this value, we don't want to override the surface layer.
+     */
+    private static final int LAYER_NO_OVERRIDE = -1;
+
     final Animation mAnimation;
     final RemoteAnimationTarget mTarget;
     final SurfaceControl mLeash;
@@ -42,6 +48,7 @@
     final float[] mVecs = new float[4];
     final Rect mRect = new Rect();
     private boolean mIsFirstFrame = true;
+    private int mOverrideLayer = LAYER_NO_OVERRIDE;
 
     TaskFragmentAnimationAdapter(@NonNull Animation animation,
             @NonNull RemoteAnimationTarget target) {
@@ -58,10 +65,21 @@
         mLeash = leash;
     }
 
+    /**
+     * Surface layer to be set at the first frame of the animation. We will not set the layer if it
+     * is set to {@link #LAYER_NO_OVERRIDE}.
+     */
+    final void overrideLayer(int layer) {
+        mOverrideLayer = layer;
+    }
+
     /** Called on frame update. */
     final void onAnimationUpdate(@NonNull SurfaceControl.Transaction t, long currentPlayTime) {
         if (mIsFirstFrame) {
             t.show(mLeash);
+            if (mOverrideLayer != LAYER_NO_OVERRIDE) {
+                t.setLayer(mLeash, mOverrideLayer);
+            }
             mIsFirstFrame = false;
         }
 
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
index 46bdf6d..1ac3317 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
@@ -25,6 +25,7 @@
 import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
 import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
 import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
+import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET;
 
 import android.animation.Animator;
 import android.animation.ValueAnimator;
@@ -181,18 +182,22 @@
 
     private List<TaskFragmentAnimationAdapter> createOpenAnimationAdapters(
             @NonNull RemoteAnimationTarget[] targets) {
-        return createOpenCloseAnimationAdapters(targets,
+        return createOpenCloseAnimationAdapters(targets, true /* isOpening */,
                 mAnimationSpec::loadOpenAnimation);
     }
 
     private List<TaskFragmentAnimationAdapter> createCloseAnimationAdapters(
             @NonNull RemoteAnimationTarget[] targets) {
-        return createOpenCloseAnimationAdapters(targets,
+        return createOpenCloseAnimationAdapters(targets, false /* isOpening */,
                 mAnimationSpec::loadCloseAnimation);
     }
 
+    /**
+     * Creates {@link TaskFragmentAnimationAdapter} for OPEN and CLOSE types of transition.
+     * @param isOpening {@code true} for OPEN type, {@code false} for CLOSE type.
+     */
     private List<TaskFragmentAnimationAdapter> createOpenCloseAnimationAdapters(
-            @NonNull RemoteAnimationTarget[] targets,
+            @NonNull RemoteAnimationTarget[] targets, boolean isOpening,
             @NonNull BiFunction<RemoteAnimationTarget, Rect, Animation> animationProvider) {
         // We need to know if the target window is only a partial of the whole animation screen.
         // If so, we will need to adjust it to make the whole animation screen looks like one.
@@ -210,14 +215,25 @@
             }
         }
 
+        // For OPEN transition, open windows should be above close windows.
+        // For CLOSE transition, open windows should be below close windows.
+        int offsetLayer = TYPE_LAYER_OFFSET;
         final List<TaskFragmentAnimationAdapter> adapters = new ArrayList<>();
         for (RemoteAnimationTarget target : openingTargets) {
-            adapters.add(createOpenCloseAnimationAdapter(target, animationProvider,
-                    openingWholeScreenBounds));
+            final TaskFragmentAnimationAdapter adapter = createOpenCloseAnimationAdapter(target,
+                    animationProvider, openingWholeScreenBounds);
+            if (isOpening) {
+                adapter.overrideLayer(offsetLayer++);
+            }
+            adapters.add(adapter);
         }
         for (RemoteAnimationTarget target : closingTargets) {
-            adapters.add(createOpenCloseAnimationAdapter(target, animationProvider,
-                    closingWholeScreenBounds));
+            final TaskFragmentAnimationAdapter adapter = createOpenCloseAnimationAdapter(target,
+                    animationProvider, closingWholeScreenBounds);
+            if (!isOpening) {
+                adapter.overrideLayer(offsetLayer++);
+            }
+            adapters.add(adapter);
         }
         return adapters;
     }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index fe9ce97..a4fbdbc 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -18,28 +18,30 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 
-import static androidx.window.common.DisplayFeature.COMMON_STATE_FLAT;
-import static androidx.window.common.DisplayFeature.COMMON_STATE_HALF_OPENED;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
 import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation;
 import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
 
 import android.annotation.Nullable;
 import android.app.Activity;
+import android.app.Application;
 import android.content.Context;
 import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.util.ArrayMap;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
-import androidx.window.common.DeviceStateManagerPostureProducer;
-import androidx.window.common.DisplayFeature;
-import androidx.window.common.ResourceConfigDisplayFeatureProducer;
-import androidx.window.common.SettingsDevicePostureProducer;
+import androidx.window.common.CommonFoldingFeature;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
+import androidx.window.common.EmptyLifecycleCallbacksAdapter;
 import androidx.window.common.SettingsDisplayFeatureProducer;
 import androidx.window.util.DataProducer;
 import androidx.window.util.PriorityDataProducer;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -56,36 +58,27 @@
  */
 public class WindowLayoutComponentImpl implements WindowLayoutComponent {
     private static final String TAG = "SampleExtension";
-    private static WindowLayoutComponent sInstance;
 
     private final Map<Activity, Consumer<WindowLayoutInfo>> mWindowLayoutChangeListeners =
-            new HashMap<>();
-
-    private final SettingsDevicePostureProducer mSettingsDevicePostureProducer;
-    private final DataProducer<Integer> mDevicePostureProducer;
+            new ArrayMap<>();
 
     private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
-    private final DataProducer<List<DisplayFeature>> mDisplayFeatureProducer;
+    private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
 
     public WindowLayoutComponentImpl(Context context) {
-        mSettingsDevicePostureProducer = new SettingsDevicePostureProducer(context);
-        mDevicePostureProducer = new PriorityDataProducer<>(List.of(
-                mSettingsDevicePostureProducer,
-                new DeviceStateManagerPostureProducer(context)
-        ));
-
+        ((Application) context.getApplicationContext())
+                .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
         mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
-        mDisplayFeatureProducer = new PriorityDataProducer<>(List.of(
+        mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
                 mSettingsDisplayFeatureProducer,
-                new ResourceConfigDisplayFeatureProducer(context)
+                new DeviceStateManagerFoldingFeatureProducer(context)
         ));
-
-        mDevicePostureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
-        mDisplayFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
+        mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
     }
 
     /**
      * Adds a listener interested in receiving updates to {@link WindowLayoutInfo}
+     *
      * @param activity hosting a {@link android.view.Window}
      * @param consumer interested in receiving updates to {@link WindowLayoutInfo}
      */
@@ -97,6 +90,7 @@
 
     /**
      * Removes a listener no longer interested in receiving updates.
+     *
      * @param consumer no longer interested in receiving updates to {@link WindowLayoutInfo}
      */
     public void removeWindowLayoutInfoListener(
@@ -118,43 +112,34 @@
         return mWindowLayoutChangeListeners.keySet();
     }
 
+    @NonNull
+    private boolean isListeningForLayoutChanges(IBinder token) {
+        for (Activity activity: getActivitiesListeningForLayoutChanges()) {
+            if (token.equals(activity.getWindow().getAttributes().token)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     protected boolean hasListeners() {
         return !mWindowLayoutChangeListeners.isEmpty();
     }
 
     /**
-     * Calculate the {@link DisplayFeature.State} from the feature or the device posture producer.
-     * If the given {@link DisplayFeature.State} is not valid then {@code null} will be returned.
-     * The {@link FoldingFeature} should be ignored in the case of an invalid
-     * {@link DisplayFeature.State}.
-     *
-     * @param feature a {@link DisplayFeature} to provide the feature state if present.
-     * @return {@link DisplayFeature.State} of the hinge if present or the state from the posture
-     * produce if present.
-     */
-    @Nullable
-    private Integer getFeatureState(DisplayFeature feature) {
-        Integer featureState = feature.getState();
-        Optional<Integer> posture = mDevicePostureProducer.getData();
-        Integer state = featureState == null ? posture.orElse(null) : featureState;
-        return convertToExtensionState(state);
-    }
-
-    /**
      * A convenience method to translate from the common feature state to the extensions feature
-     * state.  More specifically, translates from {@link DisplayFeature.State} to
+     * state.  More specifically, translates from {@link CommonFoldingFeature.State} to
      * {@link FoldingFeature.STATE_FLAT} or {@link FoldingFeature.STATE_HALF_OPENED}. If it is not
      * possible to translate, then we will return a {@code null} value.
      *
-     * @param state if it matches a value in {@link DisplayFeature.State}, {@code null} otherwise.
-     * @return a {@link FoldingFeature.STATE_FLAT} or {@link FoldingFeature.STATE_HALF_OPENED} if
-     * the given state matches a value in {@link DisplayFeature.State} and {@code null} otherwise.
+     * @param state if it matches a value in {@link CommonFoldingFeature.State}, {@code null}
+     *              otherwise. @return a {@link FoldingFeature.STATE_FLAT} or
+     *              {@link FoldingFeature.STATE_HALF_OPENED} if the given state matches a value in
+     *              {@link CommonFoldingFeature.State} and {@code null} otherwise.
      */
     @Nullable
-    private Integer convertToExtensionState(@Nullable Integer state) {
-        if (state == null) { // The null check avoids a NullPointerException.
-            return null;
-        } else if (state == COMMON_STATE_FLAT) {
+    private Integer convertToExtensionState(int state) {
+        if (state == COMMON_STATE_FLAT) {
             return FoldingFeature.STATE_FLAT;
         } else if (state == COMMON_STATE_HALF_OPENED) {
             return FoldingFeature.STATE_HALF_OPENED;
@@ -172,33 +157,30 @@
 
     @NonNull
     private WindowLayoutInfo getWindowLayoutInfo(@NonNull Activity activity) {
-        List<androidx.window.extensions.layout.DisplayFeature> displayFeatures =
-                getDisplayFeatures(activity);
+        List<DisplayFeature> displayFeatures = getDisplayFeatures(activity);
         return new WindowLayoutInfo(displayFeatures);
     }
 
     /**
-     * Translate from the {@link DisplayFeature} to
-     * {@link androidx.window.extensions.layout.DisplayFeature} for a given {@link Activity}. If a
-     * {@link DisplayFeature} is not valid then it will be omitted.
+     * Translate from the {@link CommonFoldingFeature} to
+     * {@link DisplayFeature} for a given {@link Activity}. If a
+     * {@link CommonFoldingFeature} is not valid then it will be omitted.
      *
      * For a {@link FoldingFeature} the bounds are localized into the {@link Activity} window
-     * coordinate space and the state is calculated either from {@link DisplayFeature#getState()} or
-     * {@link #mDisplayFeatureProducer}. The state from {@link #mDisplayFeatureProducer} may not be
-     * valid since {@link #mDisplayFeatureProducer} is a general state controller. If the state is
-     * not valid, the {@link FoldingFeature} is omitted from the {@link List} of
-     * {@link androidx.window.extensions.layout.DisplayFeature}. If the bounds are not valid,
-     * constructing a {@link FoldingFeature} will throw an {@link IllegalArgumentException} since
-     * this can cause negative UI effects down stream.
+     * coordinate space and the state is calculated from {@link CommonFoldingFeature#getState()}.
+     * The state from {@link #mFoldingFeatureProducer} may not be valid since
+     * {@link #mFoldingFeatureProducer} is a general state controller. If the state is not valid,
+     * the {@link FoldingFeature} is omitted from the {@link List} of {@link DisplayFeature}. If the
+     * bounds are not valid, constructing a {@link FoldingFeature} will throw an
+     * {@link IllegalArgumentException} since this can cause negative UI effects down stream.
      *
      * @param activity a proxy for the {@link android.view.Window} that contains the
-     * {@link androidx.window.extensions.layout.DisplayFeature}.
-     * @return a {@link List} of valid {@link androidx.window.extensions.layout.DisplayFeature} that
+     * {@link DisplayFeature}.
+     * @return a {@link List} of valid {@link DisplayFeature} that
      * are within the {@link android.view.Window} of the {@link Activity}
      */
-    private List<androidx.window.extensions.layout.DisplayFeature> getDisplayFeatures(
-            @NonNull Activity activity) {
-        List<androidx.window.extensions.layout.DisplayFeature> features = new ArrayList<>();
+    private List<DisplayFeature> getDisplayFeatures(@NonNull Activity activity) {
+        List<DisplayFeature> features = new ArrayList<>();
         int displayId = activity.getDisplay().getDisplayId();
         if (displayId != DEFAULT_DISPLAY) {
             Log.w(TAG, "This sample doesn't support display features on secondary displays");
@@ -211,11 +193,10 @@
             return features;
         }
 
-        Optional<List<DisplayFeature>> storedFeatures = mDisplayFeatureProducer.getData();
+        Optional<List<CommonFoldingFeature>> storedFeatures = mFoldingFeatureProducer.getData();
         if (storedFeatures.isPresent()) {
-
-            for (DisplayFeature baseFeature : storedFeatures.get()) {
-                Integer state = getFeatureState(baseFeature);
+            for (CommonFoldingFeature baseFeature : storedFeatures.get()) {
+                Integer state = convertToExtensionState(baseFeature.getState());
                 if (state == null) {
                     continue;
                 }
@@ -223,8 +204,7 @@
                 rotateRectToDisplayRotation(displayId, featureRect);
                 transformToWindowSpaceRect(activity, featureRect);
 
-                features.add(new FoldingFeature(featureRect, baseFeature.getType(),
-                        getFeatureState(baseFeature)));
+                features.add(new FoldingFeature(featureRect, baseFeature.getType(), state));
             }
         }
         return features;
@@ -232,13 +212,31 @@
 
     private void updateRegistrations() {
         if (hasListeners()) {
-            mSettingsDevicePostureProducer.registerObserversIfNeeded();
             mSettingsDisplayFeatureProducer.registerObserversIfNeeded();
         } else {
-            mSettingsDevicePostureProducer.unregisterObserversIfNeeded();
             mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded();
         }
-
         onDisplayFeaturesChanged();
     }
+
+    private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter {
+        @Override
+        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+            super.onActivityCreated(activity, savedInstanceState);
+            onDisplayFeaturesChangedIfListening(activity);
+        }
+
+        @Override
+        public void onActivityConfigurationChanged(Activity activity) {
+            super.onActivityConfigurationChanged(activity);
+            onDisplayFeaturesChangedIfListening(activity);
+        }
+
+        private void onDisplayFeaturesChangedIfListening(Activity activity) {
+            IBinder token = activity.getWindow().getAttributes().token;
+            if (token == null || isListeningForLayoutChanges(token)) {
+                onDisplayFeaturesChanged();
+            }
+        }
+    }
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
index aa949f1..c7b7093 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
@@ -23,16 +23,17 @@
 
 import android.app.Activity;
 import android.app.ActivityThread;
+import android.app.Application;
 import android.content.Context;
 import android.graphics.Rect;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
-import androidx.window.common.DeviceStateManagerPostureProducer;
-import androidx.window.common.DisplayFeature;
-import androidx.window.common.ResourceConfigDisplayFeatureProducer;
-import androidx.window.common.SettingsDevicePostureProducer;
+import androidx.window.common.CommonFoldingFeature;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
+import androidx.window.common.EmptyLifecycleCallbacksAdapter;
 import androidx.window.common.SettingsDisplayFeatureProducer;
 import androidx.window.util.DataProducer;
 import androidx.window.util.PriorityDataProducer;
@@ -48,36 +49,25 @@
  */
 class SampleSidecarImpl extends StubSidecar {
     private static final String TAG = "SampleSidecar";
-    private static final boolean DEBUG = false;
 
-    private final SettingsDevicePostureProducer mSettingsDevicePostureProducer;
-    private final DataProducer<Integer> mDevicePostureProducer;
+    private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
 
-    private final SettingsDisplayFeatureProducer mSettingsDisplayFeatureProducer;
-    private final DataProducer<List<DisplayFeature>> mDisplayFeatureProducer;
+    private final SettingsDisplayFeatureProducer mSettingsFoldingFeatureProducer;
 
     SampleSidecarImpl(Context context) {
-        mSettingsDevicePostureProducer = new SettingsDevicePostureProducer(context);
-        mDevicePostureProducer = new PriorityDataProducer<>(List.of(
-                mSettingsDevicePostureProducer,
-                new DeviceStateManagerPostureProducer(context)
+        ((Application) context.getApplicationContext())
+                .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
+        mSettingsFoldingFeatureProducer = new SettingsDisplayFeatureProducer(context);
+        mFoldingFeatureProducer = new PriorityDataProducer<>(List.of(
+                mSettingsFoldingFeatureProducer,
+                new DeviceStateManagerFoldingFeatureProducer(context)
         ));
 
-        mSettingsDisplayFeatureProducer = new SettingsDisplayFeatureProducer(context);
-        mDisplayFeatureProducer = new PriorityDataProducer<>(List.of(
-                mSettingsDisplayFeatureProducer,
-                new ResourceConfigDisplayFeatureProducer(context)
-        ));
-
-        mDevicePostureProducer.addDataChangedCallback(this::onDevicePostureChanged);
-        mDisplayFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
-    }
-
-    private void onDevicePostureChanged() {
-        updateDeviceState(getDeviceState());
+        mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
     }
 
     private void onDisplayFeaturesChanged() {
+        updateDeviceState(getDeviceState());
         for (IBinder windowToken : getWindowsListeningForLayoutChanges()) {
             SidecarWindowLayoutInfo newLayout = getWindowLayoutInfo(windowToken);
             updateWindowLayout(windowToken, newLayout);
@@ -87,27 +77,21 @@
     @NonNull
     @Override
     public SidecarDeviceState getDeviceState() {
-        Optional<Integer> posture = mDevicePostureProducer.getData();
-
         SidecarDeviceState deviceState = new SidecarDeviceState();
-        deviceState.posture = posture.orElse(deviceStateFromFeature());
+        deviceState.posture = deviceStateFromFeature();
         return deviceState;
     }
 
     private int deviceStateFromFeature() {
-        List<DisplayFeature> storedFeatures = mDisplayFeatureProducer.getData()
+        List<CommonFoldingFeature> storedFeatures = mFoldingFeatureProducer.getData()
                 .orElse(Collections.emptyList());
         for (int i = 0; i < storedFeatures.size(); i++) {
-            DisplayFeature feature = storedFeatures.get(i);
-            final int state = feature.getState() == null ? -1 : feature.getState();
-            if (DEBUG && feature.getState() == null) {
-                Log.d(TAG, "feature#getState was null for DisplayFeature: " + feature);
-            }
-
+            CommonFoldingFeature feature = storedFeatures.get(i);
+            final int state = feature.getState();
             switch (state) {
-                case DisplayFeature.COMMON_STATE_FLAT:
+                case CommonFoldingFeature.COMMON_STATE_FLAT:
                     return SidecarDeviceState.POSTURE_OPENED;
-                case DisplayFeature.COMMON_STATE_HALF_OPENED:
+                case CommonFoldingFeature.COMMON_STATE_HALF_OPENED:
                     return SidecarDeviceState.POSTURE_HALF_OPENED;
             }
         }
@@ -127,22 +111,22 @@
     }
 
     private List<SidecarDisplayFeature> getDisplayFeatures(@NonNull Activity activity) {
-        List<SidecarDisplayFeature> features = new ArrayList<SidecarDisplayFeature>();
         int displayId = activity.getDisplay().getDisplayId();
         if (displayId != DEFAULT_DISPLAY) {
             Log.w(TAG, "This sample doesn't support display features on secondary displays");
-            return features;
+            return Collections.emptyList();
         }
 
         if (activity.isInMultiWindowMode()) {
             // It is recommended not to report any display features in multi-window mode, since it
             // won't be possible to synchronize the display feature positions with window movement.
-            return features;
+            return Collections.emptyList();
         }
 
-        Optional<List<DisplayFeature>> storedFeatures = mDisplayFeatureProducer.getData();
+        Optional<List<CommonFoldingFeature>> storedFeatures = mFoldingFeatureProducer.getData();
+        List<SidecarDisplayFeature> features = new ArrayList<>();
         if (storedFeatures.isPresent()) {
-            for (DisplayFeature baseFeature : storedFeatures.get()) {
+            for (CommonFoldingFeature baseFeature : storedFeatures.get()) {
                 SidecarDisplayFeature feature = new SidecarDisplayFeature();
                 Rect featureRect = baseFeature.getRect();
                 rotateRectToDisplayRotation(displayId, featureRect);
@@ -152,17 +136,37 @@
                 features.add(feature);
             }
         }
-        return features;
+        return Collections.unmodifiableList(features);
     }
 
     @Override
     protected void onListenersChanged() {
         if (hasListeners()) {
-            mSettingsDevicePostureProducer.registerObserversIfNeeded();
-            mSettingsDisplayFeatureProducer.registerObserversIfNeeded();
+            mSettingsFoldingFeatureProducer.registerObserversIfNeeded();
+            onDisplayFeaturesChanged();
         } else {
-            mSettingsDevicePostureProducer.unregisterObserversIfNeeded();
-            mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded();
+            mSettingsFoldingFeatureProducer.unregisterObserversIfNeeded();
+        }
+    }
+
+    private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter {
+        @Override
+        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+            super.onActivityCreated(activity, savedInstanceState);
+            onDisplayFeaturesChangedForActivity(activity);
+        }
+
+        @Override
+        public void onActivityConfigurationChanged(Activity activity) {
+            super.onActivityConfigurationChanged(activity);
+            onDisplayFeaturesChangedForActivity(activity);
+        }
+
+        private void onDisplayFeaturesChangedForActivity(@NonNull Activity activity) {
+            IBinder token = activity.getWindow().getAttributes().token;
+            if (token == null || mWindowLayoutChangeListenerTokens.contains(token)) {
+                onDisplayFeaturesChanged();
+            }
         }
     }
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java
index 199c373..b9c808a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.java
@@ -30,7 +30,7 @@
 abstract class StubSidecar implements SidecarInterface {
 
     private SidecarCallback mSidecarCallback;
-    private final Set<IBinder> mWindowLayoutChangeListenerTokens = new HashSet<>();
+    final Set<IBinder> mWindowLayoutChangeListenerTokens = new HashSet<>();
     private boolean mDeviceStateChangeListenerRegistered;
 
     StubSidecar() {
diff --git a/libs/WindowManager/OWNERS b/libs/WindowManager/OWNERS
index 2c61df9..780e4c1 100644
--- a/libs/WindowManager/OWNERS
+++ b/libs/WindowManager/OWNERS
@@ -1,3 +1,6 @@
 set noparent
 
 include /services/core/java/com/android/server/wm/OWNERS
+
+# Give submodule owners in shell resource approval
+per-file Shell/res*/*/*.xml = hwwang@google.com, lbill@google.com, madym@google.com
diff --git a/packages/SystemUI/res/layout/communal_host_view.xml b/libs/WindowManager/Shell/res/color/letterbox_education_dismiss_button_background_ripple.xml
similarity index 62%
copy from packages/SystemUI/res/layout/communal_host_view.xml
copy to libs/WindowManager/Shell/res/color/letterbox_education_dismiss_button_background_ripple.xml
index cd9c260..43cba1a 100644
--- a/packages/SystemUI/res/layout/communal_host_view.xml
+++ b/libs/WindowManager/Shell/res/color/letterbox_education_dismiss_button_background_ripple.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2021 The Android Open Source Project
+  ~ 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.
@@ -14,10 +14,6 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-
-<!-- This is a view that shows general status information in Keyguard. -->
-<com.android.systemui.communal.CommunalHostView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/communal_host"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"/>
\ No newline at end of file
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@android:color/system_neutral1_900" android:alpha="0.6" />
+</selector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
index 0d8a8fa..42572d6 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
@@ -15,6 +15,6 @@
   ~ limitations under the License.
   -->
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-        android:color="@android:color/system_accent1_10">
+        android:color="@color/letterbox_education_dismiss_button_background_ripple">
     <item android:drawable="@drawable/letterbox_education_dismiss_button_background"/>
 </ripple>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values-land/styles.xml b/libs/WindowManager/Shell/res/values-land/styles.xml
index 0ed9368..e89f65b 100644
--- a/libs/WindowManager/Shell/res/values-land/styles.xml
+++ b/libs/WindowManager/Shell/res/values-land/styles.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <style name="DockedDividerBackground">
-        <item name="android:layout_width">10dp</item>
+        <item name="android:layout_width">@dimen/split_divider_bar_width</item>
         <item name="android:layout_height">match_parent</item>
         <item name="android:layout_gravity">center_horizontal</item>
         <item name="android:background">@color/split_divider_background</item>
diff --git a/libs/WindowManager/Shell/res/values-television/config.xml b/libs/WindowManager/Shell/res/values-television/config.xml
index 552048e..dcb4c10 100644
--- a/libs/WindowManager/Shell/res/values-television/config.xml
+++ b/libs/WindowManager/Shell/res/values-television/config.xml
@@ -33,4 +33,10 @@
     <!-- The default gravity for the picture-in-picture window.
          Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT -->
     <integer name="config_defaultPictureInPictureGravity">0x55</integer>
+
+    <!-- Fraction of screen width/height restricted keep clear areas can move the PiP. -->
+    <fraction name="config_pipMaxRestrictedMoveDistance">15%</fraction>
+
+    <!-- Duration (in milliseconds) the PiP stays stashed before automatically unstashing. -->
+    <integer name="config_pipStashDuration">5000</integer>
 </resources>
diff --git a/packages/SystemUI/res/layout/communal_host_view.xml b/libs/WindowManager/Shell/res/values-television/dimen.xml
similarity index 60%
copy from packages/SystemUI/res/layout/communal_host_view.xml
copy to libs/WindowManager/Shell/res/values-television/dimen.xml
index cd9c260..14e89f8 100644
--- a/packages/SystemUI/res/layout/communal_host_view.xml
+++ b/libs/WindowManager/Shell/res/values-television/dimen.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2021 The Android Open Source Project
+  ~ 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.
@@ -15,9 +15,10 @@
   ~ limitations under the License.
   -->
 
-<!-- This is a view that shows general status information in Keyguard. -->
-<com.android.systemui.communal.CommunalHostView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/communal_host"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"/>
\ No newline at end of file
+<!-- These resources are around just to allow their values to be customized
+     for TV products.  Do not translate. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Padding between PIP and keep clear areas that caused it to move. -->
+    <dimen name="pip_keep_clear_area_padding">16dp</dimen>
+</resources>
diff --git a/libs/WindowManager/Shell/res/values/strings_tv.xml b/libs/WindowManager/Shell/res/values/strings_tv.xml
index c7b8a13..09ed9b8 100644
--- a/libs/WindowManager/Shell/res/values/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values/strings_tv.xml
@@ -39,5 +39,10 @@
 
     <!-- Button to collapse/shrink the picture-in-picture (PIP) window [CHAR LIMIT=30] -->
     <string name="pip_collapse">Collapse PIP</string>
+
+    <!-- Educative text instructing the user to double press the HOME button to access the pip
+        controls menu [CHAR LIMIT=50] -->
+    <string name="pip_edu_text"> Double press <annotation icon="home_icon"> HOME </annotation> for
+        controls </string>
 </resources>
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java
index 908a31d..8483f07 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java
@@ -21,6 +21,7 @@
 import com.android.wm.shell.apppairs.AppPairsController;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
+import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
 import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
 import com.android.wm.shell.onehanded.OneHandedController;
 import com.android.wm.shell.pip.Pip;
@@ -46,11 +47,13 @@
     private final Optional<AppPairsController> mAppPairsOptional;
     private final Optional<RecentTasksController> mRecentTasks;
     private final ShellTaskOrganizer mShellTaskOrganizer;
+    private final KidsModeTaskOrganizer mKidsModeTaskOrganizer;
     private final ShellExecutor mMainExecutor;
     private final HandlerImpl mImpl = new HandlerImpl();
 
     public ShellCommandHandlerImpl(
             ShellTaskOrganizer shellTaskOrganizer,
+            KidsModeTaskOrganizer kidsModeTaskOrganizer,
             Optional<LegacySplitScreenController> legacySplitScreenOptional,
             Optional<SplitScreenController> splitScreenOptional,
             Optional<Pip> pipOptional,
@@ -60,6 +63,7 @@
             Optional<RecentTasksController> recentTasks,
             ShellExecutor mainExecutor) {
         mShellTaskOrganizer = shellTaskOrganizer;
+        mKidsModeTaskOrganizer = kidsModeTaskOrganizer;
         mRecentTasks = recentTasks;
         mLegacySplitScreenOptional = legacySplitScreenOptional;
         mSplitScreenOptional = splitScreenOptional;
@@ -92,6 +96,9 @@
         pw.println();
         pw.println();
         mRecentTasks.ifPresent(recentTasks -> recentTasks.dump(pw, ""));
+        pw.println();
+        pw.println();
+        mKidsModeTaskOrganizer.dump(pw, "");
     }
 
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
index c3ce362..b729fe1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
@@ -29,6 +29,7 @@
 import com.android.wm.shell.freeform.FreeformTaskListener;
 import com.android.wm.shell.fullscreen.FullscreenTaskListener;
 import com.android.wm.shell.fullscreen.FullscreenUnfoldController;
+import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
 import com.android.wm.shell.pip.phone.PipTouchHandler;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -48,6 +49,7 @@
     private final DisplayInsetsController mDisplayInsetsController;
     private final DragAndDropController mDragAndDropController;
     private final ShellTaskOrganizer mShellTaskOrganizer;
+    private final KidsModeTaskOrganizer mKidsModeTaskOrganizer;
     private final Optional<BubbleController> mBubblesOptional;
     private final Optional<SplitScreenController> mSplitScreenOptional;
     private final Optional<AppPairsController> mAppPairsOptional;
@@ -68,6 +70,7 @@
             DisplayInsetsController displayInsetsController,
             DragAndDropController dragAndDropController,
             ShellTaskOrganizer shellTaskOrganizer,
+            KidsModeTaskOrganizer kidsModeTaskOrganizer,
             Optional<BubbleController> bubblesOptional,
             Optional<SplitScreenController> splitScreenOptional,
             Optional<AppPairsController> appPairsOptional,
@@ -84,6 +87,7 @@
         mDisplayInsetsController = displayInsetsController;
         mDragAndDropController = dragAndDropController;
         mShellTaskOrganizer = shellTaskOrganizer;
+        mKidsModeTaskOrganizer = kidsModeTaskOrganizer;
         mBubblesOptional = bubblesOptional;
         mSplitScreenOptional = splitScreenOptional;
         mAppPairsOptional = appPairsOptional;
@@ -136,6 +140,9 @@
 
         mFullscreenUnfoldController.ifPresent(FullscreenUnfoldController::init);
         mRecentTasks.ifPresent(RecentTasksController::init);
+
+        // Initialize kids mode task organizer
+        mKidsModeTaskOrganizer.initialize(mStartingWindow);
     }
 
     @ExternalThread
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 91ea436..8442994 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -98,16 +98,22 @@
         default void onTaskInfoChanged(RunningTaskInfo taskInfo) {}
         default void onTaskVanished(RunningTaskInfo taskInfo) {}
         default void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {}
-        /** Whether this task listener supports  compat UI. */
+        /** Whether this task listener supports compat UI. */
         default boolean supportCompatUI() {
             // All TaskListeners should support compat UI except PIP.
             return true;
         }
-        /** Attaches the a child window surface to the task surface. */
+        /** Attaches a child window surface to the task surface. */
         default void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
             throw new IllegalStateException(
                     "This task listener doesn't support child surface attachment.");
         }
+        /** Reparents a child window surface to the task surface. */
+        default void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+                SurfaceControl.Transaction t) {
+            throw new IllegalStateException(
+                    "This task listener doesn't support child surface reparent.");
+        }
         default void dump(@NonNull PrintWriter pw, String prefix) {};
     }
 
@@ -190,8 +196,8 @@
     }
 
     @VisibleForTesting
-    ShellTaskOrganizer(ITaskOrganizerController taskOrganizerController, ShellExecutor mainExecutor,
-            Context context, @Nullable CompatUIController compatUI,
+    protected ShellTaskOrganizer(ITaskOrganizerController taskOrganizerController,
+            ShellExecutor mainExecutor, Context context, @Nullable CompatUIController compatUI,
             Optional<RecentTasksController> recentTasks) {
         super(taskOrganizerController, mainExecutor);
         mCompatUI = compatUI;
@@ -620,6 +626,23 @@
         updateCameraCompatControlState(info.getTaskInfo().token, state);
     }
 
+    /** Reparents a child window surface to the task surface. */
+    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+            SurfaceControl.Transaction t) {
+        final TaskListener taskListener;
+        synchronized (mLock) {
+            taskListener = mTasks.contains(taskId)
+                    ? getTaskListener(mTasks.get(taskId).getTaskInfo())
+                    : null;
+        }
+        if (taskListener == null) {
+            ProtoLog.w(WM_SHELL_TASK_ORG, "Failed to find Task to reparent surface taskId=%d",
+                    taskId);
+            return;
+        }
+        taskListener.reparentChildSurfaceToTask(taskId, sc, t);
+    }
+
     private void logSizeCompatRestartButtonEventReported(@NonNull TaskAppearedInfo info,
             int event) {
         ActivityInfo topActivityInfo = info.getTaskInfo().topActivityInfo;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
index 54e743f..ca4ef07 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
@@ -367,10 +367,20 @@
 
     @Override
     public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
-        if (mTaskInfo.taskId != taskId) {
+        b.setParent(findTaskSurface(taskId));
+    }
+
+    @Override
+    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+            SurfaceControl.Transaction t) {
+        t.reparent(sc, findTaskSurface(taskId));
+    }
+
+    private SurfaceControl findTaskSurface(int taskId) {
+        if (mTaskInfo == null || mTaskLeash == null || mTaskInfo.taskId != taskId) {
             throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
         }
-        b.setParent(mTaskLeash);
+        return mTaskLeash;
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
index e344c3b..33eec33 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
@@ -275,12 +275,22 @@
 
     @Override
     public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+        b.setParent(findTaskSurface(taskId));
+    }
+
+    @Override
+    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+            SurfaceControl.Transaction t) {
+        t.reparent(sc, findTaskSurface(taskId));
+    }
+
+    private SurfaceControl findTaskSurface(int taskId) {
         if (getRootTaskId() == taskId) {
-            b.setParent(mRootTaskLeash);
+            return mRootTaskLeash;
         } else if (getTaskId1() == taskId) {
-            b.setParent(mTaskLeash1);
+            return mTaskLeash1;
         } else if (getTaskId2() == taskId) {
-            b.setParent(mTaskLeash2);
+            return mTaskLeash2;
         } else {
             throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
         }
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 8d5fdfb..08cb252 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
@@ -52,14 +52,17 @@
  */
 public class BackAnimationController implements RemoteCallable<BackAnimationController> {
 
-    private static final String BACK_PREDICTABILITY_PROP = "persist.debug.back_predictability";
-    public static final boolean IS_ENABLED = SystemProperties
-            .getInt(BACK_PREDICTABILITY_PROP, 0) > 0;
     private static final String BACK_PREDICTABILITY_PROGRESS_THRESHOLD_PROP =
             "persist.debug.back_predictability_progress_threshold";
+    // By default, enable new back dispatching without any animations.
+    private static final int BACK_PREDICTABILITY_PROP =
+            SystemProperties.getInt("persist.debug.back_predictability", 1);
+    public static final boolean IS_ENABLED = BACK_PREDICTABILITY_PROP > 0;
     private static final int PROGRESS_THRESHOLD = SystemProperties
             .getInt(BACK_PREDICTABILITY_PROGRESS_THRESHOLD_PROP, -1);
     private static final String TAG = "BackAnimationController";
+    @VisibleForTesting
+    boolean mEnableAnimations = (BACK_PREDICTABILITY_PROP & (1 << 1)) != 0;
 
     /**
      * Location of the initial touch event of the back gesture.
@@ -255,7 +258,7 @@
                         backNavigationInfo.getTaskWindowConfiguration());
             }
             mTransaction.apply();
-        } else if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME) {
+        } else if (shouldDispatchToLauncher(backType)) {
             targetCallback = mBackToLauncherCallback;
         } else if (backType == BackNavigationInfo.TYPE_CALLBACK) {
             targetCallback = mBackNavigationInfo.getOnBackInvokedCallback();
@@ -309,7 +312,7 @@
 
         BackEvent backEvent = new BackEvent(0, 0, progress, swipeEdge, animationTarget);
         IOnBackInvokedCallback targetCallback = null;
-        if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME) {
+        if (shouldDispatchToLauncher(backType)) {
             targetCallback = mBackToLauncherCallback;
         } else if (backType == BackNavigationInfo.TYPE_CROSS_TASK
                 || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) {
@@ -330,8 +333,7 @@
             return;
         }
         int backType = mBackNavigationInfo.getType();
-        boolean shouldDispatchToLauncher = backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
-                && mBackToLauncherCallback != null;
+        boolean shouldDispatchToLauncher = shouldDispatchToLauncher(backType);
         IOnBackInvokedCallback targetCallback = shouldDispatchToLauncher
                 ? mBackToLauncherCallback
                 : mBackNavigationInfo.getOnBackInvokedCallback();
@@ -356,6 +358,17 @@
         }
     }
 
+    private boolean shouldDispatchToLauncher(int backType) {
+        return backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
+                && mBackToLauncherCallback != null
+                && mEnableAnimations;
+    }
+
+    @VisibleForTesting
+    void setEnableAnimations(boolean shouldEnable) {
+        mEnableAnimations = shouldEnable;
+    }
+
     private static void dispatchOnBackStarted(IOnBackInvokedCallback callback) {
         if (callback == null) {
             return;
@@ -468,7 +481,7 @@
             return;
         }
         RemoteAnimationTarget animationTarget = backNavigationInfo.getDepartingAnimationTarget();
-        if (animationTarget != null && mTriggerBack) {
+        if (animationTarget != null) {
             if (animationTarget.leash != null && animationTarget.leash.isValid()) {
                 mTransaction.remove(animationTarget.leash);
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
index 79e6242..3876533 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
@@ -173,8 +173,8 @@
     }
 
     @Override
-    public void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
+    public void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
 
         if (!shouldDrawDot()) {
             return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index d0138a4..d2a1c55 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -383,23 +383,15 @@
         mTaskStackListener.addListener(new TaskStackListenerCallback() {
             @Override
             public void onTaskMovedToFront(int taskId) {
-                if (mSysuiProxy == null) {
-                    return;
-                }
-
-                mSysuiProxy.isNotificationShadeExpand((expand) -> {
-                    mMainExecutor.execute(() -> {
-                        int expandedId = INVALID_TASK_ID;
-                        if (mStackView != null && mStackView.getExpandedBubble() != null
-                                && isStackExpanded() && !mStackView.isExpansionAnimating()
-                                && !expand) {
-                            expandedId = mStackView.getExpandedBubble().getTaskId();
-                        }
-
-                        if (expandedId != INVALID_TASK_ID && expandedId != taskId) {
-                            mBubbleData.setExpanded(false);
-                        }
-                    });
+                mMainExecutor.execute(() -> {
+                    int expandedId = INVALID_TASK_ID;
+                    if (mStackView != null && mStackView.getExpandedBubble() != null
+                            && isStackExpanded() && !mStackView.isExpansionAnimating()) {
+                        expandedId = mStackView.getExpandedBubble().getTaskId();
+                    }
+                    if (expandedId != INVALID_TASK_ID && expandedId != taskId) {
+                        mBubbleData.setExpanded(false);
+                    }
                 });
             }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
index d22fb50..4ba32e9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
@@ -110,6 +110,14 @@
     }
 
     /**
+     *  Get the InsetsState of a display.
+     */
+    public InsetsState getInsetsState(int displayId) {
+        final DisplayRecord r = mDisplays.get(displayId);
+        return r != null ? r.mInsetsState : null;
+    }
+
+    /**
      * Updates the insets for a given display.
      */
     public void updateDisplayInsets(int displayId, InsetsState state) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
index 51067a4..4583389 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
@@ -344,7 +344,7 @@
         @Override
         public void resized(ClientWindowFrames frames, boolean reportDraw,
                 MergedConfiguration newMergedConfiguration, boolean forceLayout,
-                boolean alwaysConsumeSystemBars, int displayId) {}
+                boolean alwaysConsumeSystemBars, int displayId, int syncSeqId) {}
 
         @Override
         public void insetsChanged(InsetsState insetsState, boolean willMove, boolean willResize) {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index b52c8d1..5246117 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -98,6 +98,7 @@
     private WindowContainerToken mWinToken2;
     private int mDividePosition;
     private boolean mInitialized = false;
+    private boolean mFreezeDividerWindow = false;
     private int mOrientation;
     private int mRotation;
 
@@ -225,11 +226,6 @@
         mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, null);
         initDividerPosition(mTempRect);
 
-        if (mInitialized) {
-            release();
-            init();
-        }
-
         return true;
     }
 
@@ -298,20 +294,37 @@
     }
 
     /** Releases the surface holding the current {@link DividerView}. */
-    public void release() {
+    public void release(SurfaceControl.Transaction t) {
         if (!mInitialized) return;
         mInitialized = false;
-        mSplitWindowManager.release();
+        mSplitWindowManager.release(t);
         mDisplayImeController.removePositionProcessor(mImePositionProcessor);
         mImePositionProcessor.reset();
     }
 
+    public void release() {
+        release(null /* t */);
+    }
+
+    /** Releases and re-inflates {@link DividerView} on the root surface. */
+    public void update(SurfaceControl.Transaction t) {
+        if (!mInitialized) return;
+        mSplitWindowManager.release(t);
+        mImePositionProcessor.reset();
+        mSplitWindowManager.init(this, mInsetsState);
+    }
+
     @Override
     public void insetsChanged(InsetsState insetsState) {
         mInsetsState.set(insetsState);
         if (!mInitialized) {
             return;
         }
+        if (mFreezeDividerWindow) {
+            // DO NOT change its layout before transition actually run because it might cause
+            // flicker.
+            return;
+        }
         mSplitWindowManager.onInsetsChanged(insetsState);
     }
 
@@ -323,6 +336,10 @@
         }
     }
 
+    public void setFreezeDividerWindow(boolean freezeDividerWindow) {
+        mFreezeDividerWindow = freezeDividerWindow;
+    }
+
     /**
      * Updates bounds with the passing position. Usually used to update recording bounds while
      * performing animation or dragging divider bar to resize the splits.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
index 4903f9d..833d9d5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
@@ -58,6 +58,9 @@
     private SurfaceControl mLeash;
     private DividerView mDividerView;
 
+    // Used to "pass" a transaction to WWM.remove so that view removal can be synchronized.
+    private SurfaceControl.Transaction mSyncTransaction = null;
+
     public interface ParentContainerCallbacks {
         void attachToParentSurface(SurfaceControl.Builder b);
         void onLeashReady(SurfaceControl leash);
@@ -130,22 +133,38 @@
      * Releases the surface control of the current {@link DividerView} and tear down the view
      * hierarchy.
      */
-    void release() {
+    void release(@Nullable SurfaceControl.Transaction t) {
         if (mDividerView != null) {
             mDividerView = null;
         }
 
         if (mViewHost != null){
+            mSyncTransaction = t;
             mViewHost.release();
+            mSyncTransaction = null;
             mViewHost = null;
         }
 
         if (mLeash != null) {
-            new SurfaceControl.Transaction().remove(mLeash).apply();
+            if (t == null) {
+                new SurfaceControl.Transaction().remove(mLeash).apply();
+            } else {
+                t.remove(mLeash);
+            }
             mLeash = null;
         }
     }
 
+    @Override
+    protected void removeSurface(SurfaceControl sc) {
+        // This gets called via SurfaceControlViewHost.release()
+        if (mSyncTransaction != null) {
+            mSyncTransaction.remove(sc);
+        } else {
+            super.removeSurface(sc);
+        }
+    }
+
     void setInteractive(boolean interactive) {
         if (mDividerView == null) return;
         mDividerView.setInteractive(interactive);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java
index 99dbfe0..b87cf47 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java
@@ -24,9 +24,12 @@
 @ExternalThread
 public interface CompatUI {
     /**
-     * Called when the keyguard occluded state changes. Removes all compat UIs if the
-     * keyguard is now occluded.
-     * @param occluded indicates if the keyguard is now occluded.
+     * Called when the keyguard showing state changes. Removes all compat UIs if the
+     * keyguard is now showing.
+     *
+     * <p>Note that if the keyguard is occluded it will also be considered showing.
+     *
+     * @param showing indicates if the keyguard is now showing.
      */
-    void onKeyguardOccludedChanged(boolean occluded);
+    void onKeyguardShowingChanged(boolean showing);
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index ee4d5ed..b2bbafe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -109,9 +109,9 @@
     // Only show each hint once automatically in the process life.
     private final CompatUIHintsState mCompatUIHintsState;
 
-    // Indicates if the keyguard is currently occluded, in which case compat UIs shouldn't
+    // Indicates if the keyguard is currently showing, in which case compat UIs shouldn't
     // be shown.
-    private boolean mKeyguardOccluded;
+    private boolean mKeyguardShowing;
 
     public CompatUIController(Context context,
             DisplayController displayController,
@@ -218,14 +218,14 @@
     }
 
     @VisibleForTesting
-    void onKeyguardOccludedChanged(boolean occluded) {
-        mKeyguardOccluded = occluded;
-        // Hide the compat UIs when keyguard is occluded.
+    void onKeyguardShowingChanged(boolean showing) {
+        mKeyguardShowing = showing;
+        // Hide the compat UIs when keyguard is showing.
         forAllLayouts(layout -> layout.updateVisibility(showOnDisplay(layout.getDisplayId())));
     }
 
     private boolean showOnDisplay(int displayId) {
-        return !mKeyguardOccluded && !isImeShowingOnDisplay(displayId);
+        return !mKeyguardShowing && !isImeShowingOnDisplay(displayId);
     }
 
     private boolean isImeShowingOnDisplay(int displayId) {
@@ -372,9 +372,9 @@
     @ExternalThread
     private class CompatUIImpl implements CompatUI {
         @Override
-        public void onKeyguardOccludedChanged(boolean occluded) {
+        public void onKeyguardShowingChanged(boolean showing) {
             mMainExecutor.execute(() -> {
-                CompatUIController.this.onKeyguardOccludedChanged(occluded);
+                CompatUIController.this.onKeyguardShowingChanged(showing);
             });
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
index 2da6a6b..8aa4d0e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
@@ -21,6 +21,7 @@
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.View;
+import android.widget.TextView;
 
 import androidx.constraintlayout.widget.ConstraintLayout;
 
@@ -38,6 +39,7 @@
     // 204 is simply 255 * 0.8.
     static final int BACKGROUND_DIM_ALPHA = 204;
     private View mDialogContainer;
+    private TextView mDialogTitle;
     private Drawable mBackgroundDim;
 
     public LetterboxEduDialogLayout(Context context) {
@@ -61,6 +63,10 @@
         return mDialogContainer;
     }
 
+    TextView getDialogTitle() {
+        return mDialogTitle;
+    }
+
     Drawable getBackgroundDim() {
         return mBackgroundDim;
     }
@@ -84,6 +90,7 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mDialogContainer = findViewById(R.id.letterbox_education_dialog_container);
+        mDialogTitle = findViewById(R.id.letterbox_education_dialog_title);
         mBackgroundDim = getBackground().mutate();
         // Set the alpha of the background dim to 0 for enter animation.
         mBackgroundDim.setAlpha(0);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
index 30b9f08..dda72ff 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
@@ -28,6 +28,7 @@
 import android.view.View;
 import android.view.ViewGroup.MarginLayoutParams;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.wm.shell.R;
@@ -132,7 +133,7 @@
         updateDialogMargins();
 
         mAnimationController.startEnterAnimation(mLayout, /* endCallback= */
-                this::setDismissOnClickListener);
+                this::onDialogEnterAnimationEnded);
 
         return mLayout;
     }
@@ -157,11 +158,13 @@
                 R.layout.letterbox_education_dialog_layout, null);
     }
 
-    private void setDismissOnClickListener() {
+    private void onDialogEnterAnimationEnded() {
         if (mLayout == null) {
             return;
         }
         mLayout.setDismissOnClickListener(this::onDismiss);
+        // Focus on the dialog title for accessibility.
+        mLayout.getDialogTitle().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
     }
 
     private void onDismiss() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
index 491dff0..1dd5ebc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
@@ -27,7 +27,6 @@
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.common.annotations.ShellMainThread;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.pip.PipAnimationController;
 import com.android.wm.shell.pip.PipMediaController;
@@ -70,7 +69,8 @@
             TaskStackListenerImpl taskStackListener,
             DisplayController displayController,
             WindowManagerShellWrapper windowManagerShellWrapper,
-            @ShellMainThread ShellExecutor mainExecutor) {
+            @ShellMainThread ShellExecutor mainExecutor,
+            @ShellMainThread Handler mainHandler) {
         return Optional.of(
                 TvPipController.create(
                         context,
@@ -84,7 +84,8 @@
                         taskStackListener,
                         displayController,
                         windowManagerShellWrapper,
-                        mainExecutor));
+                        mainExecutor,
+                        mainHandler));
     }
 
     @WMSingleton
@@ -163,15 +164,14 @@
             PipAnimationController pipAnimationController,
             PipTransitionController pipTransitionController,
             PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
-            Optional<LegacySplitScreenController> splitScreenOptional,
-            Optional<SplitScreenController> newSplitScreenOptional,
+            Optional<SplitScreenController> splitScreenControllerOptional,
             DisplayController displayController,
             PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
             @ShellMainThread ShellExecutor mainExecutor) {
         return new PipTaskOrganizer(context,
                 syncTransactionQueue, pipTransitionState, tvPipBoundsState, tvPipBoundsAlgorithm,
                 tvPipMenuController, pipAnimationController, pipSurfaceTransactionHelper,
-                pipTransitionController, splitScreenOptional, newSplitScreenOptional,
+                pipTransitionController, splitScreenControllerOptional,
                 displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor);
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 0362b3f..bf0337d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -68,6 +68,7 @@
 import com.android.wm.shell.fullscreen.FullscreenUnfoldController;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
+import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
 import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
 import com.android.wm.shell.onehanded.OneHanded;
@@ -184,7 +185,23 @@
 
     @WMSingleton
     @Provides
-    static Optional<CompatUI> provideCompatUI(CompatUIController compatUIController) {
+    static KidsModeTaskOrganizer provideKidsModeTaskOrganizer(
+            @ShellMainThread ShellExecutor mainExecutor,
+            @ShellMainThread Handler mainHandler,
+            Context context,
+            CompatUIController compatUI,
+            SyncTransactionQueue syncTransactionQueue,
+            DisplayController displayController,
+            DisplayInsetsController displayInsetsController,
+            Optional<RecentTasksController> recentTasksOptional
+    ) {
+        return new KidsModeTaskOrganizer(mainExecutor, mainHandler, context, compatUI,
+                syncTransactionQueue, displayController, displayInsetsController,
+                recentTasksOptional);
+    }
+
+    @WMSingleton
+    @Provides static Optional<CompatUI> provideCompatUI(CompatUIController compatUIController) {
         return Optional.of(compatUIController.asCompatUI());
     }
 
@@ -637,6 +654,7 @@
             DisplayInsetsController displayInsetsController,
             DragAndDropController dragAndDropController,
             ShellTaskOrganizer shellTaskOrganizer,
+            KidsModeTaskOrganizer kidsModeTaskOrganizer,
             Optional<BubbleController> bubblesOptional,
             Optional<SplitScreenController> splitScreenOptional,
             Optional<AppPairsController> appPairsOptional,
@@ -653,6 +671,7 @@
                 displayInsetsController,
                 dragAndDropController,
                 shellTaskOrganizer,
+                kidsModeTaskOrganizer,
                 bubblesOptional,
                 splitScreenOptional,
                 appPairsOptional,
@@ -680,6 +699,7 @@
     @Provides
     static ShellCommandHandlerImpl provideShellCommandHandlerImpl(
             ShellTaskOrganizer shellTaskOrganizer,
+            KidsModeTaskOrganizer kidsModeTaskOrganizer,
             Optional<LegacySplitScreenController> legacySplitScreenOptional,
             Optional<SplitScreenController> splitScreenOptional,
             Optional<Pip> pipOptional,
@@ -688,7 +708,7 @@
             Optional<AppPairsController> appPairsOptional,
             Optional<RecentTasksController> recentTasksOptional,
             @ShellMainThread ShellExecutor mainExecutor) {
-        return new ShellCommandHandlerImpl(shellTaskOrganizer,
+        return new ShellCommandHandlerImpl(shellTaskOrganizer, kidsModeTaskOrganizer,
                 legacySplitScreenOptional, splitScreenOptional, pipOptional, oneHandedOptional,
                 hideDisplayCutout, appPairsOptional, recentTasksOptional, mainExecutor);
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 7879e7a..73f3931 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -285,15 +285,14 @@
             PipAnimationController pipAnimationController,
             PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
             PipTransitionController pipTransitionController,
-            Optional<LegacySplitScreenController> splitScreenOptional,
-            Optional<SplitScreenController> newSplitScreenOptional,
+            Optional<SplitScreenController> splitScreenControllerOptional,
             DisplayController displayController,
             PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
             @ShellMainThread ShellExecutor mainExecutor) {
         return new PipTaskOrganizer(context,
                 syncTransactionQueue, pipTransitionState, pipBoundsState, pipBoundsAlgorithm,
                 menuPhoneController, pipAnimationController, pipSurfaceTransactionHelper,
-                pipTransitionController, splitScreenOptional, newSplitScreenOptional,
+                pipTransitionController, splitScreenControllerOptional,
                 displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index 52ff21b..fef9be3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -110,6 +110,24 @@
     }
 
     @Override
+    public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+        b.setParent(findTaskSurface(taskId));
+    }
+
+    @Override
+    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+            SurfaceControl.Transaction t) {
+        t.reparent(sc, findTaskSurface(taskId));
+    }
+
+    private SurfaceControl findTaskSurface(int taskId) {
+        if (!mTasks.contains(taskId)) {
+            throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
+        }
+        return mTasks.get(taskId).mLeash;
+    }
+
+    @Override
     public void dump(PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         pw.println(prefix + this);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 6e38e42..73e6cba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -133,10 +133,20 @@
 
     @Override
     public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+        b.setParent(findTaskSurface(taskId));
+    }
+
+    @Override
+    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+            SurfaceControl.Transaction t) {
+        t.reparent(sc, findTaskSurface(taskId));
+    }
+
+    private SurfaceControl findTaskSurface(int taskId) {
         if (!mDataByTaskId.contains(taskId)) {
             throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
         }
-        b.setParent(mDataByTaskId.get(taskId).surface);
+        return mDataByTaskId.get(taskId).surface;
     }
 
     @Override
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
new file mode 100644
index 0000000..429eb99
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
@@ -0,0 +1,341 @@
+/*
+ * 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.wm.shell.kidsmode;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.view.InsetsSource;
+import android.view.InsetsState;
+import android.view.SurfaceControl;
+import android.window.ITaskOrganizerController;
+import android.window.TaskAppearedInfo;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.policy.ForceShowNavigationBarSettingsObserver;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayInsetsController;
+import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.compatui.CompatUIController;
+import com.android.wm.shell.recents.RecentTasksController;
+import com.android.wm.shell.startingsurface.StartingWindowController;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * A dedicated task organizer when kids mode is enabled.
+ *  - Creates a root task with bounds that exclude the navigation bar area
+ *  - Launch all task into the root task except for Launcher
+ */
+public class KidsModeTaskOrganizer extends ShellTaskOrganizer {
+    private static final String TAG = "KidsModeTaskOrganizer";
+
+    private static final int[] CONTROLLED_ACTIVITY_TYPES =
+            {ACTIVITY_TYPE_UNDEFINED, ACTIVITY_TYPE_STANDARD};
+    private static final int[] CONTROLLED_WINDOWING_MODES =
+            {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED};
+
+    private final Handler mMainHandler;
+    private final Context mContext;
+    private final SyncTransactionQueue mSyncQueue;
+    private final DisplayController mDisplayController;
+    private final DisplayInsetsController mDisplayInsetsController;
+
+    @VisibleForTesting
+    ActivityManager.RunningTaskInfo mLaunchRootTask;
+    @VisibleForTesting
+    SurfaceControl mLaunchRootLeash;
+    @VisibleForTesting
+    final IBinder mCookie = new Binder();
+
+    private final InsetsState mInsetsState = new InsetsState();
+    private int mDisplayWidth;
+    private int mDisplayHeight;
+
+    private ForceShowNavigationBarSettingsObserver mForceShowNavigationBarSettingsObserver;
+    private boolean mEnabled;
+
+    DisplayController.OnDisplaysChangedListener mOnDisplaysChangedListener =
+            new DisplayController.OnDisplaysChangedListener() {
+        @Override
+        public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
+            if (displayId != DEFAULT_DISPLAY) {
+                return;
+            }
+            final DisplayLayout displayLayout =
+                    mDisplayController.getDisplayLayout(DEFAULT_DISPLAY);
+            if (displayLayout == null) {
+                return;
+            }
+            final int displayWidth = displayLayout.width();
+            final int displayHeight = displayLayout.height();
+            if (displayWidth == mDisplayWidth || displayHeight == mDisplayHeight) {
+                return;
+            }
+            mDisplayWidth = displayWidth;
+            mDisplayHeight = displayHeight;
+            updateBounds();
+        }
+    };
+
+    DisplayInsetsController.OnInsetsChangedListener mOnInsetsChangedListener =
+            new DisplayInsetsController.OnInsetsChangedListener() {
+        @Override
+        public void insetsChanged(InsetsState insetsState) {
+            // Update bounds only when the insets of navigation bar or task bar is changed.
+            if (Objects.equals(insetsState.peekSource(InsetsState.ITYPE_NAVIGATION_BAR),
+                    mInsetsState.peekSource(InsetsState.ITYPE_NAVIGATION_BAR))
+                    && Objects.equals(insetsState.peekSource(
+                            InsetsState.ITYPE_EXTRA_NAVIGATION_BAR),
+                    mInsetsState.peekSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR))) {
+                return;
+            }
+            mInsetsState.set(insetsState);
+            updateBounds();
+        }
+    };
+
+    @VisibleForTesting
+    KidsModeTaskOrganizer(
+            ITaskOrganizerController taskOrganizerController,
+            ShellExecutor mainExecutor,
+            Handler mainHandler,
+            Context context,
+            @Nullable CompatUIController compatUI,
+            SyncTransactionQueue syncTransactionQueue,
+            DisplayController displayController,
+            DisplayInsetsController displayInsetsController,
+            Optional<RecentTasksController> recentTasks,
+            ForceShowNavigationBarSettingsObserver forceShowNavigationBarSettingsObserver) {
+        super(taskOrganizerController, mainExecutor, context, compatUI, recentTasks);
+        mContext = context;
+        mMainHandler = mainHandler;
+        mSyncQueue = syncTransactionQueue;
+        mDisplayController = displayController;
+        mDisplayInsetsController = displayInsetsController;
+        mForceShowNavigationBarSettingsObserver = forceShowNavigationBarSettingsObserver;
+    }
+
+    public KidsModeTaskOrganizer(
+            ShellExecutor mainExecutor,
+            Handler mainHandler,
+            Context context,
+            @Nullable CompatUIController compatUI,
+            SyncTransactionQueue syncTransactionQueue,
+            DisplayController displayController,
+            DisplayInsetsController displayInsetsController,
+            Optional<RecentTasksController> recentTasks) {
+        super(mainExecutor, context, compatUI, recentTasks);
+        mContext = context;
+        mMainHandler = mainHandler;
+        mSyncQueue = syncTransactionQueue;
+        mDisplayController = displayController;
+        mDisplayInsetsController = displayInsetsController;
+    }
+
+    /**
+     * Initializes kids mode status.
+     */
+    public void initialize(StartingWindowController startingWindowController) {
+        initStartingWindow(startingWindowController);
+        if (mForceShowNavigationBarSettingsObserver == null) {
+            mForceShowNavigationBarSettingsObserver = new ForceShowNavigationBarSettingsObserver(
+                    mMainHandler, mContext);
+        }
+        mForceShowNavigationBarSettingsObserver.setOnChangeRunnable(() -> updateKidsModeState());
+        updateKidsModeState();
+        mForceShowNavigationBarSettingsObserver.register();
+    }
+
+    @Override
+    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
+        if (mEnabled && mLaunchRootTask == null && taskInfo.launchCookies != null
+                && taskInfo.launchCookies.contains(mCookie)) {
+            mLaunchRootTask = taskInfo;
+            mLaunchRootLeash = leash;
+            updateTask();
+        }
+        super.onTaskAppeared(taskInfo, leash);
+
+        mSyncQueue.runInSync(t -> {
+            // Reset several properties back to fullscreen (PiP, for example, leaves all these
+            // properties in a bad state).
+            t.setCrop(leash, null);
+            t.setPosition(leash, 0, 0);
+            t.setAlpha(leash, 1f);
+            t.setMatrix(leash, 1, 0, 0, 1);
+            t.show(leash);
+        });
+    }
+
+    @Override
+    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+        if (mLaunchRootTask != null && mLaunchRootTask.taskId == taskInfo.taskId
+                && !taskInfo.equals(mLaunchRootTask)) {
+            mLaunchRootTask = taskInfo;
+        }
+
+        super.onTaskInfoChanged(taskInfo);
+    }
+
+    @VisibleForTesting
+    void updateKidsModeState() {
+        final boolean enabled = mForceShowNavigationBarSettingsObserver.isEnabled();
+        if (mEnabled == enabled) {
+            return;
+        }
+        mEnabled = enabled;
+        if (mEnabled) {
+            enable();
+        } else {
+            disable();
+        }
+    }
+
+    @VisibleForTesting
+    void enable() {
+        final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(DEFAULT_DISPLAY);
+        if (displayLayout != null) {
+            mDisplayWidth = displayLayout.width();
+            mDisplayHeight = displayLayout.height();
+        }
+        mInsetsState.set(mDisplayController.getInsetsState(DEFAULT_DISPLAY));
+        mDisplayInsetsController.addInsetsChangedListener(DEFAULT_DISPLAY,
+                mOnInsetsChangedListener);
+        mDisplayController.addDisplayWindowListener(mOnDisplaysChangedListener);
+        List<TaskAppearedInfo> taskAppearedInfos = registerOrganizer();
+        for (int i = 0; i < taskAppearedInfos.size(); i++) {
+            final TaskAppearedInfo info = taskAppearedInfos.get(i);
+            onTaskAppeared(info.getTaskInfo(), info.getLeash());
+        }
+        createRootTask(DEFAULT_DISPLAY, WINDOWING_MODE_FULLSCREEN, mCookie);
+        updateTask();
+    }
+
+    @VisibleForTesting
+    void disable() {
+        mDisplayInsetsController.removeInsetsChangedListener(DEFAULT_DISPLAY,
+                mOnInsetsChangedListener);
+        mDisplayController.removeDisplayWindowListener(mOnDisplaysChangedListener);
+        updateTask();
+        final WindowContainerToken token = mLaunchRootTask.token;
+        if (token != null) {
+            deleteRootTask(token);
+        }
+        mLaunchRootTask = null;
+        mLaunchRootLeash = null;
+        unregisterOrganizer();
+    }
+
+    private void updateTask() {
+        updateTask(getWindowContainerTransaction());
+    }
+
+    private void updateTask(WindowContainerTransaction wct) {
+        if (mLaunchRootTask == null || mLaunchRootLeash == null) {
+            return;
+        }
+        final Rect taskBounds = calculateBounds();
+        final WindowContainerToken rootToken = mLaunchRootTask.token;
+        wct.setBounds(rootToken, mEnabled ? taskBounds : null);
+        wct.setLaunchRoot(rootToken,
+                mEnabled ? CONTROLLED_WINDOWING_MODES : null,
+                mEnabled ? CONTROLLED_ACTIVITY_TYPES : null);
+        wct.reparentTasks(
+                mEnabled ? null : rootToken /* currentParent */,
+                mEnabled ? rootToken : null /* newParent */,
+                CONTROLLED_WINDOWING_MODES,
+                CONTROLLED_ACTIVITY_TYPES,
+                true /* onTop */);
+        wct.reorder(rootToken, mEnabled /* onTop */);
+        mSyncQueue.queue(wct);
+        final SurfaceControl rootLeash = mLaunchRootLeash;
+        mSyncQueue.runInSync(t -> {
+            t.setPosition(rootLeash, taskBounds.left, taskBounds.top);
+            t.setWindowCrop(rootLeash, taskBounds.width(), taskBounds.height());
+        });
+    }
+
+    private Rect calculateBounds() {
+        final Rect bounds = new Rect(0, 0, mDisplayWidth, mDisplayHeight);
+        final InsetsSource navBarSource = mInsetsState.peekSource(InsetsState.ITYPE_NAVIGATION_BAR);
+        final InsetsSource taskBarSource = mInsetsState.peekSource(
+                InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
+        if (navBarSource != null && !navBarSource.getFrame().isEmpty()) {
+            bounds.inset(navBarSource.calculateInsets(bounds, false /* ignoreVisibility */));
+        } else if (taskBarSource != null && !taskBarSource.getFrame().isEmpty()) {
+            bounds.inset(taskBarSource.calculateInsets(bounds, false /* ignoreVisibility */));
+        } else {
+            bounds.setEmpty();
+        }
+        return bounds;
+    }
+
+    private void updateBounds() {
+        if (mLaunchRootTask == null) {
+            return;
+        }
+        final WindowContainerTransaction wct = getWindowContainerTransaction();
+        final Rect taskBounds = calculateBounds();
+        wct.setBounds(mLaunchRootTask.token, taskBounds);
+        mSyncQueue.queue(wct);
+        final SurfaceControl finalLeash = mLaunchRootLeash;
+        mSyncQueue.runInSync(t -> {
+            t.setPosition(finalLeash, taskBounds.left, taskBounds.top);
+            t.setWindowCrop(finalLeash, taskBounds.width(), taskBounds.height());
+        });
+    }
+
+    @VisibleForTesting
+    WindowContainerTransaction getWindowContainerTransaction() {
+        return new WindowContainerTransaction();
+    }
+
+    @Override
+    public void dump(@NonNull PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + " mEnabled=" + mEnabled);
+        pw.println(innerPrefix + " mLaunchRootTask=" + mLaunchRootTask);
+        pw.println(innerPrefix + " mLaunchRootLeash=" + mLaunchRootLeash);
+        pw.println(innerPrefix + " mDisplayWidth=" + mDisplayWidth);
+        pw.println(innerPrefix + " mDisplayHeight=" + mDisplayHeight);
+        pw.println(innerPrefix + " mInsetsState=" + mInsetsState);
+        super.dump(pw, innerPrefix);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
index 86bf3ff..d2f42c3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
@@ -343,10 +343,20 @@
 
     @Override
     public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+        b.setParent(findTaskSurface(taskId));
+    }
+
+    @Override
+    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+            SurfaceControl.Transaction t) {
+        t.reparent(sc, findTaskSurface(taskId));
+    }
+
+    private SurfaceControl findTaskSurface(int taskId) {
         if (!mLeashByTaskId.contains(taskId)) {
             throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
         }
-        b.setParent(mLeashByTaskId.get(taskId));
+        return mLeashByTaskId.get(taskId);
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
index ddc85f7..e03421d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
@@ -47,12 +47,13 @@
     /**
      * Notifies the swiping Activity to PiP onto home transition is finished
      *
+     * @param taskId the Task id that the Activity and overlay are currently in.
      * @param componentName ComponentName represents the Activity
      * @param destinationBounds the destination bounds the PiP window lands into
      * @param overlay an optional overlay to fade out after entering PiP
      */
-    oneway void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds,
-            in SurfaceControl overlay) = 2;
+    oneway void stopSwipePipToHome(int taskId, in ComponentName componentName,
+            in Rect destinationBounds, in SurfaceControl overlay) = 2;
 
     /**
      * Sets listener to get pinned stack animation callbacks.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
index 797df41..c2d5823 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
@@ -74,7 +74,7 @@
     /**
      * TODO: move the resources to SysUI package.
      */
-    protected void reloadResources(Context context) {
+    private void reloadResources(Context context) {
         final Resources res = context.getResources();
         mDefaultAspectRatio = res.getFloat(
                 R.dimen.config_pictureInPictureDefaultAspectRatio);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
index 210ea54..17d7f5d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
@@ -29,14 +29,15 @@
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.util.ArraySet;
-import android.util.Log;
 import android.util.Size;
 import android.view.Display;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.function.TriConsumer;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -54,11 +55,15 @@
     public static final int STASH_TYPE_NONE = 0;
     public static final int STASH_TYPE_LEFT = 1;
     public static final int STASH_TYPE_RIGHT = 2;
+    public static final int STASH_TYPE_BOTTOM = 3;
+    public static final int STASH_TYPE_TOP = 4;
 
     @IntDef(prefix = { "STASH_TYPE_" }, value =  {
             STASH_TYPE_NONE,
             STASH_TYPE_LEFT,
-            STASH_TYPE_RIGHT
+            STASH_TYPE_RIGHT,
+            STASH_TYPE_BOTTOM,
+            STASH_TYPE_TOP
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface StashType {}
@@ -223,7 +228,8 @@
                     new PictureInPictureUiState(stashedState != STASH_TYPE_NONE /* isStashed */)
             );
         } catch (RemoteException e) {
-            Log.e(TAG, "Unable to set alert PiP state change.");
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Unable to set alert PiP state change.", TAG);
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 1eb9501..c1e7825 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -18,7 +18,6 @@
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.util.RotationUtils.deltaRotation;
 import static android.util.RotationUtils.rotateBounds;
@@ -63,7 +62,6 @@
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.util.Log;
 import android.util.Rational;
 import android.view.Display;
 import android.view.Surface;
@@ -73,6 +71,7 @@
 import android.window.WindowContainerTransaction;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.animation.Interpolators;
@@ -81,8 +80,8 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.annotations.ShellMainThread;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
 import com.android.wm.shell.pip.phone.PipMotionHelper;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.transition.Transitions;
 
@@ -133,7 +132,6 @@
     private final int mExitAnimationDuration;
     private final int mCrossFadeAnimationDuration;
     private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
-    private final Optional<LegacySplitScreenController> mLegacySplitScreenOptional;
     private final Optional<SplitScreenController> mSplitScreenOptional;
     protected final ShellTaskOrganizer mTaskOrganizer;
     protected final ShellExecutor mMainExecutor;
@@ -249,7 +247,8 @@
      * An optional overlay used to mask content changing between an app in/out of PiP, only set if
      * {@link PipTransitionState#getInSwipePipToHomeTransition()} is true.
      */
-    private SurfaceControl mSwipePipToHomeOverlay;
+    @Nullable
+    SurfaceControl mSwipePipToHomeOverlay;
 
     public PipTaskOrganizer(Context context,
             @NonNull SyncTransactionQueue syncTransactionQueue,
@@ -260,7 +259,6 @@
             @NonNull PipAnimationController pipAnimationController,
             @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
             @NonNull PipTransitionController pipTransitionController,
-            Optional<LegacySplitScreenController> legacySplitScreenOptional,
             Optional<SplitScreenController> splitScreenOptional,
             @NonNull DisplayController displayController,
             @NonNull PipUiEventLogger pipUiEventLogger,
@@ -283,7 +281,6 @@
         mPipAnimationController = pipAnimationController;
         mPipUiEventLoggerLogger = pipUiEventLogger;
         mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
-        mLegacySplitScreenOptional = legacySplitScreenOptional;
         mSplitScreenOptional = splitScreenOptional;
         mTaskOrganizer = shellTaskOrganizer;
         mMainExecutor = mainExecutor;
@@ -356,12 +353,24 @@
      * Callback when launcher finishes swipe-pip-to-home operation.
      * Expect {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)} afterwards.
      */
-    public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
+    public void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
             SurfaceControl overlay) {
         // do nothing if there is no startSwipePipToHome being called before
-        if (mPipTransitionState.getInSwipePipToHomeTransition()) {
-            mPipBoundsState.setBounds(destinationBounds);
-            mSwipePipToHomeOverlay = overlay;
+        if (!mPipTransitionState.getInSwipePipToHomeTransition()) {
+            return;
+        }
+        mPipBoundsState.setBounds(destinationBounds);
+        mSwipePipToHomeOverlay = overlay;
+        if (ENABLE_SHELL_TRANSITIONS) {
+            // With Shell transition, the overlay was attached to the remote transition leash, which
+            // will be removed when the current transition is finished, so we need to reparent it
+            // to the actual Task surface now.
+            // PipTransition is responsible to fade it out and cleanup when finishing the enter PIP
+            // transition.
+            final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+            mTaskOrganizer.reparentChildSurfaceToTask(taskId, overlay, t);
+            t.setLayer(overlay, Integer.MAX_VALUE);
+            t.apply();
         }
     }
 
@@ -395,8 +404,10 @@
         if (!mPipTransitionState.isInPip()
                 || mPipTransitionState.getTransitionState() == PipTransitionState.EXITING_PIP
                 || mToken == null) {
-            Log.wtf(TAG, "Not allowed to exitPip in current state"
-                    + " mState=" + mPipTransitionState.getTransitionState() + " mToken=" + mToken);
+            ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Not allowed to exitPip in current state"
+                            + " mState=%d mToken=%s", TAG, mPipTransitionState.getTransitionState(),
+                    mToken);
             return;
         }
 
@@ -438,11 +449,7 @@
             tx.setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height());
             // We set to fullscreen here for now, but later it will be set to UNDEFINED for
             // the proper windowing mode to take place. See #applyWindowingModeChangeOnExit.
-            wct.setActivityWindowingMode(mToken,
-                    direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN
-                            && !requestEnterSplit
-                            ? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
-                            : WINDOWING_MODE_FULLSCREEN);
+            wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN);
             wct.setBounds(mToken, destinationBounds);
             wct.setBoundsChangeTransaction(mToken, tx);
         }
@@ -489,20 +496,17 @@
         wct.setWindowingMode(mToken, getOutPipWindowingMode());
         // Simply reset the activity mode set prior to the animation running.
         wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
-        mLegacySplitScreenOptional.ifPresent(splitScreen -> {
-            if (direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
-                wct.reparent(mToken, splitScreen.getSecondaryRoot(), true /* onTop */);
-            }
-        });
     }
 
     /**
      * Removes PiP immediately.
      */
     public void removePip() {
-        if (!mPipTransitionState.isInPip() ||  mToken == null) {
-            Log.wtf(TAG, "Not allowed to removePip in current state"
-                    + " mState=" + mPipTransitionState.getTransitionState() + " mToken=" + mToken);
+        if (!mPipTransitionState.isInPip() || mToken == null) {
+            ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Not allowed to removePip in current state"
+                            + " mState=%d mToken=%s", TAG, mPipTransitionState.getTransitionState(),
+                    mToken);
             return;
         }
 
@@ -539,7 +543,9 @@
             ActivityTaskManager.getService().removeRootTasksInWindowingModes(
                     new int[]{ WINDOWING_MODE_PINNED });
         } catch (RemoteException e) {
-            Log.e(TAG, "Failed to remove PiP", e);
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Failed to remove PiP, %s",
+                    TAG, e);
         }
     }
 
@@ -568,7 +574,9 @@
             if (!mWaitForFixedRotation) {
                 onEndOfSwipePipToHomeTransition();
             } else {
-                Log.d(TAG, "Defer onTaskAppeared-SwipePipToHome until end of fixed rotation.");
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: Defer onTaskAppeared-SwipePipToHome until end of fixed rotation.",
+                        TAG);
             }
             return;
         }
@@ -576,7 +584,8 @@
         if (mOneShotAnimationType == ANIM_TYPE_ALPHA
                 && SystemClock.uptimeMillis() - mLastOneShotAlphaAnimationTime
                 > ONE_SHOT_ALPHA_ANIMATION_TIMEOUT_MS) {
-            Log.d(TAG, "Alpha animation is expired. Use bounds animation.");
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Alpha animation is expired. Use bounds animation.", TAG);
             mOneShotAnimationType = ANIM_TYPE_BOUNDS;
         }
 
@@ -613,8 +622,9 @@
 
     private void onTaskAppearedWithFixedRotation() {
         if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
-            Log.d(TAG, "Defer entering PiP alpha animation, fixed rotation is ongoing");
-            // If deferred, hide the surface till fixed rotation is completed.
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Defer entering PiP alpha animation, fixed rotation is ongoing", TAG);
+            // If deferred, hside the surface till fixed rotation is completed.
             final SurfaceControl.Transaction tx =
                     mSurfaceControlTransactionFactory.getTransaction();
             tx.setAlpha(mLeash, 0f);
@@ -671,7 +681,6 @@
 
     private void onEndOfSwipePipToHomeTransition() {
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            mSwipePipToHomeOverlay = null;
             return;
         }
 
@@ -763,7 +772,8 @@
         final WindowContainerToken token = info.token;
         Objects.requireNonNull(token, "Requires valid WindowContainerToken");
         if (token.asBinder() != mToken.asBinder()) {
-            Log.wtf(TAG, "Unrecognized token: " + token);
+            ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Unrecognized token: %s", TAG, token);
             return;
         }
         onExitPipFinished(info);
@@ -788,8 +798,9 @@
         Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken");
         if (mPipTransitionState.getTransitionState() != PipTransitionState.ENTERED_PIP
                 && mPipTransitionState.getTransitionState() != PipTransitionState.EXITING_PIP) {
-            Log.d(TAG, "Defer onTaskInfoChange in current state: "
-                    + mPipTransitionState.getTransitionState());
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Defer onTaskInfoChange in current state: %d", TAG,
+                    mPipTransitionState.getTransitionState());
             // Defer applying PiP parameters if the task is entering PiP to avoid disturbing
             // the animation.
             mDeferredTaskInfo = info;
@@ -800,7 +811,8 @@
                 mPipBoundsAlgorithm.getMinimalSize(info.topActivityInfo));
         final PictureInPictureParams newParams = info.pictureInPictureParams;
         if (newParams == null || !applyPictureInPictureParams(newParams)) {
-            Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams);
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Ignored onTaskInfoChanged with PiP param: %s", TAG, newParams);
             return;
         }
         // Aspect ratio changed, re-calculate bounds if valid.
@@ -823,6 +835,24 @@
     }
 
     @Override
+    public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+        b.setParent(findTaskSurface(taskId));
+    }
+
+    @Override
+    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+            SurfaceControl.Transaction t) {
+        t.reparent(sc, findTaskSurface(taskId));
+    }
+
+    private SurfaceControl findTaskSurface(int taskId) {
+        if (mTaskInfo == null || mLeash == null || mTaskInfo.taskId != taskId) {
+            throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
+        }
+        return mLeash;
+    }
+
+    @Override
     public void onFixedRotationStarted(int displayId, int newRotation) {
         mNextRotation = newRotation;
         mWaitForFixedRotation = true;
@@ -877,9 +907,13 @@
         clearWaitForFixedRotation();
     }
 
-    /** Called when exiting PIP tranisiton is finished to do the state cleanup. */
+    /** Called when exiting PIP transition is finished to do the state cleanup. */
     void onExitPipFinished(TaskInfo info) {
         clearWaitForFixedRotation();
+        if (mSwipePipToHomeOverlay != null) {
+            removeContentOverlay(mSwipePipToHomeOverlay, null /* callback */);
+            mSwipePipToHomeOverlay = null;
+        }
         mPipTransitionState.setInSwipePipToHomeTransition(false);
         mPictureInPictureParams = null;
         mPipTransitionState.setTransitionState(PipTransitionState.UNDEFINED);
@@ -895,7 +929,8 @@
 
     private void fadeExistingPip(boolean show) {
         if (mLeash == null || !mLeash.isValid()) {
-            Log.w(TAG, "Invalid leash on fadeExistingPip: " + mLeash);
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Invalid leash on fadeExistingPip: %s", TAG, mLeash);
             return;
         }
         final float alphaStart = show ? 0 : 1;
@@ -942,11 +977,13 @@
         if ((mPipTransitionState.getInSwipePipToHomeTransition()
                 || waitForFixedRotationOnEnteringPip) && fromRotation) {
             if (DEBUG) {
-                Log.d(TAG, "Skip onMovementBoundsChanged on rotation change"
-                        + " InSwipePipToHomeTransition="
-                        + mPipTransitionState.getInSwipePipToHomeTransition()
-                        + " mWaitForFixedRotation=" + mWaitForFixedRotation
-                        + " getTransitionState=" + mPipTransitionState.getTransitionState());
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: Skip onMovementBoundsChanged on rotation change"
+                                + " InSwipePipToHomeTransition=%b"
+                                + " mWaitForFixedRotation=%b"
+                                + " getTransitionState=%d", TAG,
+                        mPipTransitionState.getInSwipePipToHomeTransition(), mWaitForFixedRotation,
+                        mPipTransitionState.getTransitionState());
             }
             return;
         }
@@ -1061,7 +1098,8 @@
             @PipAnimationController.TransitionDirection int direction,
             Consumer<Rect> updateBoundsCallback) {
         if (mWaitForFixedRotation) {
-            Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred");
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: skip scheduleAnimateResizePip, entering pip deferred", TAG);
             return;
         }
         scheduleAnimateResizePip(mPipBoundsState.getBounds(), toBounds, 0 /* startingAngle */,
@@ -1075,7 +1113,8 @@
     public void scheduleAnimateResizePip(Rect fromBounds, Rect toBounds, int duration,
             float startingAngle, Consumer<Rect> updateBoundsCallback) {
         if (mWaitForFixedRotation) {
-            Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred");
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: skip scheduleAnimateResizePip, entering pip deferred", TAG);
             return;
         }
         scheduleAnimateResizePip(fromBounds, toBounds, startingAngle, null /* sourceHintRect */,
@@ -1113,7 +1152,8 @@
     public void scheduleResizePip(Rect toBounds, Consumer<Rect> updateBoundsCallback) {
         // Could happen when exitPip
         if (mToken == null || mLeash == null) {
-            Log.w(TAG, "Abort animation, invalid leash");
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Abort animation, invalid leash", TAG);
             return;
         }
         mPipBoundsState.setBounds(toBounds);
@@ -1148,12 +1188,14 @@
             Consumer<Rect> updateBoundsCallback) {
         // Could happen when exitPip
         if (mToken == null || mLeash == null) {
-            Log.w(TAG, "Abort animation, invalid leash");
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Abort animation, invalid leash", TAG);
             return;
         }
 
         if (startBounds.isEmpty() || toBounds.isEmpty()) {
-            Log.w(TAG, "Attempted to user resize PIP to or from empty bounds, aborting.");
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Attempted to user resize PIP to or from empty bounds, aborting.", TAG);
             return;
         }
 
@@ -1228,7 +1270,8 @@
             return;
         }
         if (mWaitForFixedRotation) {
-            Log.d(TAG, "skip scheduleOffsetPip, entering pip deferred");
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: skip scheduleOffsetPip, entering pip deferred", TAG);
             return;
         }
         offsetPip(originalBounds, 0 /* xOffset */, offset, duration);
@@ -1241,7 +1284,8 @@
 
     private void offsetPip(Rect originalBounds, int xOffset, int yOffset, int durationMs) {
         if (mTaskInfo == null) {
-            Log.w(TAG, "mTaskInfo is not set");
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: mTaskInfo is not set",
+                    TAG);
             return;
         }
         final Rect destinationBounds = new Rect(originalBounds);
@@ -1386,7 +1430,8 @@
             float startingAngle) {
         // Could happen when exitPip
         if (mToken == null || mLeash == null) {
-            Log.w(TAG, "Abort animation, invalid leash");
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Abort animation, invalid leash", TAG);
             return null;
         }
         final int rotationDelta = mWaitForFixedRotation
@@ -1453,36 +1498,21 @@
     }
 
     /**
-     * Sync with {@link LegacySplitScreenController} or {@link SplitScreenController} on destination
-     * bounds if PiP is going to split screen.
+     * Sync with {@link SplitScreenController} on destination bounds if PiP is going to
+     * split screen.
      *
      * @param destinationBoundsOut contain the updated destination bounds if applicable
      * @return {@code true} if destinationBounds is altered for split screen
      */
     private boolean syncWithSplitScreenBounds(Rect destinationBoundsOut, boolean enterSplit) {
-        if (enterSplit && mSplitScreenOptional.isPresent()) {
-            final Rect topLeft = new Rect();
-            final Rect bottomRight = new Rect();
-            mSplitScreenOptional.get().getStageBounds(topLeft, bottomRight);
-            final boolean isPipTopLeft = isPipTopLeft();
-            destinationBoundsOut.set(isPipTopLeft ? topLeft : bottomRight);
-            return true;
-        }
-
-        if (!mLegacySplitScreenOptional.isPresent()) {
+        if (!enterSplit || !mSplitScreenOptional.isPresent()) {
             return false;
         }
-
-        LegacySplitScreenController legacySplitScreen = mLegacySplitScreenOptional.get();
-        if (!legacySplitScreen.isDividerVisible()) {
-            // fail early if system is not in split screen mode
-            return false;
-        }
-
-        // PiP window will go to split-secondary mode instead of fullscreen, populates the
-        // split screen bounds here.
-        destinationBoundsOut.set(legacySplitScreen.getDividerView()
-                .getNonMinimizedSplitScreenSecondaryBounds());
+        final Rect topLeft = new Rect();
+        final Rect bottomRight = new Rect();
+        mSplitScreenOptional.get().getStageBounds(topLeft, bottomRight);
+        final boolean isPipTopLeft = isPipTopLeft();
+        destinationBoundsOut.set(isPipTopLeft ? topLeft : bottomRight);
         return true;
     }
 
@@ -1501,7 +1531,8 @@
             if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) {
                 // Could happen if onTaskVanished happens during the animation since we may have
                 // set a start delay on this animation.
-                Log.d(TAG, "Task vanished, skip fadeOutAndRemoveOverlay");
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: Task vanished, skip fadeOutAndRemoveOverlay", TAG);
                 animation.removeAllListeners();
                 animation.removeAllUpdateListeners();
                 animation.cancel();
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 f01457b..be713a5 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
@@ -50,7 +50,6 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.IBinder;
-import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.window.TransitionInfo;
@@ -61,8 +60,10 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.transition.CounterRotatorHelper;
 import com.android.wm.shell.transition.Transitions;
@@ -151,7 +152,7 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
-        final TransitionInfo.Change currentPipChange = findCurrentPipChange(info);
+        final TransitionInfo.Change currentPipTaskChange = findCurrentPipTaskChange(info);
         final TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info);
         mInFixedRotation = fixedRotationChange != null;
         mEndFixedRotation = mInFixedRotation
@@ -171,22 +172,29 @@
                 throw new RuntimeException("Previous callback not called, aborting exit PIP.");
             }
 
-            if (currentPipChange == null) {
-                throw new RuntimeException("Cannot find the pip window for exit-pip transition.");
+            // PipTaskChange can be null if the PIP task has been detached, for example, when the
+            // task contains multiple activities, the PIP will be moved to a new PIP task when
+            // entering, and be moved back when exiting. In that case, the PIP task will be removed
+            // immediately.
+            final TaskInfo pipTaskInfo = currentPipTaskChange != null
+                    ? currentPipTaskChange.getTaskInfo()
+                    : mPipOrganizer.getTaskInfo();
+            if (pipTaskInfo == null) {
+                throw new RuntimeException("Cannot find the pip task for exit-pip transition.");
             }
 
             switch (type) {
                 case TRANSIT_EXIT_PIP:
                     startExitAnimation(info, startTransaction, finishTransaction, finishCallback,
-                            currentPipChange);
+                            pipTaskInfo, currentPipTaskChange);
                     break;
                 case TRANSIT_EXIT_PIP_TO_SPLIT:
                     startExitToSplitAnimation(info, startTransaction, finishTransaction,
-                            finishCallback, currentPipChange);
+                            finishCallback, pipTaskInfo);
                     break;
                 case TRANSIT_REMOVE_PIP:
                     removePipImmediately(info, startTransaction, finishTransaction, finishCallback,
-                            currentPipChange);
+                            pipTaskInfo);
                     break;
                 default:
                     throw new IllegalStateException("mExitTransition with unexpected transit type="
@@ -199,9 +207,9 @@
         // The previous PIP Task is no longer in PIP, but this is not an exit transition (This can
         // happen when a new activity requests enter PIP). In this case, we just show this Task in
         // its end state, and play other animation as normal.
-        if (currentPipChange != null
-                && currentPipChange.getTaskInfo().getWindowingMode() != WINDOWING_MODE_PINNED) {
-            resetPrevPip(currentPipChange, startTransaction);
+        if (currentPipTaskChange != null
+                && currentPipTaskChange.getTaskInfo().getWindowingMode() != WINDOWING_MODE_PINNED) {
+            resetPrevPip(currentPipTaskChange, startTransaction);
         }
 
         // Entering PIP.
@@ -211,8 +219,9 @@
 
         // 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 (currentPipChange != null) {
-            updatePipForUnhandledTransition(currentPipChange, startTransaction, finishTransaction);
+        if (currentPipTaskChange != null) {
+            updatePipForUnhandledTransition(currentPipTaskChange, startTransaction,
+                    finishTransaction);
         }
 
         // Fade in the fadeout PIP when the fixed rotation is finished.
@@ -321,7 +330,7 @@
     }
 
     @Nullable
-    private TransitionInfo.Change findCurrentPipChange(@NonNull TransitionInfo info) {
+    private TransitionInfo.Change findCurrentPipTaskChange(@NonNull TransitionInfo info) {
         if (mCurrentPipTaskToken == null) {
             return null;
         }
@@ -349,9 +358,30 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback,
-            @NonNull TransitionInfo.Change pipChange) {
+            @NonNull TaskInfo taskInfo, @Nullable TransitionInfo.Change pipTaskChange) {
+        TransitionInfo.Change pipChange = pipTaskChange;
+        if (pipChange == null) {
+            // The pipTaskChange is null, this can happen if we are reparenting the PIP activity
+            // back to its original Task. In that case, we should animate the activity leash
+            // instead, which should be the only non-task, independent, TRANSIT_CHANGE window.
+            for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+                final TransitionInfo.Change change = info.getChanges().get(i);
+                if (change.getTaskInfo() == null && change.getMode() == TRANSIT_CHANGE
+                        && TransitionInfo.isIndependent(change, info)) {
+                    pipChange = change;
+                    break;
+                }
+            }
+        }
+        if (pipChange == null) {
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: No window of exiting PIP is found. Can't play expand animation", TAG);
+            removePipImmediately(info, startTransaction, finishTransaction, finishCallback,
+                    taskInfo);
+            return;
+        }
         mFinishCallback = (wct, wctCB) -> {
-            mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo());
+            mPipOrganizer.onExitPipFinished(taskInfo);
             finishCallback.onTransitionFinished(wct, wctCB);
         };
         mFinishTransaction = finishTransaction;
@@ -371,7 +401,7 @@
             if (displayRotationChange != null) {
                 // Exiting PIP to fullscreen with orientation change.
                 startExpandAndRotationAnimation(info, startTransaction, finishTransaction,
-                        displayRotationChange, pipChange);
+                        displayRotationChange, taskInfo, pipChange);
                 return;
             }
         }
@@ -412,15 +442,14 @@
         } else {
             rotationDelta = Surface.ROTATION_0;
         }
-        startExpandAnimation(pipChange.getTaskInfo(), pipChange.getLeash(), destinationBounds,
-                rotationDelta);
+        startExpandAnimation(taskInfo, pipChange.getLeash(), destinationBounds, rotationDelta);
     }
 
     private void startExpandAndRotationAnimation(@NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull TransitionInfo.Change displayRotationChange,
-            @NonNull TransitionInfo.Change pipChange) {
+            @NonNull TaskInfo taskInfo, @NonNull TransitionInfo.Change pipChange) {
         final int rotateDelta = deltaRotation(displayRotationChange.getStartRotation(),
                 displayRotationChange.getEndRotation());
 
@@ -458,7 +487,7 @@
 
         // Expand and rotate the pip window to fullscreen.
         final PipAnimationController.PipTransitionAnimator animator =
-                mPipAnimationController.getAnimator(pipChange.getTaskInfo(), pipChange.getLeash(),
+                mPipAnimationController.getAnimator(taskInfo, pipChange.getLeash(),
                         startBounds, startBounds, endBounds, null, TRANSITION_DIRECTION_LEAVE_PIP,
                         0 /* startingAngle */, pipRotateDelta);
         animator.setTransitionDirection(TRANSITION_DIRECTION_LEAVE_PIP)
@@ -484,11 +513,11 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback,
-            @NonNull TransitionInfo.Change pipChange) {
+            @NonNull TaskInfo taskInfo) {
         startTransaction.apply();
         finishTransaction.setWindowCrop(info.getChanges().get(0).getLeash(),
                 mPipBoundsState.getDisplayBounds());
-        mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo());
+        mPipOrganizer.onExitPipFinished(taskInfo);
         finishCallback.onTransitionFinished(null, null);
     }
 
@@ -603,11 +632,18 @@
                 && taskInfo.pictureInPictureParams.isAutoEnterEnabled()
                 && mPipTransitionState.getInSwipePipToHomeTransition()) {
             mOneShotAnimationType = ANIM_TYPE_BOUNDS;
-            SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
-            tx.setMatrix(leash, Matrix.IDENTITY_MATRIX, new float[9])
+            final SurfaceControl swipePipToHomeOverlay = mPipOrganizer.mSwipePipToHomeOverlay;
+            startTransaction.setMatrix(leash, Matrix.IDENTITY_MATRIX, new float[9])
                     .setPosition(leash, destinationBounds.left, destinationBounds.top)
                     .setWindowCrop(leash, destinationBounds.width(), destinationBounds.height());
-            startTransaction.merge(tx);
+            if (swipePipToHomeOverlay != null) {
+                // Launcher fade in the overlay on top of the fullscreen Task. It is possible we
+                // reparent the PIP activity to a new PIP task (in case there are other activities
+                // in the original Task), so we should also reparent the overlay to the PIP task.
+                startTransaction.reparent(swipePipToHomeOverlay, leash)
+                        .setLayer(swipePipToHomeOverlay, Integer.MAX_VALUE);
+                mPipOrganizer.mSwipePipToHomeOverlay = null;
+            }
             startTransaction.apply();
             if (rotationDelta != Surface.ROTATION_0 && mInFixedRotation) {
                 // For fixed rotation, set the destination bounds to the new rotation coordinates
@@ -617,6 +653,10 @@
             mPipBoundsState.setBounds(destinationBounds);
             onFinishResize(taskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, null /* tx */);
             sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
+            if (swipePipToHomeOverlay != null) {
+                mPipOrganizer.fadeOutAndRemoveOverlay(swipePipToHomeOverlay,
+                        null /* callback */, false /* withStartDelay */);
+            }
             mPipTransitionState.setInSwipePipToHomeTransition(false);
             return true;
         }
@@ -677,11 +717,11 @@
         }
     }
 
-    private void startExitToSplitAnimation(TransitionInfo info,
-            SurfaceControl.Transaction startTransaction,
-            SurfaceControl.Transaction finishTransaction,
-            Transitions.TransitionFinishCallback finishCallback,
-            TransitionInfo.Change pipChange) {
+    private void startExitToSplitAnimation(@NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback,
+            @NonNull TaskInfo taskInfo) {
         final int changeSize = info.getChanges().size();
         if (changeSize < 4) {
             throw new RuntimeException(
@@ -709,15 +749,15 @@
         mSplitScreenOptional.get().finishEnterSplitScreen(startTransaction);
         startTransaction.apply();
 
-        mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo());
+        mPipOrganizer.onExitPipFinished(taskInfo);
         finishCallback.onTransitionFinished(null, null);
     }
 
-    private void resetPrevPip(@NonNull TransitionInfo.Change prevPipChange,
+    private void resetPrevPip(@NonNull TransitionInfo.Change prevPipTaskChange,
             @NonNull SurfaceControl.Transaction startTransaction) {
-        final SurfaceControl leash = prevPipChange.getLeash();
-        final Rect bounds = prevPipChange.getEndAbsBounds();
-        final Point offset = prevPipChange.getEndRelOffset();
+        final SurfaceControl leash = prevPipTaskChange.getLeash();
+        final Rect bounds = prevPipTaskChange.getEndAbsBounds();
+        final Point offset = prevPipTaskChange.getEndRelOffset();
         bounds.offset(-offset.x, -offset.y);
 
         startTransaction.setWindowCrop(leash, null);
@@ -725,7 +765,7 @@
         startTransaction.setCornerRadius(leash, 0);
         startTransaction.setPosition(leash, bounds.left, bounds.top);
 
-        if (mHasFadeOut && prevPipChange.getTaskInfo().isVisible()) {
+        if (mHasFadeOut && prevPipTaskChange.getTaskInfo().isVisible()) {
             if (mPipAnimationController.getCurrentAnimator() != null) {
                 mPipAnimationController.getCurrentAnimator().cancel();
             }
@@ -733,7 +773,7 @@
         }
         mHasFadeOut = false;
         mCurrentPipTaskToken = null;
-        mPipOrganizer.onExitPipFinished(prevPipChange.getTaskInfo());
+        mPipOrganizer.onExitPipFinished(prevPipTaskChange.getTaskInfo());
     }
 
     private void updatePipForUnhandledTransition(@NonNull TransitionInfo.Change pipChange,
@@ -757,7 +797,8 @@
         final SurfaceControl leash = mPipOrganizer.getSurfaceControl();
         final TaskInfo taskInfo = mPipOrganizer.getTaskInfo();
         if (leash == null || !leash.isValid() || taskInfo == null) {
-            Log.w(TAG, "Invalid leash on fadeExistingPip: " + leash);
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Invalid leash on fadeExistingPip: %s", TAG, leash);
             return;
         }
         final float alphaStart = show ? 0 : 1;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java
index da6d980..d7b69ad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java
@@ -24,9 +24,11 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.RemoteException;
-import android.util.Log;
 import android.util.Pair;
 
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+
 /** A class that includes convenience methods. */
 public class PipUtils {
     private static final String TAG = "PipUtils";
@@ -51,7 +53,8 @@
                 }
             }
         } catch (RemoteException e) {
-            Log.w(TAG, "Unable to get pinned stack.");
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Unable to get pinned stack.", TAG);
         }
         return new Pair<>(null, 0);
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 71cff02..c4dadf1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -29,7 +29,6 @@
 import android.os.Debug;
 import android.os.Handler;
 import android.os.RemoteException;
-import android.util.Log;
 import android.util.Size;
 import android.view.MotionEvent;
 import android.view.SurfaceControl;
@@ -37,6 +36,7 @@
 import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
 import android.view.WindowManagerGlobal;
 
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.pip.PipBoundsState;
@@ -44,6 +44,7 @@
 import com.android.wm.shell.pip.PipMediaController.ActionListener;
 import com.android.wm.shell.pip.PipMenuController;
 import com.android.wm.shell.pip.PipUiEventLogger;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 
 import java.io.PrintWriter;
@@ -285,13 +286,15 @@
     private void showMenuInternal(int menuState, Rect stackBounds, boolean allowMenuTimeout,
             boolean willResizeMenu, boolean withDelay, boolean showResizeHandle) {
         if (DEBUG) {
-            Log.d(TAG, "showMenu() state=" + menuState
-                    + " isMenuVisible=" + isMenuVisible()
-                    + " allowMenuTimeout=" + allowMenuTimeout
-                    + " willResizeMenu=" + willResizeMenu
-                    + " withDelay=" + withDelay
-                    + " showResizeHandle=" + showResizeHandle
-                    + " callers=\n" + Debug.getCallers(5, "    "));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: showMenu() state=%s"
+                            + " isMenuVisible=%s"
+                            + " allowMenuTimeout=%s"
+                            + " willResizeMenu=%s"
+                            + " withDelay=%s"
+                            + " showResizeHandle=%s"
+                            + " callers=\n%s", TAG, menuState, isMenuVisible(), allowMenuTimeout,
+                    willResizeMenu, withDelay, showResizeHandle, Debug.getCallers(5, "    "));
         }
 
         if (!maybeCreateSyncApplier()) {
@@ -383,7 +386,8 @@
 
     private boolean maybeCreateSyncApplier() {
         if (mPipMenuView == null || mPipMenuView.getViewRootImpl() == null) {
-            Log.v(TAG, "Not going to move PiP, either menu or its parent is not created.");
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Not going to move PiP, either menu or its parent is not created.", TAG);
             return false;
         }
 
@@ -400,7 +404,8 @@
     public void pokeMenu() {
         final boolean isMenuVisible = isMenuVisible();
         if (DEBUG) {
-            Log.d(TAG, "pokeMenu() isMenuVisible=" + isMenuVisible);
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: pokeMenu() isMenuVisible=%b", TAG, isMenuVisible);
         }
         if (isMenuVisible) {
             mPipMenuView.pokeMenu();
@@ -410,7 +415,8 @@
     private void fadeOutMenu() {
         final boolean isMenuVisible = isMenuVisible();
         if (DEBUG) {
-            Log.d(TAG, "fadeOutMenu() isMenuVisible=" + isMenuVisible);
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: fadeOutMenu() isMenuVisible=%b", TAG, isMenuVisible);
         }
         if (isMenuVisible) {
             mPipMenuView.fadeOutMenu();
@@ -436,11 +442,14 @@
     public void hideMenu(@PipMenuView.AnimationType int animationType, boolean resize) {
         final boolean isMenuVisible = isMenuVisible();
         if (DEBUG) {
-            Log.d(TAG, "hideMenu() state=" + mMenuState
-                    + " isMenuVisible=" + isMenuVisible
-                    + " animationType=" + animationType
-                    + " resize=" + resize
-                    + " callers=\n" + Debug.getCallers(5, "    "));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: hideMenu() state=%s"
+                            + " isMenuVisible=%s"
+                            + " animationType=%s"
+                            + " resize=%s"
+                            + " callers=\n%s", TAG, mMenuState, isMenuVisible,
+                    animationType, resize,
+                    Debug.getCallers(5, "    "));
         }
         if (isMenuVisible) {
             mPipMenuView.hideMenu(resize, animationType);
@@ -516,9 +525,11 @@
      */
     void onMenuStateChangeStart(int menuState, boolean resize, Runnable callback) {
         if (DEBUG) {
-            Log.d(TAG, "onMenuStateChangeStart() mMenuState=" + mMenuState
-                    + " menuState=" + menuState + " resize=" + resize
-                    + " callers=\n" + Debug.getCallers(5, "    "));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: onMenuStateChangeStart() mMenuState=%s"
+                            + " menuState=%s resize=%s"
+                            + " callers=\n%s", TAG, mMenuState, menuState, resize,
+                    Debug.getCallers(5, "    "));
         }
 
         if (menuState != mMenuState) {
@@ -538,7 +549,8 @@
                         mSystemWindows.getFocusGrantToken(mPipMenuView),
                         menuState != MENU_STATE_NONE /* grantFocus */);
             } catch (RemoteException e) {
-                Log.e(TAG, "Unable to update focus as menu appears/disappears", e);
+                ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: Unable to update focus as menu appears/disappears, %s", TAG, e);
             }
         }
     }
@@ -584,9 +596,11 @@
     public void updateMenuLayout(Rect bounds) {
         final boolean isMenuVisible = isMenuVisible();
         if (DEBUG) {
-            Log.d(TAG, "updateMenuLayout() state=" + mMenuState
-                    + " isMenuVisible=" + isMenuVisible
-                    + " callers=\n" + Debug.getCallers(5, "    "));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: updateMenuLayout() state=%s"
+                            + " isMenuVisible=%s"
+                            + " callers=\n%s", TAG, mMenuState, isMenuVisible,
+                    Debug.getCallers(5, "    "));
         }
         if (isMenuVisible) {
             mPipMenuView.updateMenuLayout(bounds);
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 d3dc915..e7a1c4c 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
@@ -46,10 +46,8 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.util.Log;
 import android.util.Pair;
 import android.util.Size;
-import android.util.Slog;
 import android.view.DisplayInfo;
 import android.view.SurfaceControl;
 import android.view.WindowManagerGlobal;
@@ -61,6 +59,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.common.DisplayChangeController;
@@ -85,6 +84,7 @@
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.pip.PipUtils;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.transition.Transitions;
 
 import java.io.PrintWriter;
@@ -282,7 +282,8 @@
             Optional<OneHandedController> oneHandedController,
             ShellExecutor mainExecutor) {
         if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
-            Slog.w(TAG, "Device doesn't support Pip feature");
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Device doesn't support Pip feature", TAG);
             return null;
         }
 
@@ -375,7 +376,8 @@
         try {
             mWindowManagerShellWrapper.addPinnedStackListener(mPinnedTaskListener);
         } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to register pinned stack listener", e);
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Failed to register pinned stack listener, %s", TAG, e);
         }
 
         try {
@@ -387,7 +389,8 @@
                 mPipInputConsumer.registerInputConsumer();
             }
         } catch (RemoteException | UnsupportedOperationException e) {
-            Log.e(TAG, "Failed to register pinned stack listener", e);
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Failed to register pinned stack listener, %s", TAG, e);
             e.printStackTrace();
         }
 
@@ -592,9 +595,9 @@
         return entryBounds;
     }
 
-    private void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
+    private void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
             SurfaceControl overlay) {
-        mPipTaskOrganizer.stopSwipePipToHome(componentName, destinationBounds, overlay);
+        mPipTaskOrganizer.stopSwipePipToHome(taskId, componentName, destinationBounds, overlay);
     }
 
     private String getTransitionTag(int direction) {
@@ -724,7 +727,8 @@
                     .getRootTaskInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
             if (pinnedTaskInfo == null) return false;
         } catch (RemoteException e) {
-            Log.e(TAG, "Failed to get RootTaskInfo for pinned task", e);
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Failed to get RootTaskInfo for pinned task, %s", TAG, e);
             return false;
         }
         final PipSnapAlgorithm pipSnapAlgorithm = mPipBoundsAlgorithm.getSnapAlgorithm();
@@ -870,7 +874,8 @@
                     PipController.this.dump(pw);
                 });
             } catch (InterruptedException e) {
-                Slog.e(TAG, "Failed to dump PipController in 2s");
+                ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: Failed to dump PipController in 2s", TAG);
             }
         }
     }
@@ -923,11 +928,12 @@
         }
 
         @Override
-        public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
-                SurfaceControl overlay) {
+        public void stopSwipePipToHome(int taskId, ComponentName componentName,
+                Rect destinationBounds, SurfaceControl overlay) {
             executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome",
                     (controller) -> {
-                        controller.stopSwipePipToHome(componentName, destinationBounds, overlay);
+                        controller.stopSwipePipToHome(taskId, componentName, destinationBounds,
+                                overlay);
                     });
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
index 3115f8a..11633a9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
@@ -253,11 +253,11 @@
     private WindowManager.LayoutParams getDismissTargetLayoutParams() {
         final Point windowSize = new Point();
         mWindowManager.getDefaultDisplay().getRealSize(windowSize);
-
+        int height = Math.min(windowSize.y, mDismissAreaHeight);
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 WindowManager.LayoutParams.MATCH_PARENT,
-                mDismissAreaHeight,
-                0, windowSize.y - mDismissAreaHeight,
+                height,
+                0, windowSize.y - height,
                 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                         | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
index 6e3a20d..0f3ff36 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
@@ -22,14 +22,15 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
-import android.util.Log;
 import android.view.BatchedInputEventReceiver;
 import android.view.Choreographer;
 import android.view.IWindowManager;
 import android.view.InputChannel;
 import android.view.InputEvent;
 
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.io.PrintWriter;
 
@@ -141,11 +142,13 @@
             mWindowManager.destroyInputConsumer(mName, DEFAULT_DISPLAY);
             mWindowManager.createInputConsumer(mToken, mName, DEFAULT_DISPLAY, inputChannel);
         } catch (RemoteException e) {
-            Log.e(TAG, "Failed to create input consumer", e);
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Failed to create input consumer, %s", TAG, e);
         }
         mMainExecutor.execute(() -> {
             // Choreographer.getSfInstance() must be called on the thread that the input event
             // receiver should be receiving events
+            // TODO(b/222697646): remove getSfInstance usage and use vsyncId for transactions
             mInputEventReceiver = new InputEventReceiver(inputChannel,
                 Looper.myLooper(), Choreographer.getSfInstance());
             if (mRegistrationListener != null) {
@@ -165,7 +168,8 @@
             // TODO(b/113087003): Support Picture-in-picture in multi-display.
             mWindowManager.destroyInputConsumer(mName, DEFAULT_DISPLAY);
         } catch (RemoteException e) {
-            Log.e(TAG, "Failed to destroy input consumer", e);
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Failed to destroy input consumer, %s", TAG, e);
         }
         mInputEventReceiver.dispose();
         mInputEventReceiver = null;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 225305b..c0fa8c0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -47,7 +47,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.UserHandle;
-import android.util.Log;
 import android.util.Pair;
 import android.util.Size;
 import android.view.KeyEvent;
@@ -60,11 +59,13 @@
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.pip.PipUiEventLogger;
 import com.android.wm.shell.pip.PipUtils;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 
 import java.lang.annotation.Retention;
@@ -423,7 +424,7 @@
 
     /**
      * @return Estimated minimum {@link Size} to hold the actions.
-     *         See also {@link #updateActionViews(Rect)}
+     * See also {@link #updateActionViews(Rect)}
      */
     Size getEstimatedMinMenuSize() {
         final int pipActionSize = getResources().getDimensionPixelSize(R.dimen.pip_action_size);
@@ -505,7 +506,8 @@
                             try {
                                 action.getActionIntent().send();
                             } catch (CanceledException e) {
-                                Log.w(TAG, "Failed to send action", e);
+                                ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                        "%s: Failed to send action, %s", TAG, e);
                             }
                         });
                     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index 96fd59f..fa0f092 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -34,12 +34,12 @@
 import android.graphics.Rect;
 import android.os.Debug;
 import android.os.Looper;
-import android.util.Log;
 import android.view.Choreographer;
 
 import androidx.dynamicanimation.animation.AnimationHandler;
 import androidx.dynamicanimation.animation.AnimationHandler.FrameCallbackScheduler;
 
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.FloatProperties;
 import com.android.wm.shell.animation.PhysicsAnimator;
@@ -49,6 +49,7 @@
 import com.android.wm.shell.pip.PipSnapAlgorithm;
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipTransitionController;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.util.function.Consumer;
 
@@ -94,6 +95,8 @@
                 final FrameCallbackScheduler scheduler = new FrameCallbackScheduler() {
                     @Override
                     public void postFrameCallback(@androidx.annotation.NonNull Runnable runnable) {
+                        // TODO(b/222697646): remove getSfInstance usage and use vsyncId for
+                        //  transactions
                         Choreographer.getSfInstance().postFrameCallback(t -> runnable.run());
                     }
 
@@ -354,8 +357,9 @@
      */
     private void expandLeavePip(boolean skipAnimation, boolean enterSplit) {
         if (DEBUG) {
-            Log.d(TAG, "exitPip: skipAnimation=" + skipAnimation
-                    + " callers=\n" + Debug.getCallers(5, "    "));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: exitPip: skipAnimation=%s"
+                            + " callers=\n%s", TAG, skipAnimation, Debug.getCallers(5, "    "));
         }
         cancelPhysicsAnimation();
         mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);
@@ -368,7 +372,8 @@
     @Override
     public void dismissPip() {
         if (DEBUG) {
-            Log.d(TAG, "removePip: callers=\n" + Debug.getCallers(5, "    "));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: removePip: callers=\n%s", TAG, Debug.getCallers(5, "    "));
         }
         cancelPhysicsAnimation();
         mMenuController.hideMenu(ANIM_TYPE_DISMISS, false /* resize */);
@@ -552,8 +557,10 @@
      */
     void animateToOffset(Rect originalBounds, int offset) {
         if (DEBUG) {
-            Log.d(TAG, "animateToOffset: originalBounds=" + originalBounds + " offset=" + offset
-                    + " callers=\n" + Debug.getCallers(5, "    "));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: animateToOffset: originalBounds=%s offset=%s"
+                            + " callers=\n%s", TAG, originalBounds, offset,
+                    Debug.getCallers(5, "    "));
         }
         cancelPhysicsAnimation();
         mPipTaskOrganizer.scheduleOffsetPip(originalBounds, offset, SHIFT_DURATION,
@@ -671,8 +678,9 @@
      */
     private void resizePipUnchecked(Rect toBounds) {
         if (DEBUG) {
-            Log.d(TAG, "resizePipUnchecked: toBounds=" + toBounds
-                    + " callers=\n" + Debug.getCallers(5, "    "));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: resizePipUnchecked: toBounds=%s"
+                            + " callers=\n%s", TAG, toBounds, Debug.getCallers(5, "    "));
         }
         if (!toBounds.equals(getBounds())) {
             mPipTaskOrganizer.scheduleResizePip(toBounds, mUpdateBoundsCallback);
@@ -684,8 +692,10 @@
      */
     private void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) {
         if (DEBUG) {
-            Log.d(TAG, "resizeAndAnimatePipUnchecked: toBounds=" + toBounds
-                    + " duration=" + duration + " callers=\n" + Debug.getCallers(5, "    "));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: resizeAndAnimatePipUnchecked: toBounds=%s"
+                            + " duration=%s callers=\n%s", TAG, toBounds, duration,
+                    Debug.getCallers(5, "    "));
         }
 
         // Intentionally resize here even if the current bounds match the destination bounds.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index c816f18..abf1a95 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -625,6 +625,7 @@
 
     class PipResizeInputEventReceiver extends BatchedInputEventReceiver {
         PipResizeInputEventReceiver(InputChannel channel, Looper looper) {
+            // TODO(b/222697646): remove getSfInstance usage and use vsyncId for transactions
             super(channel, looper, Choreographer.getSfInstance());
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index 350f285..147a272 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -35,7 +35,6 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.provider.DeviceConfig;
-import android.util.Log;
 import android.util.Size;
 import android.view.InputEvent;
 import android.view.MotionEvent;
@@ -46,6 +45,7 @@
 import android.view.accessibility.AccessibilityWindowInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.ShellExecutor;
@@ -54,6 +54,7 @@
 import com.android.wm.shell.pip.PipBoundsState;
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipUiEventLogger;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.io.PrintWriter;
 
@@ -1010,7 +1011,8 @@
         }
         final Size estimatedMinMenuSize = mMenuController.getEstimatedMinMenuSize();
         if (estimatedMinMenuSize == null) {
-            Log.wtf(TAG, "Failed to get estimated menu size");
+            ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Failed to get estimated menu size", TAG);
             return false;
         }
         final Rect currentBounds = mPipBoundsState.getBounds();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
index 53303ff..d7d69f2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
@@ -17,15 +17,15 @@
 package com.android.wm.shell.pip.phone;
 
 import android.graphics.PointF;
-import android.os.Handler;
-import android.util.Log;
 import android.view.Display;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.ViewConfiguration;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.io.PrintWriter;
 
@@ -104,7 +104,8 @@
 
                 mActivePointerId = ev.getPointerId(0);
                 if (DEBUG) {
-                    Log.e(TAG, "Setting active pointer id on DOWN: " + mActivePointerId);
+                    ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                            "%s: Setting active pointer id on DOWN: %d", TAG, mActivePointerId);
                 }
                 mLastTouch.set(ev.getRawX(), ev.getRawY());
                 mDownTouch.set(mLastTouch);
@@ -131,7 +132,8 @@
                 addMovementToVelocityTracker(ev);
                 int pointerIndex = ev.findPointerIndex(mActivePointerId);
                 if (pointerIndex == -1) {
-                    Log.e(TAG, "Invalid active pointer id on MOVE: " + mActivePointerId);
+                    ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                            "%s: Invalid active pointer id on MOVE: %d", TAG, mActivePointerId);
                     break;
                 }
 
@@ -168,8 +170,9 @@
                     final int newPointerIndex = (pointerIndex == 0) ? 1 : 0;
                     mActivePointerId = ev.getPointerId(newPointerIndex);
                     if (DEBUG) {
-                        Log.e(TAG,
-                                "Relinquish active pointer id on POINTER_UP: " + mActivePointerId);
+                        ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: Relinquish active pointer id on POINTER_UP: %d",
+                                TAG, mActivePointerId);
                     }
                     mLastTouch.set(ev.getRawX(newPointerIndex), ev.getRawY(newPointerIndex));
                 }
@@ -189,7 +192,8 @@
 
                 int pointerIndex = ev.findPointerIndex(mActivePointerId);
                 if (pointerIndex == -1) {
-                    Log.e(TAG, "Invalid active pointer id on UP: " + mActivePointerId);
+                    ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                            "%s: Invalid active pointer id on UP: %d", TAG, mActivePointerId);
                     break;
                 }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
index 8ab78e6..d6dacd1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
@@ -28,15 +28,22 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Rect;
-import android.util.Log;
+import android.os.SystemClock;
+import android.util.ArraySet;
 import android.util.Size;
 import android.view.Gravity;
 
 import androidx.annotation.NonNull;
 
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.pip.PipSnapAlgorithm;
+import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+
+import java.util.Set;
 
 /**
  * Contains pip bounds calculations that are specific to TV.
@@ -46,91 +53,148 @@
     private static final String TAG = TvPipBoundsAlgorithm.class.getSimpleName();
     private static final boolean DEBUG = TvPipController.DEBUG;
 
-    private final @android.annotation.NonNull TvPipBoundsState mTvPipBoundsState;
+    private final @NonNull TvPipBoundsState mTvPipBoundsState;
 
     private int mFixedExpandedHeightInPx;
     private int mFixedExpandedWidthInPx;
 
+    private final TvPipKeepClearAlgorithm mKeepClearAlgorithm;
+
     public TvPipBoundsAlgorithm(Context context,
             @NonNull TvPipBoundsState tvPipBoundsState,
             @NonNull PipSnapAlgorithm pipSnapAlgorithm) {
         super(context, tvPipBoundsState, pipSnapAlgorithm);
         this.mTvPipBoundsState = tvPipBoundsState;
+        this.mKeepClearAlgorithm = new TvPipKeepClearAlgorithm(SystemClock::uptimeMillis);
+        reloadResources(context);
     }
 
-    @Override
-    protected void reloadResources(Context context) {
-        super.reloadResources(context);
+    private void reloadResources(Context context) {
         final Resources res = context.getResources();
         mFixedExpandedHeightInPx = res.getDimensionPixelSize(
                 com.android.internal.R.dimen.config_pictureInPictureExpandedHorizontalHeight);
         mFixedExpandedWidthInPx = res.getDimensionPixelSize(
                 com.android.internal.R.dimen.config_pictureInPictureExpandedVerticalWidth);
+        mKeepClearAlgorithm.setPipAreaPadding(
+                res.getDimensionPixelSize(R.dimen.pip_keep_clear_area_padding));
+        mKeepClearAlgorithm.setMaxRestrictedDistanceFraction(
+                res.getFraction(R.fraction.config_pipMaxRestrictedMoveDistance, 1, 1));
+        mKeepClearAlgorithm.setStashDuration(res.getInteger(R.integer.config_pipStashDuration));
+    }
+
+    @Override
+    public void onConfigurationChanged(Context context) {
+        super.onConfigurationChanged(context);
+        reloadResources(context);
     }
 
     /** Returns the destination bounds to place the PIP window on entry. */
     @Override
     public Rect getEntryDestinationBounds() {
-        if (DEBUG) Log.d(TAG, "getEntryDestinationBounds()");
-        if (mTvPipBoundsState.getTvExpandedAspectRatio() != 0
-                && !mTvPipBoundsState.isTvPipManuallyCollapsed()) {
-            updatePositionOnExpandToggled(Gravity.NO_GRAVITY, true);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: getEntryDestinationBounds()", TAG);
         }
-        return getTvPipBounds(true);
+        if (mTvPipBoundsState.isTvExpandedPipSupported()
+                && mTvPipBoundsState.getDesiredTvExpandedAspectRatio() != 0
+                && !mTvPipBoundsState.isTvPipManuallyCollapsed()) {
+            updateExpandedPipSize();
+            updateGravityOnExpandToggled(Gravity.NO_GRAVITY, true);
+            mTvPipBoundsState.setTvPipExpanded(true);
+        }
+        return getTvPipBounds().getBounds();
     }
 
     /** Returns the current bounds adjusted to the new aspect ratio, if valid. */
     @Override
     public Rect getAdjustedDestinationBounds(Rect currentBounds, float newAspectRatio) {
-        if (DEBUG) Log.d(TAG, "getAdjustedDestinationBounds: " + newAspectRatio);
-        return getTvPipBounds(mTvPipBoundsState.isTvPipExpanded());
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: getAdjustedDestinationBounds: %f", TAG, newAspectRatio);
+        }
+        return getTvPipBounds().getBounds();
     }
 
     /**
-     * The normal bounds at a different position on the screen.
+     * Calculates the PiP bounds.
      */
-    public Rect getTvNormalBounds() {
-        Rect normalBounds = getNormalBounds();
-        Rect insetBounds = new Rect();
+    public Placement getTvPipBounds() {
+        final Size pipSize = getPipSize();
+        final Rect displayBounds = mTvPipBoundsState.getDisplayBounds();
+        final Size screenSize = new Size(displayBounds.width(), displayBounds.height());
+        final Rect insetBounds = new Rect();
         getInsetBounds(insetBounds);
 
+        Set<Rect> restrictedKeepClearAreas = mTvPipBoundsState.getRestrictedKeepClearAreas();
+        Set<Rect> unrestrictedKeepClearAreas = mTvPipBoundsState.getUnrestrictedKeepClearAreas();
+
         if (mTvPipBoundsState.isImeShowing()) {
-            if (DEBUG) Log.d(TAG, "IME showing, height: " + mTvPipBoundsState.getImeHeight());
-            insetBounds.bottom -= mTvPipBoundsState.getImeHeight();
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: IME showing, height: %d",
+                        TAG, mTvPipBoundsState.getImeHeight());
+            }
+
+            final Rect imeBounds = new Rect(
+                    0,
+                    insetBounds.bottom - mTvPipBoundsState.getImeHeight(),
+                    insetBounds.right,
+                    insetBounds.bottom);
+
+            unrestrictedKeepClearAreas = new ArraySet<>(unrestrictedKeepClearAreas);
+            unrestrictedKeepClearAreas.add(imeBounds);
         }
 
-        Rect result = new Rect();
-        Gravity.apply(mTvPipBoundsState.getTvPipGravity(), normalBounds.width(),
-                normalBounds.height(), insetBounds, result);
+        mKeepClearAlgorithm.setGravity(mTvPipBoundsState.getTvPipGravity());
+        mKeepClearAlgorithm.setScreenSize(screenSize);
+        mKeepClearAlgorithm.setMovementBounds(insetBounds);
+        mKeepClearAlgorithm.setStashOffset(mTvPipBoundsState.getStashOffset());
+
+        final Placement placement = mKeepClearAlgorithm.calculatePipPosition(
+                pipSize,
+                restrictedKeepClearAreas,
+                unrestrictedKeepClearAreas);
 
         if (DEBUG) {
-            Log.d(TAG, "normalBounds: " + normalBounds.toShortString());
-            Log.d(TAG, "insetBounds: " + insetBounds.toShortString());
-            Log.d(TAG, "gravity: " + Gravity.toString(mTvPipBoundsState.getTvPipGravity()));
-            Log.d(TAG, "resultBounds: " + result.toShortString());
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: screenSize: %s", TAG, screenSize);
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: stashOffset: %d", TAG, mTvPipBoundsState.getStashOffset());
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: insetBounds: %s", TAG, insetBounds.toShortString());
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: pipSize: %s", TAG, pipSize);
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: gravity: %s", TAG, Gravity.toString(mTvPipBoundsState.getTvPipGravity()));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: restrictedKeepClearAreas: %s", TAG, restrictedKeepClearAreas);
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: unrestrictedKeepClearAreas: %s", TAG, unrestrictedKeepClearAreas);
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: placement: %s", TAG, placement);
         }
 
-        mTvPipBoundsState.setTvPipExpanded(false);
-
-        return result;
+        return placement;
     }
 
     /**
-     * @return previous gravity if it is to be saved, or Gravity.NO_GRAVITY if not.
+     * @return previous gravity if it is to be saved, or {@link Gravity#NO_GRAVITY} if not.
      */
-    int updatePositionOnExpandToggled(int previousGravity, boolean expanding) {
+    int updateGravityOnExpandToggled(int previousGravity, boolean expanding) {
         if (DEBUG) {
-            Log.d(TAG, "updatePositionOnExpandToggle(), expanding: " + expanding
-                    + ", mOrientation: " + mTvPipBoundsState.getTvFixedPipOrientation()
-                    + ", previous gravity: " + Gravity.toString(previousGravity));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: updateGravityOnExpandToggled(), expanding: %b"
+                    + ", mOrientation: %d, previous gravity: %s",
+                    TAG, expanding, mTvPipBoundsState.getTvFixedPipOrientation(),
+                    Gravity.toString(previousGravity));
         }
 
-        if (!mTvPipBoundsState.isTvExpandedPipEnabled()) {
+        if (!mTvPipBoundsState.isTvExpandedPipSupported()) {
             return Gravity.NO_GRAVITY;
         }
 
         if (expanding && mTvPipBoundsState.getTvFixedPipOrientation() == ORIENTATION_UNDETERMINED) {
-            float expandedRatio = mTvPipBoundsState.getTvExpandedAspectRatio();
+            float expandedRatio = mTvPipBoundsState.getDesiredTvExpandedAspectRatio();
             if (expandedRatio == 0) {
                 return Gravity.NO_GRAVITY;
             }
@@ -139,7 +203,6 @@
             } else {
                 mTvPipBoundsState.setTvFixedPipOrientation(ORIENTATION_HORIZONTAL);
             }
-
         }
 
         int gravityToSave = Gravity.NO_GRAVITY;
@@ -175,16 +238,22 @@
             }
         }
         mTvPipBoundsState.setTvPipGravity(updatedGravity);
-        if (DEBUG) Log.d(TAG, "new gravity: " + Gravity.toString(updatedGravity));
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: new gravity: %s", TAG, Gravity.toString(updatedGravity));
+        }
 
         return gravityToSave;
     }
 
     /**
-     * @return true if position changed
+     * @return true if gravity changed
      */
-    boolean updatePosition(int keycode) {
-        if (DEBUG) Log.d(TAG, "updatePosition, keycode: " + keycode);
+    boolean updateGravity(int keycode) {
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: updateGravity, keycode: %d", TAG, keycode);
+        }
 
         // Check if position change is valid
         if (mTvPipBoundsState.isTvPipExpanded()) {
@@ -241,32 +310,42 @@
 
         if (updatedGravity != currentGravity) {
             mTvPipBoundsState.setTvPipGravity(updatedGravity);
-            if (DEBUG) Log.d(TAG, "new gravity: " + Gravity.toString(updatedGravity));
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: new gravity: %s", TAG, Gravity.toString(updatedGravity));
+            }
             return true;
         }
         return false;
     }
 
+    private Size getPipSize() {
+        final boolean isExpanded =
+                mTvPipBoundsState.isTvExpandedPipSupported() && mTvPipBoundsState.isTvPipExpanded()
+                        && mTvPipBoundsState.getDesiredTvExpandedAspectRatio() != 0;
+        if (isExpanded) {
+            return mTvPipBoundsState.getTvExpandedSize();
+        } else {
+            final Rect normalBounds = getNormalBounds();
+            return new Size(normalBounds.width(), normalBounds.height());
+        }
+    }
+
     /**
-     * Calculates the PiP bounds.
+     * Updates {@link TvPipBoundsState#getTvExpandedSize()} based on
+     * {@link TvPipBoundsState#getDesiredTvExpandedAspectRatio()}, the screen size.
      */
-    public Rect getTvPipBounds(boolean expandedIfPossible) {
-        if (DEBUG) {
-            Log.d(TAG, "getExpandedBoundsIfPossible with gravity "
-                    + Gravity.toString(mTvPipBoundsState.getTvPipGravity())
-                    + ", fixed orientation: " + mTvPipBoundsState.getTvFixedPipOrientation());
-        }
+    void updateExpandedPipSize() {
+        final DisplayLayout displayLayout = mTvPipBoundsState.getDisplayLayout();
+        final float expandedRatio =
+                mTvPipBoundsState.getDesiredTvExpandedAspectRatio(); // width / height
 
-        if (!mTvPipBoundsState.isTvExpandedPipEnabled() || !expandedIfPossible) {
-            return getTvNormalBounds();
-        }
-
-        DisplayLayout displayLayout = mTvPipBoundsState.getDisplayLayout();
-        float expandedRatio = mTvPipBoundsState.getTvExpandedAspectRatio(); // width / height
-        Size expandedSize;
+        final Size expandedSize;
         if (expandedRatio == 0) {
-            Log.d(TAG, "Expanded mode not supported");
-            return getTvNormalBounds();
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                       "%s: updateExpandedPipSize(): Expanded mode aspect ratio"
+                               + " of 0 not supported", TAG);
+            return;
         } else if (expandedRatio < 1) {
             // vertical
             if (mTvPipBoundsState.getTvFixedPipOrientation() == ORIENTATION_HORIZONTAL) {
@@ -276,10 +355,16 @@
                 float aspectRatioHeight = mFixedExpandedWidthInPx / expandedRatio;
 
                 if (maxHeight > aspectRatioHeight) {
-                    if (DEBUG) Log.d(TAG, "Accommodate aspect ratio");
+                    if (DEBUG) {
+                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: Accommodate aspect ratio", TAG);
+                    }
                     expandedSize = new Size(mFixedExpandedWidthInPx, (int) aspectRatioHeight);
                 } else {
-                    if (DEBUG) Log.d(TAG, "Aspect ratio is too extreme, use max size");
+                    if (DEBUG) {
+                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: Aspect ratio is too extreme, use max size", TAG);
+                    }
                     expandedSize = new Size(mFixedExpandedWidthInPx, maxHeight);
                 }
             }
@@ -291,35 +376,30 @@
                 int maxWidth = displayLayout.width() - (2 * mScreenEdgeInsets.x);
                 float aspectRatioWidth = mFixedExpandedHeightInPx * expandedRatio;
                 if (maxWidth > aspectRatioWidth) {
-                    if (DEBUG) Log.d(TAG, "Accommodate aspect ratio");
+                    if (DEBUG) {
+                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: Accommodate aspect ratio", TAG);
+                    }
                     expandedSize = new Size((int) aspectRatioWidth, mFixedExpandedHeightInPx);
                 } else {
-                    if (DEBUG) Log.d(TAG, "Aspect ratio is too extreme, use max size");
+                    if (DEBUG) {
+                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: Aspect ratio is too extreme, use max size", TAG);
+                    }
                     expandedSize = new Size(maxWidth, mFixedExpandedHeightInPx);
                 }
             }
         }
 
-        if (expandedSize == null) {
-            return getTvNormalBounds();
-        }
-
-        if (DEBUG) {
-            Log.d(TAG, "expanded size, width: " + expandedSize.getWidth()
-                    + ", height: " + expandedSize.getHeight());
-        }
-
-        Rect insetBounds = new Rect();
-        getInsetBounds(insetBounds);
-
-        Rect expandedBounds = new Rect();
-        Gravity.apply(mTvPipBoundsState.getTvPipGravity(), expandedSize.getWidth(),
-                expandedSize.getHeight(), insetBounds, expandedBounds);
-        if (DEBUG) Log.d(TAG, "expanded bounds: " + expandedBounds.toShortString());
-
         mTvPipBoundsState.setTvExpandedSize(expandedSize);
-        mTvPipBoundsState.setTvPipExpanded(true);
-        return expandedBounds;
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                       "%s: updateExpandedPipSize(): expanded size, width: %d, height: %d",
+                    TAG, expandedSize.getWidth(), expandedSize.getHeight());
+        }
     }
 
+    void keepUnstashedForCurrentKeepClearAreas() {
+        mKeepClearAlgorithm.keepUnstashedForCurrentKeepClearAreas();
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
index 9370e33..d880f82 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
@@ -53,10 +53,10 @@
 
     public static final int DEFAULT_TV_GRAVITY = Gravity.BOTTOM | Gravity.RIGHT;
 
-    private boolean mIsTvExpandedPipEnabled;
+    private final boolean mIsTvExpandedPipSupported;
     private boolean mIsTvPipExpanded;
     private boolean mTvPipManuallyCollapsed;
-    private float mTvExpandedAspectRatio;
+    private float mDesiredTvExpandedAspectRatio;
     private @Orientation int mTvFixedPipOrientation;
     private int mTvPipGravity;
     private @Nullable Size mTvExpandedSize;
@@ -64,8 +64,8 @@
 
     public TvPipBoundsState(@NonNull Context context) {
         super(context);
-        setIsTvExpandedPipEnabled(context.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_EXPANDED_PICTURE_IN_PICTURE));
+        mIsTvExpandedPipSupported = context.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_EXPANDED_PICTURE_IN_PICTURE);
     }
 
     /**
@@ -75,7 +75,7 @@
     public void setBoundsStateForEntry(ComponentName componentName, ActivityInfo activityInfo,
             PictureInPictureParams params, PipBoundsAlgorithm pipBoundsAlgorithm) {
         super.setBoundsStateForEntry(componentName, activityInfo, params, pipBoundsAlgorithm);
-        setTvExpandedAspectRatio(params.getExpandedAspectRatio(), true);
+        setDesiredTvExpandedAspectRatio(params.getExpandedAspectRatio(), true);
     }
 
     /** Resets the TV PiP state for a new activity. */
@@ -85,32 +85,32 @@
     }
 
     /** Set the tv expanded bounds of PIP */
-    public void setTvExpandedSize(@Nullable Size bounds) {
-        mTvExpandedSize = bounds;
+    public void setTvExpandedSize(@Nullable Size size) {
+        mTvExpandedSize = size;
     }
 
-    /** Get the PIP tv expanded bounds. */
+    /** Get the expanded size of the PiP. */
     @Nullable
     public Size getTvExpandedSize() {
         return mTvExpandedSize;
     }
 
     /** Set the PIP aspect ratio for the expanded PIP (TV) that is desired by the app. */
-    public void setTvExpandedAspectRatio(float aspectRatio, boolean override) {
+    public void setDesiredTvExpandedAspectRatio(float aspectRatio, boolean override) {
         if (override || mTvFixedPipOrientation == ORIENTATION_UNDETERMINED || aspectRatio == 0) {
-            mTvExpandedAspectRatio = aspectRatio;
+            mDesiredTvExpandedAspectRatio = aspectRatio;
             resetTvPipState();
             return;
         }
         if ((aspectRatio > 1 && mTvFixedPipOrientation == ORIENTATION_HORIZONTAL)
                 || (aspectRatio <= 1 && mTvFixedPipOrientation == ORIENTATION_VERTICAL)) {
-            mTvExpandedAspectRatio = aspectRatio;
+            mDesiredTvExpandedAspectRatio = aspectRatio;
         }
     }
 
     /** Get the PIP aspect ratio for the expanded PIP (TV) that is desired by the app. */
-    public float getTvExpandedAspectRatio() {
-        return mTvExpandedAspectRatio;
+    public float getDesiredTvExpandedAspectRatio() {
+        return mDesiredTvExpandedAspectRatio;
     }
 
     /** Sets the orientation the expanded TV PiP activity has been fixed to. */
@@ -154,13 +154,9 @@
         return mTvPipManuallyCollapsed;
     }
 
-    /** Sets whether expanded PiP is supported by the device. */
-    public void setIsTvExpandedPipEnabled(boolean enabled) {
-        mIsTvExpandedPipEnabled = enabled;
+    /** Returns whether expanded PiP is supported by the device. */
+    public boolean isTvExpandedPipSupported() {
+        return mIsTvExpandedPipSupported;
     }
 
-    /** Returns whether expanded PiP is supported by the device. */
-    public boolean isTvExpandedPipEnabled() {
-        return mIsTvExpandedPipEnabled;
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
index 3c830e0..f397ac0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
@@ -30,11 +30,11 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Rect;
+import android.os.Handler;
 import android.os.RemoteException;
-import android.util.Log;
-import android.view.DisplayInfo;
 import android.view.Gravity;
 
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.common.DisplayController;
@@ -45,9 +45,12 @@
 import com.android.wm.shell.pip.PinnedStackListenerForwarder;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.pip.PipAnimationController;
+import com.android.wm.shell.pip.PipBoundsState;
 import com.android.wm.shell.pip.PipMediaController;
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipTransitionController;
+import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -62,6 +65,7 @@
     private static final String TAG = "TvPipController";
     static final boolean DEBUG = false;
 
+    private static final double EPS = 1e-7;
     private static final int NONEXISTENT_TASK_ID = -1;
 
     @Retention(RetentionPolicy.SOURCE)
@@ -97,11 +101,13 @@
     private final TvPipNotificationController mPipNotificationController;
     private final TvPipMenuController mTvPipMenuController;
     private final ShellExecutor mMainExecutor;
+    private final Handler mMainHandler;
     private final TvPipImpl mImpl = new TvPipImpl();
 
     private @State int mState = STATE_NO_PIP;
     private int mPreviousGravity = TvPipBoundsState.DEFAULT_TV_GRAVITY;
     private int mPinnedTaskId = NONEXISTENT_TASK_ID;
+    private Runnable mUnstashRunnable;
 
     private int mResizeAnimationDuration;
 
@@ -117,7 +123,8 @@
             TaskStackListenerImpl taskStackListener,
             DisplayController displayController,
             WindowManagerShellWrapper wmShell,
-            ShellExecutor mainExecutor) {
+            ShellExecutor mainExecutor,
+            Handler mainHandler) {
         return new TvPipController(
                 context,
                 tvPipBoundsState,
@@ -130,7 +137,8 @@
                 taskStackListener,
                 displayController,
                 wmShell,
-                mainExecutor).mImpl;
+                mainExecutor,
+                mainHandler).mImpl;
     }
 
     private TvPipController(
@@ -145,9 +153,11 @@
             TaskStackListenerImpl taskStackListener,
             DisplayController displayController,
             WindowManagerShellWrapper wmShell,
-            ShellExecutor mainExecutor) {
+            ShellExecutor mainExecutor,
+            Handler mainHandler) {
         mContext = context;
         mMainExecutor = mainExecutor;
+        mMainHandler = mainHandler;
 
         mTvPipBoundsState = tvPipBoundsState;
         mTvPipBoundsState.setDisplayId(context.getDisplayId());
@@ -173,15 +183,22 @@
     }
 
     private void onConfigurationChanged(Configuration newConfig) {
-        if (DEBUG) Log.d(TAG, "onConfigurationChanged(), state=" + stateToName(mState));
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: onConfigurationChanged(), state=%s", TAG, stateToName(mState));
+        }
 
         if (isPipShown()) {
-            if (DEBUG) Log.d(TAG, "  > closing Pip.");
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s:  > closing Pip.", TAG);
+            }
             closePip();
         }
 
         loadConfigurations();
         mPipNotificationController.onConfigurationChanged(mContext);
+        mTvPipBoundsAlgorithm.onConfigurationChanged(mContext);
     }
 
     /**
@@ -198,21 +215,37 @@
      */
     @Override
     public void showPictureInPictureMenu() {
-        if (DEBUG) Log.d(TAG, "showPictureInPictureMenu(), state=" + stateToName(mState));
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: showPictureInPictureMenu(), state=%s", TAG, stateToName(mState));
+        }
 
         if (mState == STATE_NO_PIP) {
-            if (DEBUG) Log.d(TAG, "  > cannot open Menu from the current state.");
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s:  > cannot open Menu from the current state.", TAG);
+            }
             return;
         }
 
         setState(STATE_PIP_MENU);
-        movePinnedStack();
+        updatePinnedStackBounds();
     }
 
     @Override
     public void closeMenu() {
-        if (DEBUG) Log.d(TAG, "closeMenu(), state before=" + stateToName(mState));
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: closeMenu(), state before=%s", TAG, stateToName(mState));
+        }
         setState(STATE_PIP);
+        mTvPipBoundsAlgorithm.keepUnstashedForCurrentKeepClearAreas();
+        updatePinnedStackBounds();
+    }
+
+    @Override
+    public void onInMoveModeChanged() {
+        updatePinnedStackBounds();
     }
 
     /**
@@ -220,7 +253,10 @@
      */
     @Override
     public void movePipToFullscreen() {
-        if (DEBUG) Log.d(TAG, "movePipToFullscreen(), state=" + stateToName(mState));
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: movePipToFullscreen(), state=%s", TAG, stateToName(mState));
+        }
 
         mPipTaskOrganizer.exitPip(mResizeAnimationDuration, false /* requestEnterSplit */);
         onPipDisappeared();
@@ -228,26 +264,32 @@
 
     @Override
     public void togglePipExpansion() {
-        if (DEBUG) Log.d(TAG, "togglePipExpansion()");
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: togglePipExpansion()", TAG);
+        }
         boolean expanding = !mTvPipBoundsState.isTvPipExpanded();
         int saveGravity = mTvPipBoundsAlgorithm
-                .updatePositionOnExpandToggled(mPreviousGravity, expanding);
+                .updateGravityOnExpandToggled(mPreviousGravity, expanding);
         if (saveGravity != Gravity.NO_GRAVITY) {
             mPreviousGravity = saveGravity;
         }
         mTvPipBoundsState.setTvPipManuallyCollapsed(!expanding);
         mTvPipBoundsState.setTvPipExpanded(expanding);
-        movePinnedStack();
+        updatePinnedStackBounds();
     }
 
     @Override
     public void movePip(int keycode) {
-        if (mTvPipBoundsAlgorithm.updatePosition(keycode)) {
+        if (mTvPipBoundsAlgorithm.updateGravity(keycode)) {
             mTvPipMenuController.updateGravity(mTvPipBoundsState.getTvPipGravity());
             mPreviousGravity = Gravity.NO_GRAVITY;
-            movePinnedStack();
+            updatePinnedStackBounds();
         } else {
-            if (DEBUG) Log.d(TAG, "Position hasn't changed");
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: Position hasn't changed", TAG);
+            }
         }
     }
 
@@ -265,23 +307,57 @@
             Set<Rect> unrestricted) {
         if (mTvPipBoundsState.getDisplayId() == displayId) {
             mTvPipBoundsState.setKeepClearAreas(restricted, unrestricted);
-            movePinnedStack();
+            updatePinnedStackBounds();
         }
     }
 
     /**
-     * Animate to the updated position of the PiP based on the state and position of the PiP.
+     * Update the PiP bounds based on the state of the PiP and keep clear areas.
+     * Animates to the current PiP bounds, and schedules unstashing the PiP if necessary.
      */
-    private void movePinnedStack() {
+    private void updatePinnedStackBounds() {
         if (mState == STATE_NO_PIP) {
             return;
         }
 
-        Rect bounds = mTvPipBoundsAlgorithm.getTvPipBounds(mTvPipBoundsState.isTvPipExpanded());
-        if (DEBUG) Log.d(TAG, "movePinnedStack() - new pip bounds: " + bounds.toShortString());
+        final boolean stayAtAnchorPosition = mTvPipMenuController.isInMoveMode();
+        final boolean disallowStashing = mState == STATE_PIP_MENU || stayAtAnchorPosition;
+        final Placement placement = mTvPipBoundsAlgorithm.getTvPipBounds();
+
+        int stashType =
+                disallowStashing ? PipBoundsState.STASH_TYPE_NONE : placement.getStashType();
+        mTvPipBoundsState.setStashed(stashType);
+
+        if (stayAtAnchorPosition) {
+            movePinnedStackTo(placement.getAnchorBounds());
+        } else if (disallowStashing) {
+            movePinnedStackTo(placement.getUnstashedBounds());
+        } else {
+            movePinnedStackTo(placement.getBounds());
+        }
+
+        if (mUnstashRunnable != null) {
+            mMainHandler.removeCallbacks(mUnstashRunnable);
+            mUnstashRunnable = null;
+        }
+        if (!disallowStashing && placement.getUnstashDestinationBounds() != null) {
+            mUnstashRunnable = () -> movePinnedStackTo(placement.getUnstashDestinationBounds());
+            mMainHandler.postAtTime(mUnstashRunnable, placement.getUnstashTime());
+        }
+    }
+
+    /** Animates the PiP to the given bounds. */
+    private void movePinnedStackTo(Rect bounds) {
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: movePinnedStack() - new pip bounds: %s", TAG, bounds.toShortString());
+        }
         mPipTaskOrganizer.scheduleAnimateResizePip(bounds,
                 mResizeAnimationDuration, rect -> {
-                    if (DEBUG) Log.d(TAG, "movePinnedStack() animation done");
+                    if (DEBUG) {
+                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: movePinnedStack() animation done", TAG);
+                    }
                     mTvPipMenuController.updateExpansionState();
                 });
     }
@@ -291,7 +367,10 @@
      */
     @Override
     public void closePip() {
-        if (DEBUG) Log.d(TAG, "closePip(), state=" + stateToName(mState));
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: closePip(), state=%s", TAG, stateToName(mState));
+        }
 
         removeTask(mPinnedTaskId);
         onPipDisappeared();
@@ -303,7 +382,10 @@
 
     private void checkIfPinnedTaskAppeared() {
         final TaskInfo pinnedTask = getPinnedTaskInfo();
-        if (DEBUG) Log.d(TAG, "checkIfPinnedTaskAppeared(), task=" + pinnedTask);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: checkIfPinnedTaskAppeared(), task=%s", TAG, pinnedTask);
+        }
         if (pinnedTask == null || pinnedTask.topActivity == null) return;
         mPinnedTaskId = pinnedTask.taskId;
 
@@ -312,16 +394,23 @@
     }
 
     private void checkIfPinnedTaskIsGone() {
-        if (DEBUG) Log.d(TAG, "onTaskStackChanged()");
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: onTaskStackChanged()", TAG);
+        }
 
         if (isPipShown() && getPinnedTaskInfo() == null) {
-            Log.w(TAG, "Pinned task is gone.");
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Pinned task is gone.", TAG);
             onPipDisappeared();
         }
     }
 
     private void onPipDisappeared() {
-        if (DEBUG) Log.d(TAG, "onPipDisappeared() state=" + stateToName(mState));
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: onPipDisappeared() state=%s", TAG, stateToName(mState));
+        }
 
         mPipNotificationController.dismiss();
         mTvPipMenuController.hideMenu();
@@ -332,12 +421,18 @@
 
     @Override
     public void onPipTransitionStarted(int direction, Rect pipBounds) {
-        if (DEBUG) Log.d(TAG, "onPipTransition_Started(), state=" + stateToName(mState));
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: onPipTransition_Started(), state=%s", TAG, stateToName(mState));
+        }
     }
 
     @Override
     public void onPipTransitionCanceled(int direction) {
-        if (DEBUG) Log.d(TAG, "onPipTransition_Canceled(), state=" + stateToName(mState));
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: onPipTransition_Canceled(), state=%s", TAG, stateToName(mState));
+        }
     }
 
     @Override
@@ -345,20 +440,29 @@
         if (PipAnimationController.isInPipDirection(direction) && mState == STATE_NO_PIP) {
             setState(STATE_PIP);
         }
-        if (DEBUG) Log.d(TAG, "onPipTransition_Finished(), state=" + stateToName(mState));
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: onPipTransition_Finished(), state=%s", TAG, stateToName(mState));
+        }
     }
 
     private void setState(@State int state) {
         if (DEBUG) {
-            Log.d(TAG, "setState(), state=" + stateToName(state) + ", prev="
-                    + stateToName(mState));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: setState(), state=%s, prev=%s",
+                    TAG, stateToName(state), stateToName(mState));
         }
         mState = state;
 
         if (mState == STATE_PIP_MENU) {
-            if (DEBUG) Log.d(TAG, "  > show menu");
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s:  > show menu", TAG);
+            }
             mTvPipMenuController.showMenu();
         }
+
+        updatePinnedStackBounds();
     }
 
     private void loadConfigurations() {
@@ -366,12 +470,6 @@
         mResizeAnimationDuration = res.getInteger(R.integer.config_pipResizeAnimationDuration);
     }
 
-    private DisplayInfo getDisplayInfo() {
-        final DisplayInfo displayInfo = new DisplayInfo();
-        mContext.getDisplay().getDisplayInfo(displayInfo);
-        return displayInfo;
-    }
-
     private void registerTaskStackListenerCallback(TaskStackListenerImpl taskStackListener) {
         taskStackListener.addListener(new TaskStackListenerCallback() {
             @Override
@@ -388,7 +486,10 @@
             public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
                     boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
                 if (task.getWindowingMode() == WINDOWING_MODE_PINNED) {
-                    if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()");
+                    if (DEBUG) {
+                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: onPinnedActivityRestartAttempt()", TAG);
+                    }
 
                     // If the "Pip-ed" Activity is launched again by Launcher or intent, make it
                     // fullscreen.
@@ -404,8 +505,9 @@
                 @Override
                 public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
                     if (DEBUG) {
-                        Log.d(TAG, "onImeVisibilityChanged(), visible=" + imeVisible
-                                + ", height=" + imeHeight);
+                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: onImeVisibilityChanged(), visible=%b, height=%d",
+                                TAG, imeVisible, imeHeight);
                     }
 
                     if (imeVisible == mTvPipBoundsState.isImeShowing()
@@ -417,62 +519,72 @@
                     mTvPipBoundsState.setImeVisibility(imeVisible, imeHeight);
 
                     if (mState != STATE_NO_PIP) {
-                        movePinnedStack();
+                        updatePinnedStackBounds();
                     }
                 }
 
                 @Override
                 public void onAspectRatioChanged(float ratio) {
-                    if (DEBUG) Log.d(TAG, "onAspectRatioChanged: " + ratio);
+                    if (DEBUG) {
+                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: onAspectRatioChanged: %f", TAG, ratio);
+                    }
 
                     boolean ratioChanged = mTvPipBoundsState.getAspectRatio() != ratio;
                     mTvPipBoundsState.setAspectRatio(ratio);
 
                     if (!mTvPipBoundsState.isTvPipExpanded() && ratioChanged) {
-                        movePinnedStack();
+                        updatePinnedStackBounds();
                     }
                 }
 
                 @Override
                 public void onExpandedAspectRatioChanged(float ratio) {
-                    if (DEBUG) Log.d(TAG, "onExpandedAspectRatioChanged: " + ratio);
+                    if (DEBUG) {
+                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: onExpandedAspectRatioChanged: %f", TAG, ratio);
+                    }
 
                     // 0) No update to the ratio --> don't do anything
-                    if (mTvPipBoundsState.getTvExpandedAspectRatio() == ratio) {
+
+                    if (Math.abs(mTvPipBoundsState.getDesiredTvExpandedAspectRatio() - ratio)
+                            < EPS) {
                         return;
                     }
 
-                    mTvPipBoundsState.setTvExpandedAspectRatio(ratio, false);
+                    mTvPipBoundsState.setDesiredTvExpandedAspectRatio(ratio, false);
 
                     // 1) PiP is expanded and only aspect ratio changed, but wasn't disabled
                     // --> update bounds, but don't toggle
                     if (mTvPipBoundsState.isTvPipExpanded() && ratio != 0) {
-                        movePinnedStack();
+                        mTvPipBoundsAlgorithm.updateExpandedPipSize();
+                        updatePinnedStackBounds();
                     }
 
                     // 2) PiP is expanded, but expanded PiP was disabled
                     // --> collapse PiP
                     if (mTvPipBoundsState.isTvPipExpanded() && ratio == 0) {
                         int saveGravity = mTvPipBoundsAlgorithm
-                                .updatePositionOnExpandToggled(mPreviousGravity, false);
+                                .updateGravityOnExpandToggled(mPreviousGravity, false);
                         if (saveGravity != Gravity.NO_GRAVITY) {
                             mPreviousGravity = saveGravity;
                         }
                         mTvPipBoundsState.setTvPipExpanded(false);
-                        movePinnedStack();
+                        updatePinnedStackBounds();
                     }
 
                     // 3) PiP not expanded and not manually collapsed and expand was enabled
                     // --> expand to new ratio
                     if (!mTvPipBoundsState.isTvPipExpanded() && ratio != 0
                             && !mTvPipBoundsState.isTvPipManuallyCollapsed()) {
+                        mTvPipBoundsAlgorithm.updateExpandedPipSize();
                         int saveGravity = mTvPipBoundsAlgorithm
-                                .updatePositionOnExpandToggled(mPreviousGravity, true);
+                                .updateGravityOnExpandToggled(mPreviousGravity, true);
                         if (saveGravity != Gravity.NO_GRAVITY) {
                             mPreviousGravity = saveGravity;
                         }
                         mTvPipBoundsState.setTvPipExpanded(true);
-                        movePinnedStack();
+                        updatePinnedStackBounds();
                     }
                 }
 
@@ -481,35 +593,50 @@
 
                 @Override
                 public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
-                    if (DEBUG) Log.d(TAG, "onActionsChanged()");
+                    if (DEBUG) {
+                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: onActionsChanged()", TAG);
+                    }
 
                     mTvPipMenuController.setAppActions(actions);
                 }
             });
         } catch (RemoteException e) {
-            Log.e(TAG, "Failed to register pinned stack listener", e);
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Failed to register pinned stack listener, %s", TAG, e);
         }
     }
 
     private static TaskInfo getPinnedTaskInfo() {
-        if (DEBUG) Log.d(TAG, "getPinnedTaskInfo()");
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: getPinnedTaskInfo()", TAG);
+        }
         try {
             final TaskInfo taskInfo = ActivityTaskManager.getService().getRootTaskInfo(
                     WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
-            if (DEBUG) Log.d(TAG, "  > taskInfo=" + taskInfo);
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s:   > taskInfo=%s", TAG, taskInfo);
+            }
             return taskInfo;
         } catch (RemoteException e) {
-            Log.e(TAG, "getRootTaskInfo() failed", e);
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: getRootTaskInfo() failed, %s", TAG, e);
             return null;
         }
     }
 
     private static void removeTask(int taskId) {
-        if (DEBUG) Log.d(TAG, "removeTask(), taskId=" + taskId);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: removeTask(), taskId=%d", TAG, taskId);
+        }
         try {
             ActivityTaskManager.getService().removeTask(taskId);
         } catch (Exception e) {
-            Log.e(TAG, "Atm.removeTask() failed", e);
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Atm.removeTask() failed, %s", TAG, e);
         }
     }
 
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
new file mode 100644
index 0000000..5ac7a72
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
@@ -0,0 +1,741 @@
+/*
+ * 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.wm.shell.pip.tv
+
+import android.graphics.Point
+import android.graphics.Rect
+import android.util.Size
+import android.view.Gravity
+import com.android.wm.shell.pip.PipBoundsState
+import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_BOTTOM
+import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_LEFT
+import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE
+import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT
+import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_TOP
+import kotlin.math.abs
+import kotlin.math.max
+import kotlin.math.min
+import kotlin.math.roundToInt
+
+private const val DEFAULT_PIP_MARGINS = 48
+private const val DEFAULT_STASH_DURATION = 5000L
+private const val RELAX_DEPTH = 1
+private const val DEFAULT_MAX_RESTRICTED_DISTANCE_FRACTION = 0.15
+
+/**
+ * This class calculates an appropriate position for a Picture-In-Picture (PiP) window, taking
+ * into account app defined keep clear areas.
+ *
+ * @param clock A function returning a current timestamp (in milliseconds)
+ */
+class TvPipKeepClearAlgorithm(private val clock: () -> Long) {
+    /**
+     * Result of the positioning algorithm.
+     *
+     * @param bounds The bounds the PiP should be placed at
+     * @param anchorBounds The bounds of the PiP anchor position
+     *     (where the PiP would be placed if there were no keep clear areas)
+     * @param stashType Where the PiP has been stashed, if at all
+     * @param unstashDestinationBounds If stashed, the PiP should move to this position after
+     *     [stashDuration] has passed.
+     * @param unstashTime If stashed, the time at which the PiP should move
+     *     to [unstashDestinationBounds]
+     */
+    data class Placement(
+        val bounds: Rect,
+        val anchorBounds: Rect,
+        @PipBoundsState.StashType val stashType: Int = STASH_TYPE_NONE,
+        val unstashDestinationBounds: Rect? = null,
+        val unstashTime: Long = 0L
+    ) {
+        /** Bounds to use if the PiP should not be stashed. */
+        fun getUnstashedBounds() = unstashDestinationBounds ?: bounds
+    }
+
+    /**  The size of the screen */
+    private var screenSize = Size(0, 0)
+
+    /** The bounds the PiP is allowed to move in */
+    private var movementBounds = Rect()
+
+    /** Padding to add between a keep clear area that caused the PiP to move and the PiP */
+    var pipAreaPadding = DEFAULT_PIP_MARGINS
+
+    /** The distance the PiP peeks into the screen when stashed */
+    var stashOffset = DEFAULT_PIP_MARGINS
+
+    /**
+     * How long (in milliseconds) the PiP should stay stashed for after the last time the
+     * keep clear areas causing the PiP to stash have changed.
+     */
+    var stashDuration = DEFAULT_STASH_DURATION
+
+    /** The fraction of screen width/height restricted keep clear areas can move the PiP */
+    var maxRestrictedDistanceFraction = DEFAULT_MAX_RESTRICTED_DISTANCE_FRACTION
+
+    private var pipGravity = Gravity.BOTTOM or Gravity.RIGHT
+    private var transformedScreenBounds = Rect()
+    private var transformedMovementBounds = Rect()
+
+    private var lastAreasOverlappingUnstashPosition: Set<Rect> = emptySet()
+    private var lastStashTime: Long = Long.MIN_VALUE
+
+    /**
+     * Calculates the position the PiP should be placed at, taking into consideration the
+     * given keep clear areas.
+     *
+     * Restricted keep clear areas can move the PiP only by a limited amount, and may be ignored
+     * if there is no space for the PiP to move to.
+     * Apps holding the permission [android.Manifest.permission.USE_UNRESTRICTED_KEEP_CLEAR_AREAS]
+     * can declare unrestricted keep clear areas, which can move the PiP farther and placement will
+     * always try to respect these areas.
+     *
+     * If no free space the PiP is allowed to move to can be found, a stashed position is returned
+     * as [Placement.bounds], along with a position to move to once [Placement.unstashTime] has
+     * passed as [Placement.unstashDestinationBounds].
+     *
+     * @param pipSize The size of the PiP window
+     * @param restrictedAreas The restricted keep clear areas
+     * @param unrestrictedAreas The unrestricted keep clear areas
+     *
+     */
+    fun calculatePipPosition(
+        pipSize: Size,
+        restrictedAreas: Set<Rect>,
+        unrestrictedAreas: Set<Rect>
+    ): Placement {
+        val transformedRestrictedAreas = transformAndFilterAreas(restrictedAreas)
+        val transformedUnrestrictedAreas = transformAndFilterAreas(unrestrictedAreas)
+        val pipAnchorBounds = getNormalPipAnchorBounds(pipSize, transformedMovementBounds)
+
+        val result = calculatePipPositionTransformed(
+            pipAnchorBounds,
+            transformedRestrictedAreas,
+            transformedUnrestrictedAreas
+        )
+
+        val screenSpaceBounds = fromTransformedSpace(result.bounds)
+        return Placement(
+            screenSpaceBounds,
+            fromTransformedSpace(result.anchorBounds),
+            getStashType(screenSpaceBounds, movementBounds),
+            result.unstashDestinationBounds?.let { fromTransformedSpace(it) },
+            result.unstashTime
+        )
+    }
+
+    /**
+     * Filters out areas that encompass the entire movement bounds and returns them mapped to
+     * the base case space.
+     *
+     * Areas encompassing the entire movement bounds can occur when a full-screen View gets focused,
+     * but we don't want this to cause the PiP to get stashed.
+     */
+    private fun transformAndFilterAreas(areas: Set<Rect>): Set<Rect> {
+        return areas.mapNotNullTo(mutableSetOf()) {
+            when {
+                it.contains(movementBounds) -> null
+                else -> toTransformedSpace(it)
+            }
+        }
+    }
+
+    /**
+     * Calculates the position the PiP should be placed at, taking into consideration the
+     * given keep clear areas.
+     * All parameters are transformed from screen space to the base case space, where the PiP
+     * anchor is in the bottom right corner / on the right side.
+     *
+     * @see [calculatePipPosition]
+     */
+    private fun calculatePipPositionTransformed(
+        pipAnchorBounds: Rect,
+        restrictedAreas: Set<Rect>,
+        unrestrictedAreas: Set<Rect>
+    ): Placement {
+        if (restrictedAreas.isEmpty() && unrestrictedAreas.isEmpty()) {
+            return Placement(pipAnchorBounds, pipAnchorBounds)
+        }
+
+        // First try to find a free position to move to
+        val freeMovePos = findFreeMovePosition(pipAnchorBounds, restrictedAreas, unrestrictedAreas)
+        if (freeMovePos != null) {
+            lastAreasOverlappingUnstashPosition = emptySet()
+            return Placement(freeMovePos, pipAnchorBounds)
+        }
+
+        // If no free position is found, we have to stash the PiP.
+        // Find the position the PiP should return to once it unstashes by doing a relaxed
+        // search, or ignoring restricted areas, or returning to the anchor position
+        val unstashBounds =
+            findRelaxedMovePosition(pipAnchorBounds, restrictedAreas, unrestrictedAreas)
+                ?: findFreeMovePosition(pipAnchorBounds, emptySet(), unrestrictedAreas)
+                ?: pipAnchorBounds
+
+        val keepClearAreas = restrictedAreas + unrestrictedAreas
+        val areasOverlappingUnstashPosition =
+            keepClearAreas.filter { Rect.intersects(it, unstashBounds) }.toSet()
+        val areasOverlappingUnstashPositionChanged =
+            !lastAreasOverlappingUnstashPosition.containsAll(areasOverlappingUnstashPosition)
+        lastAreasOverlappingUnstashPosition = areasOverlappingUnstashPosition
+
+        val now = clock()
+        if (areasOverlappingUnstashPositionChanged) {
+            lastStashTime = now
+        }
+
+        // If overlapping areas haven't changed and the stash duration has passed, we can
+        // place the PiP at the unstash position
+        val unstashTime = lastStashTime + stashDuration
+        if (now >= unstashTime) {
+            return Placement(unstashBounds, pipAnchorBounds)
+        }
+
+        // Otherwise, we'll stash it close to the unstash position
+        val stashedBounds = getNearbyStashedPosition(unstashBounds, keepClearAreas)
+        return Placement(
+            stashedBounds,
+            pipAnchorBounds,
+            getStashType(stashedBounds, transformedMovementBounds),
+            unstashBounds,
+            unstashTime
+        )
+    }
+
+    @PipBoundsState.StashType
+    private fun getStashType(stashedBounds: Rect, movementBounds: Rect): Int {
+        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
+            else -> STASH_TYPE_NONE
+        }
+    }
+
+    private fun findRelaxedMovePosition(
+        pipAnchorBounds: Rect,
+        restrictedAreas: Set<Rect>,
+        unrestrictedAreas: Set<Rect>
+    ): Rect? {
+        if (RELAX_DEPTH <= 0) {
+            // relaxed search disabled
+            return null
+        }
+
+        return findRelaxedMovePosition(
+            RELAX_DEPTH,
+            pipAnchorBounds,
+            restrictedAreas.toMutableSet(),
+            unrestrictedAreas
+        )
+    }
+
+    private fun findRelaxedMovePosition(
+        depth: Int,
+        pipAnchorBounds: Rect,
+        restrictedAreas: MutableSet<Rect>,
+        unrestrictedAreas: Set<Rect>
+    ): Rect? {
+        if (depth == 0) {
+            return findFreeMovePosition(pipAnchorBounds, restrictedAreas, unrestrictedAreas)
+        }
+
+        val candidates = mutableListOf<Rect>()
+        val areasToExclude = restrictedAreas.toList()
+        for (area in areasToExclude) {
+            restrictedAreas.remove(area)
+            val candidate = findRelaxedMovePosition(
+                depth - 1,
+                pipAnchorBounds,
+                restrictedAreas,
+                unrestrictedAreas
+            )
+            restrictedAreas.add(area)
+
+            if (candidate != null) {
+                candidates.add(candidate)
+            }
+        }
+        return candidates.minByOrNull { candidateCost(it, pipAnchorBounds) }
+    }
+
+    /** Cost function to evaluate candidate bounds */
+    private fun candidateCost(candidateBounds: Rect, pipAnchorBounds: Rect): Int {
+        // squared euclidean distance of corresponding rect corners
+        val dx = candidateBounds.left - pipAnchorBounds.left
+        val dy = candidateBounds.top - pipAnchorBounds.top
+        return dx * dx + dy * dy
+    }
+
+    private fun findFreeMovePosition(
+        pipAnchorBounds: Rect,
+        restrictedAreas: Set<Rect>,
+        unrestrictedAreas: Set<Rect>
+    ): Rect? {
+        val movementBounds = transformedMovementBounds
+        val candidateEdgeRects = mutableListOf<Rect>()
+        val minRestrictedLeft =
+            pipAnchorBounds.right - screenSize.width * maxRestrictedDistanceFraction
+
+        candidateEdgeRects.add(
+            movementBounds.offsetCopy(movementBounds.width() + pipAreaPadding, 0)
+        )
+        candidateEdgeRects.addAll(unrestrictedAreas)
+        candidateEdgeRects.addAll(restrictedAreas.filter { it.left >= minRestrictedLeft })
+
+        // throw out edges that are too close to the left screen edge to fit the PiP
+        val minLeft = movementBounds.left + pipAnchorBounds.width()
+        candidateEdgeRects.retainAll { it.left - pipAreaPadding > minLeft }
+        candidateEdgeRects.sortBy { -it.left }
+
+        val maxRestrictedDY = (screenSize.height * maxRestrictedDistanceFraction).roundToInt()
+
+        val candidateBounds = mutableListOf<Rect>()
+        for (edgeRect in candidateEdgeRects) {
+            val edge = edgeRect.left - pipAreaPadding
+            val dx = (edge - pipAnchorBounds.width()) - pipAnchorBounds.left
+            val candidatePipBounds = pipAnchorBounds.offsetCopy(dx, 0)
+            val searchUp = true
+            val searchDown = !isPipAnchoredToCorner()
+
+            if (searchUp) {
+                val event = findMinMoveUp(candidatePipBounds, restrictedAreas, unrestrictedAreas)
+                val padding = if (event.start) 0 else pipAreaPadding
+                val dy = event.pos - pipAnchorBounds.bottom - padding
+                val maxDY = if (event.unrestricted) movementBounds.height() else maxRestrictedDY
+                val candidate = pipAnchorBounds.offsetCopy(dx, dy)
+                val isOnScreen = candidate.top > movementBounds.top
+                val hangingMidAir = !candidate.intersectsY(edgeRect)
+                if (isOnScreen && abs(dy) <= maxDY && !hangingMidAir) {
+                    candidateBounds.add(candidate)
+                }
+            }
+
+            if (searchDown) {
+                val event = findMinMoveDown(candidatePipBounds, restrictedAreas, unrestrictedAreas)
+                val padding = if (event.start) 0 else pipAreaPadding
+                val dy = event.pos - pipAnchorBounds.top + padding
+                val maxDY = if (event.unrestricted) movementBounds.height() else maxRestrictedDY
+                val candidate = pipAnchorBounds.offsetCopy(dx, dy)
+                val isOnScreen = candidate.bottom < movementBounds.bottom
+                val hangingMidAir = !candidate.intersectsY(edgeRect)
+                if (isOnScreen && abs(dy) <= maxDY && !hangingMidAir) {
+                    candidateBounds.add(candidate)
+                }
+            }
+        }
+
+        candidateBounds.sortBy { candidateCost(it, pipAnchorBounds) }
+        return candidateBounds.firstOrNull()
+    }
+
+    private fun getNearbyStashedPosition(bounds: Rect, keepClearAreas: Set<Rect>): Rect {
+        val screenBounds = transformedScreenBounds
+        val stashCandidates = Array(2) { Rect(bounds) }
+        val areasOverlappingPipX = keepClearAreas.filter { it.intersectsX(bounds) }
+        val areasOverlappingPipY = keepClearAreas.filter { it.intersectsY(bounds) }
+
+        if (screenBounds.bottom - bounds.bottom <= bounds.top - screenBounds.top) {
+            // bottom is closer than top, stash downwards
+            val fullStashTop = screenBounds.bottom - stashOffset
+
+            val maxBottom = areasOverlappingPipX.maxByOrNull { it.bottom }!!.bottom
+            val partialStashTop = maxBottom + pipAreaPadding
+
+            val downPosition = stashCandidates[0]
+            downPosition.offsetTo(bounds.left, min(fullStashTop, partialStashTop))
+        } else {
+            // top is closer than bottom, stash upwards
+            val fullStashY = screenBounds.top - bounds.height() + stashOffset
+
+            val minTop = areasOverlappingPipX.minByOrNull { it.top }!!.top
+            val partialStashY = minTop - bounds.height() - pipAreaPadding
+
+            val upPosition = stashCandidates[0]
+            upPosition.offsetTo(bounds.left, max(fullStashY, partialStashY))
+        }
+
+        if (screenBounds.right - bounds.right <= bounds.left - screenBounds.left) {
+            // right is closer than left, stash rightwards
+            val fullStashLeft = screenBounds.right - stashOffset
+
+            val maxRight = areasOverlappingPipY.maxByOrNull { it.right }!!.right
+            val partialStashLeft = maxRight + pipAreaPadding
+
+            val rightPosition = stashCandidates[1]
+            rightPosition.offsetTo(min(fullStashLeft, partialStashLeft), bounds.top)
+        } else {
+            // left is closer than right, stash leftwards
+            val fullStashLeft = screenBounds.left - bounds.width() + stashOffset
+
+            val minLeft = areasOverlappingPipY.minByOrNull { it.left }!!.left
+            val partialStashLeft = minLeft - bounds.width() - pipAreaPadding
+
+            val rightPosition = stashCandidates[1]
+            rightPosition.offsetTo(max(fullStashLeft, partialStashLeft), bounds.top)
+        }
+
+        return stashCandidates.minByOrNull {
+            val dx = abs(it.left - bounds.left)
+            val dy = abs(it.top - bounds.top)
+            dx * bounds.height() + dy * bounds.width()
+        }!!
+    }
+
+    /**
+     * Prevents the PiP from being stashed for the current set of keep clear areas.
+     * The PiP may stash again if keep clear areas change.
+     */
+    fun keepUnstashedForCurrentKeepClearAreas() {
+        lastStashTime = Long.MIN_VALUE
+    }
+
+    /**
+     * Updates the size of the screen.
+     *
+     * @param size The new size of the screen
+     */
+    fun setScreenSize(size: Size) {
+        if (screenSize == size) {
+            return
+        }
+
+        screenSize = size
+        transformedScreenBounds =
+            toTransformedSpace(Rect(0, 0, screenSize.width, screenSize.height))
+        transformedMovementBounds = toTransformedSpace(transformedMovementBounds)
+    }
+
+    /**
+     * Updates the bounds within which the PiP is allowed to move.
+     *
+     * @param bounds The new movement bounds
+     */
+    fun setMovementBounds(bounds: Rect) {
+        if (movementBounds == bounds) {
+            return
+        }
+
+        movementBounds.set(bounds)
+        transformedMovementBounds = toTransformedSpace(movementBounds)
+    }
+
+    /**
+     * Sets the corner/side of the PiP's home position.
+     */
+    fun setGravity(gravity: Int) {
+        if (pipGravity == gravity) return
+
+        pipGravity = gravity
+        transformedScreenBounds =
+            toTransformedSpace(Rect(0, 0, screenSize.width, screenSize.height))
+        transformedMovementBounds = toTransformedSpace(movementBounds)
+    }
+
+    /**
+     * @param open Whether this event marks the opening of an occupied segment
+     * @param pos The coordinate of this event
+     * @param unrestricted Whether this event was generated by an unrestricted keep clear area
+     * @param start Marks the special start event. Earlier events are skipped when sweeping
+     */
+    data class SweepLineEvent(
+        val open: Boolean,
+        val pos: Int,
+        val unrestricted: Boolean,
+        val start: Boolean = false
+    )
+
+    /**
+     * Returns a [SweepLineEvent] representing the minimal move up from [pipBounds] that clears
+     * the given keep clear areas.
+     */
+    private fun findMinMoveUp(
+        pipBounds: Rect,
+        restrictedAreas: Set<Rect>,
+        unrestrictedAreas: Set<Rect>
+    ): SweepLineEvent {
+        val events = mutableListOf<SweepLineEvent>()
+        val generateEvents: (Boolean) -> (Rect) -> Unit = { unrestricted ->
+            { area ->
+                if (pipBounds.intersectsX(area)) {
+                    events.add(SweepLineEvent(true, area.bottom, unrestricted))
+                    events.add(SweepLineEvent(false, area.top, unrestricted))
+                }
+            }
+        }
+
+        restrictedAreas.forEach(generateEvents(false))
+        unrestrictedAreas.forEach(generateEvents(true))
+
+        return sweepLineFindEarliestGap(
+            events,
+            pipBounds.height() + pipAreaPadding,
+            pipBounds.bottom,
+            pipBounds.height()
+        )
+    }
+
+    /**
+     * Returns a [SweepLineEvent] representing the minimal move down from [pipBounds] that clears
+     * the given keep clear areas.
+     */
+    private fun findMinMoveDown(
+        pipBounds: Rect,
+        restrictedAreas: Set<Rect>,
+        unrestrictedAreas: Set<Rect>
+    ): SweepLineEvent {
+        val events = mutableListOf<SweepLineEvent>()
+        val generateEvents: (Boolean) -> (Rect) -> Unit = { unrestricted ->
+            { area ->
+                if (pipBounds.intersectsX(area)) {
+                    events.add(SweepLineEvent(true, -area.top, unrestricted))
+                    events.add(SweepLineEvent(false, -area.bottom, unrestricted))
+                }
+            }
+        }
+
+        restrictedAreas.forEach(generateEvents(false))
+        unrestrictedAreas.forEach(generateEvents(true))
+
+        val earliestEvent = sweepLineFindEarliestGap(
+            events,
+            pipBounds.height() + pipAreaPadding,
+            -pipBounds.top,
+            pipBounds.height()
+        )
+
+        return earliestEvent.copy(pos = -earliestEvent.pos)
+    }
+
+    /**
+     * Takes a list of events representing the starts & ends of occupied segments, and
+     * returns the earliest event whose position is unoccupied and has [gapSize] distance to the
+     * next event.
+     *
+     * @param events List of [SweepLineEvent] representing occupied segments
+     * @param gapSize Size of the gap to search for
+     * @param startPos The position to start the search on.
+     *     Inserts a special event marked with [SweepLineEvent.start].
+     * @param startGapSize Used instead of [gapSize] for the start event
+     */
+    private fun sweepLineFindEarliestGap(
+        events: MutableList<SweepLineEvent>,
+        gapSize: Int,
+        startPos: Int,
+        startGapSize: Int
+    ): SweepLineEvent {
+        events.add(
+            SweepLineEvent(
+                open = false,
+                pos = startPos,
+                unrestricted = true,
+                start = true
+            )
+        )
+        events.sortBy { -it.pos }
+
+        // sweep
+        var openCount = 0
+        var i = 0
+        while (i < events.size) {
+            val event = events[i]
+            if (!event.start) {
+                if (event.open) {
+                    openCount++
+                } else {
+                    openCount--
+                }
+            }
+
+            if (openCount == 0) {
+                // check if placement is possible
+                val candidate = event.pos
+                if (candidate > startPos) {
+                    i++
+                    continue
+                }
+
+                val eventGapSize = if (event.start) startGapSize else gapSize
+                val nextEvent = events.getOrNull(i + 1)
+                if (nextEvent == null || nextEvent.pos < candidate - eventGapSize) {
+                    return event
+                }
+            }
+            i++
+        }
+
+        return events.last()
+    }
+
+    private fun shouldTransformFlipX(): Boolean {
+        return when (pipGravity) {
+            (Gravity.TOP), (Gravity.TOP or Gravity.CENTER_HORIZONTAL) -> true
+            (Gravity.TOP or Gravity.LEFT) -> true
+            (Gravity.LEFT), (Gravity.LEFT or Gravity.CENTER_VERTICAL) -> true
+            (Gravity.BOTTOM or Gravity.LEFT) -> true
+            else -> false
+        }
+    }
+
+    private fun shouldTransformFlipY(): Boolean {
+        return when (pipGravity) {
+            (Gravity.TOP or Gravity.LEFT) -> true
+            (Gravity.TOP or Gravity.RIGHT) -> true
+            else -> false
+        }
+    }
+
+    private fun shouldTransformRotate(): Boolean {
+        val horizontalGravity = pipGravity and Gravity.HORIZONTAL_GRAVITY_MASK
+        val leftOrRight = horizontalGravity == Gravity.LEFT || horizontalGravity == Gravity.RIGHT
+
+        if (leftOrRight) return false
+        return when (pipGravity and Gravity.VERTICAL_GRAVITY_MASK) {
+            (Gravity.TOP) -> true
+            (Gravity.BOTTOM) -> true
+            else -> false
+        }
+    }
+
+    /**
+     * Transforms the given rect from screen space into the base case space, where the PiP
+     * anchor is positioned in the bottom right corner or on the right side (for expanded PiP).
+     *
+     * @see [fromTransformedSpace]
+     */
+    private fun toTransformedSpace(r: Rect): Rect {
+        var screenWidth = screenSize.width
+        var screenHeight = screenSize.height
+
+        val tl = Point(r.left, r.top)
+        val tr = Point(r.right, r.top)
+        val br = Point(r.right, r.bottom)
+        val bl = Point(r.left, r.bottom)
+        val corners = arrayOf(tl, tr, br, bl)
+
+        // rotate first (CW)
+        if (shouldTransformRotate()) {
+            corners.forEach { p ->
+                val px = p.x
+                val py = p.y
+                p.x = py
+                p.y = -px
+                p.y += screenWidth // shift back screen into positive quadrant
+            }
+            screenWidth = screenSize.height
+            screenHeight = screenSize.width
+        }
+
+        // flip second
+        corners.forEach {
+            if (shouldTransformFlipX()) it.x = screenWidth - it.x
+            if (shouldTransformFlipY()) it.y = screenHeight - it.y
+        }
+
+        val top = corners.minByOrNull { it.y }!!.y
+        val right = corners.maxByOrNull { it.x }!!.x
+        val bottom = corners.maxByOrNull { it.y }!!.y
+        val left = corners.minByOrNull { it.x }!!.x
+
+        return Rect(left, top, right, bottom)
+    }
+
+    /**
+     * Transforms the given rect from the base case space, where the PiP anchor is positioned in
+     * the bottom right corner or on the right side, back into screen space.
+     *
+     * @see [toTransformedSpace]
+     */
+    private fun fromTransformedSpace(r: Rect): Rect {
+        val rotate = shouldTransformRotate()
+        val transformedScreenWidth = if (rotate) screenSize.height else screenSize.width
+        val transformedScreenHeight = if (rotate) screenSize.width else screenSize.height
+
+        val tl = Point(r.left, r.top)
+        val tr = Point(r.right, r.top)
+        val br = Point(r.right, r.bottom)
+        val bl = Point(r.left, r.bottom)
+        val corners = arrayOf(tl, tr, br, bl)
+
+        // flip first
+        corners.forEach {
+            if (shouldTransformFlipX()) it.x = transformedScreenWidth - it.x
+            if (shouldTransformFlipY()) it.y = transformedScreenHeight - it.y
+        }
+
+        // rotate second (CCW)
+        if (rotate) {
+            corners.forEach { p ->
+                p.y -= screenSize.width // undo shift back screen into positive quadrant
+                val px = p.x
+                val py = p.y
+                p.x = -py
+                p.y = px
+            }
+        }
+
+        val top = corners.minByOrNull { it.y }!!.y
+        val right = corners.maxByOrNull { it.x }!!.x
+        val bottom = corners.maxByOrNull { it.y }!!.y
+        val left = corners.minByOrNull { it.x }!!.x
+
+        return Rect(left, top, right, bottom)
+    }
+
+    /** PiP anchor bounds in base case for given gravity */
+    private fun getNormalPipAnchorBounds(pipSize: Size, movementBounds: Rect): Rect {
+        var size = pipSize
+        val rotateCW = shouldTransformRotate()
+        if (rotateCW) {
+            size = Size(pipSize.height, pipSize.width)
+        }
+
+        val pipBounds = Rect()
+        if (isPipAnchoredToCorner()) {
+            // bottom right
+            Gravity.apply(
+                Gravity.BOTTOM or Gravity.RIGHT,
+                size.width,
+                size.height,
+                movementBounds,
+                pipBounds
+            )
+            return pipBounds
+        } else {
+            // expanded, right side
+            Gravity.apply(Gravity.RIGHT, size.width, size.height, movementBounds, pipBounds)
+            return pipBounds
+        }
+    }
+
+    private fun isPipAnchoredToCorner(): Boolean {
+        val left = (pipGravity and Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT
+        val right = (pipGravity and Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.RIGHT
+        val top = (pipGravity and Gravity.VERTICAL_GRAVITY_MASK) == Gravity.TOP
+        val bottom = (pipGravity and Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM
+
+        val horizontal = left || right
+        val vertical = top || bottom
+
+        return horizontal && vertical
+    }
+
+    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
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
index 32ebe2d..1a035c5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
@@ -30,17 +30,18 @@
 import android.graphics.RectF;
 import android.os.Handler;
 import android.os.RemoteException;
-import android.util.Log;
 import android.view.SurfaceControl;
 import android.view.SyncRtSurfaceTransactionApplier;
 import android.view.WindowManagerGlobal;
 
 import androidx.annotation.Nullable;
 
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.pip.PipMediaController;
 import com.android.wm.shell.pip.PipMenuController;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -110,7 +111,10 @@
     }
 
     void setDelegate(Delegate delegate) {
-        if (DEBUG) Log.d(TAG, "setDelegate(), delegate=" + delegate);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: setDelegate(), delegate=%s", TAG, delegate);
+        }
         if (mDelegate != null) {
             throw new IllegalStateException(
                     "The delegate has already been set and should not change.");
@@ -133,7 +137,10 @@
     }
 
     private void attachPipMenuView() {
-        if (DEBUG) Log.d(TAG, "attachPipMenuView()");
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: attachPipMenuView()", TAG);
+        }
 
         if (mPipMenuView != null) {
             detachPipMenuView();
@@ -148,7 +155,10 @@
 
     @Override
     public void showMenu() {
-        if (DEBUG) Log.d(TAG, "showMenu()");
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: showMenu()", TAG);
+        }
 
         if (mPipMenuView != null) {
             Rect menuBounds = getMenuBounds(mTvPipBoundsState.getBounds());
@@ -174,8 +184,8 @@
     }
 
     void updateExpansionState() {
-        mPipMenuView.setExpandedModeEnabled(mTvPipBoundsState.isTvExpandedPipEnabled()
-                && mTvPipBoundsState.getTvExpandedAspectRatio() != 0);
+        mPipMenuView.setExpandedModeEnabled(mTvPipBoundsState.isTvExpandedPipSupported()
+                && mTvPipBoundsState.getDesiredTvExpandedAspectRatio() != 0);
         mPipMenuView.setIsExpanded(mTvPipBoundsState.isTvPipExpanded());
     }
 
@@ -189,10 +199,16 @@
 
     void hideMenu() {
         if (!isMenuVisible()) {
-            if (DEBUG) Log.d(TAG, "hideMenu() - Menu isn't visible, so don't hide");
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: hideMenu() - Menu isn't visible, so don't hide", TAG);
+            }
             return;
         } else {
-            if (DEBUG) Log.d(TAG, "hideMenu()");
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: hideMenu()", TAG);
+            }
         }
 
         mPipMenuView.hide();
@@ -202,21 +218,33 @@
         }
     }
 
+    boolean isInMoveMode() {
+        return mInMoveMode;
+    }
+
     @Override
     public void onEnterMoveMode() {
-        if (DEBUG) Log.d(TAG, "onEnterMoveMode - " + mInMoveMode);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: onEnterMoveMode - %b", TAG, mInMoveMode);
+        }
         mInMoveMode = true;
         mPipMenuView.showMenuButtons(false);
         mPipMenuView.showMovementHints(mDelegate.getPipGravity());
+        mDelegate.onInMoveModeChanged();
     }
 
     @Override
     public boolean onExitMoveMode() {
-        if (DEBUG) Log.d(TAG, "onExitMoveMode - " + mInMoveMode);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: onExitMoveMode - %b", TAG, mInMoveMode);
+        }
         if (mInMoveMode) {
             mInMoveMode = false;
             mPipMenuView.showMenuButtons(true);
             mPipMenuView.hideMovementHints();
+            mDelegate.onInMoveModeChanged();
             return true;
         }
         return false;
@@ -224,7 +252,10 @@
 
     @Override
     public boolean onPipMovement(int keycode) {
-        if (DEBUG) Log.d(TAG, "onPipMovement - " + mInMoveMode);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: onPipMovement - %b", TAG, mInMoveMode);
+        }
         if (mInMoveMode) {
             mDelegate.movePip(keycode);
         }
@@ -240,12 +271,18 @@
 
     @Override
     public void setAppActions(ParceledListSlice<RemoteAction> actions) {
-        if (DEBUG) Log.d(TAG, "setAppActions()");
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: setAppActions()", TAG);
+        }
         updateAdditionalActionsList(mAppActions, actions.getList());
     }
 
     private void onMediaActionsChanged(List<RemoteAction> actions) {
-        if (DEBUG) Log.d(TAG, "onMediaActionsChanged()");
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: onMediaActionsChanged()", TAG);
+        }
 
         // Hide disabled actions.
         List<RemoteAction> enabledActions = new ArrayList<>();
@@ -286,7 +323,10 @@
     @Override
     public boolean isMenuVisible() {
         boolean isVisible = mPipMenuView != null && mPipMenuView.isVisible();
-        if (DEBUG) Log.d(TAG, "isMenuVisible: " + isVisible);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: isMenuVisible: %b", TAG, isVisible);
+        }
         return isVisible;
     }
 
@@ -297,7 +337,10 @@
     public void resizePipMenu(@android.annotation.Nullable SurfaceControl pipLeash,
             @android.annotation.Nullable SurfaceControl.Transaction t,
             Rect destinationBounds) {
-        if (DEBUG) Log.d(TAG, "resizePipMenu: " + destinationBounds.toShortString());
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: resizePipMenu: %s", TAG, destinationBounds.toShortString());
+        }
         if (destinationBounds.isEmpty()) {
             return;
         }
@@ -329,10 +372,16 @@
     @Override
     public void movePipMenu(SurfaceControl pipLeash, SurfaceControl.Transaction transaction,
             Rect pipDestBounds) {
-        if (DEBUG) Log.d(TAG, "movePipMenu: " + pipDestBounds.toShortString());
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: movePipMenu: %s", TAG, pipDestBounds.toShortString());
+        }
 
         if (pipDestBounds.isEmpty()) {
-            if (transaction == null && DEBUG) Log.d(TAG, "no transaction given");
+            if (transaction == null && DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: no transaction given", TAG);
+            }
             return;
         }
         if (!maybeCreateSyncApplier()) {
@@ -345,10 +394,16 @@
         // resizing and the PiP menu is also resized. We then want to do a scale from the current
         // new menu bounds.
         if (pipLeash != null && transaction != null) {
-            if (DEBUG) Log.d(TAG, "mTmpSourceBounds based on mPipMenuView.getBoundsOnScreen()");
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: mTmpSourceBounds based on mPipMenuView.getBoundsOnScreen()", TAG);
+            }
             mPipMenuView.getBoundsOnScreen(mTmpSourceBounds);
         } else {
-            if (DEBUG) Log.d(TAG, "mTmpSourceBounds based on menu width and height");
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: mTmpSourceBounds based on menu width and height", TAG);
+            }
             mTmpSourceBounds.set(0, 0, menuDestBounds.width(), menuDestBounds.height());
         }
 
@@ -383,7 +438,8 @@
 
     private boolean maybeCreateSyncApplier() {
         if (mPipMenuView == null || mPipMenuView.getViewRootImpl() == null) {
-            Log.v(TAG, "Not going to move PiP, either menu or its parent is not created.");
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Not going to move PiP, either menu or its parent is not created.", TAG);
             return false;
         }
 
@@ -406,7 +462,10 @@
     @Override
     public void updateMenuBounds(Rect destinationBounds) {
         Rect menuBounds = getMenuBounds(destinationBounds);
-        if (DEBUG) Log.d(TAG, "updateMenuBounds: " + menuBounds.toShortString());
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: updateMenuBounds: %s", TAG, menuBounds.toShortString());
+        }
         mSystemWindows.updateViewLayout(mPipMenuView,
                 getPipMenuLayoutParams(MENU_WINDOW_TITLE, menuBounds.width(),
                         menuBounds.height()));
@@ -417,7 +476,7 @@
 
     @Override
     public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
-        Log.d(TAG, "onFocusTaskChanged");
+        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: onFocusTaskChanged", TAG);
     }
 
     @Override
@@ -447,6 +506,8 @@
 
         void movePip(int keycode);
 
+        void onInMoveModeChanged();
+
         int getPipGravity();
 
         void togglePipExpansion();
@@ -457,13 +518,17 @@
     }
 
     private void grantPipMenuFocus(boolean grantFocus) {
-        if (DEBUG) Log.d(TAG, "grantWindowFocus(" + grantFocus + ")");
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: grantWindowFocus(%b)", TAG, grantFocus);
+        }
 
         try {
             WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(null /* window */,
                     mSystemWindows.getFocusGrantToken(mPipMenuView), grantFocus);
         } catch (Exception e) {
-            Log.e(TAG, "Unable to update focus", e);
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Unable to update focus, %s", TAG, e);
         }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
index 3090139..984dea2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
@@ -31,7 +31,6 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.SurfaceControl;
@@ -45,7 +44,9 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -118,17 +119,24 @@
     }
 
     void updateLayout(Rect updatedBounds) {
-        Log.d(TAG, "update menu layout: " + updatedBounds.toShortString());
+        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                "%s: update menu layout: %s", TAG, updatedBounds.toShortString());
         boolean previouslyVertical =
                 mCurrentBounds != null && mCurrentBounds.height() > mCurrentBounds.width();
         boolean vertical = updatedBounds.height() > updatedBounds.width();
 
         mCurrentBounds = updatedBounds;
         if (previouslyVertical == vertical) {
-            if (DEBUG) Log.d(TAG, "no update for menu layout");
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: no update for menu layout", TAG);
+            }
             return;
         } else {
-            if (DEBUG) Log.d(TAG, "change menu layout to vertical: " + vertical);
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: change menu layout to vertical: %b", TAG, vertical);
+            }
         }
 
         if (vertical) {
@@ -154,7 +162,10 @@
     }
 
     void setIsExpanded(boolean expanded) {
-        if (DEBUG) Log.d(TAG, "setIsExpanded, expanded: " + expanded);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: setIsExpanded, expanded: %b", TAG, expanded);
+        }
         mExpandButton.setImageResource(
                 expanded ? R.drawable.pip_ic_collapse : R.drawable.pip_ic_expand);
         mExpandButton.setTextAndDescription(
@@ -162,7 +173,10 @@
     }
 
     void show(boolean inMoveMode, int gravity) {
-        if (DEBUG) Log.d(TAG, "show(), inMoveMode: " + inMoveMode);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: show(), inMoveMode: %b", TAG, inMoveMode);
+        }
         if (inMoveMode) {
             showMovementHints(gravity);
         } else {
@@ -172,7 +186,9 @@
     }
 
     void hide() {
-        if (DEBUG) Log.d(TAG, "hide()");
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: hide()", TAG);
+        }
         animateAlphaTo(0, mActionButtonsContainer);
         animateAlphaTo(0, mMenuFrameView);
         hideMovementHints();
@@ -205,7 +221,10 @@
     }
 
     void setAdditionalActions(List<RemoteAction> actions, Handler mainHandler) {
-        if (DEBUG) Log.d(TAG, "setAdditionalActions()");
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: setAdditionalActions()", TAG);
+        }
 
         // Make sure we exactly as many additional buttons as we have actions to display.
         final int actionsNumber = actions.size();
@@ -278,10 +297,12 @@
                 try {
                     action.getActionIntent().send();
                 } catch (PendingIntent.CanceledException e) {
-                    Log.w(TAG, "Failed to send action", e);
+                    ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                            "%s: Failed to send action, %s", TAG, e);
                 }
             } else {
-                Log.w(TAG, "RemoteAction is null");
+                ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: RemoteAction is null", TAG);
             }
         }
     }
@@ -289,8 +310,9 @@
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         if (DEBUG) {
-            Log.d(TAG, "dispatchKeyEvent, action: " + event.getAction()
-                    + ", keycode: " + event.getKeyCode());
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: dispatchKeyEvent, action: %d, keycode: %d",
+                    TAG, event.getAction(), event.getKeyCode());
         }
         if (mListener != null && event.getAction() == ACTION_UP) {
             switch (event.getKeyCode()) {
@@ -317,7 +339,10 @@
      * Shows user hints for moving the PiP, e.g. arrows.
      */
     public void showMovementHints(int gravity) {
-        if (DEBUG) Log.d(TAG, "showMovementHints(), position: " + Gravity.toString(gravity));
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: showMovementHints(), position: %s", TAG, Gravity.toString(gravity));
+        }
 
         animateAlphaTo(checkGravity(gravity, Gravity.BOTTOM) ? 1f : 0f, mArrowUp);
         animateAlphaTo(checkGravity(gravity, Gravity.TOP) ? 1f : 0f, mArrowDown);
@@ -333,7 +358,10 @@
      * Hides user hints for moving the PiP, e.g. arrows.
      */
     public void hideMovementHints() {
-        if (DEBUG) Log.d(TAG, "hideMovementHints()");
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: hideMovementHints()", TAG);
+        }
         animateAlphaTo(0, mArrowUp);
         animateAlphaTo(0, mArrowRight);
         animateAlphaTo(0, mArrowDown);
@@ -344,7 +372,10 @@
      * Show or hide the pip user actions.
      */
     public void showMenuButtons(boolean show) {
-        if (DEBUG) Log.d(TAG, "showMenuButtons: " + show);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: showMenuButtons: %b", TAG, show);
+        }
         animateAlphaTo(show ? 1 : 0, mActionButtonsContainer);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
index dd7e294..7bd3ce9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
@@ -28,13 +28,13 @@
 import android.graphics.Bitmap;
 import android.media.MediaMetadata;
 import android.os.Handler;
-import android.os.UserHandle;
 import android.text.TextUtils;
-import android.util.Log;
 
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.pip.PipMediaController;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.util.Objects;
 
@@ -98,7 +98,10 @@
     }
 
     void setDelegate(Delegate delegate) {
-        if (DEBUG) Log.d(TAG, "setDelegate(), delegate=" + delegate);
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: setDelegate(), delegate=%s", TAG, delegate);
+        }
         if (mDelegate != null) {
             throw new IllegalStateException(
                     "The delegate has already been set and should not change.");
@@ -240,7 +243,10 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
-            if (DEBUG) Log.d(TAG, "on(Broadcast)Receive(), action=" + action);
+            if (DEBUG) {
+                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                        "%s: on(Broadcast)Receive(), action=%s", TAG, action);
+            }
 
             if (ACTION_SHOW_PIP_MENU.equals(action)) {
                 mDelegate.showPictureInPictureMenu();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
index 1ddc0e7..64017e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
@@ -38,6 +38,8 @@
             "ShellBackPreview"),
     WM_SHELL_RECENT_TASKS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
             Consts.TAG_WM_SHELL),
+    WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG,
+            false, Consts.TAG_WM_SHELL),
     TEST_GROUP(true, true, false, "WindowManagerShellProtoLogTest");
 
     private final boolean mEnabled;
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 1a5e3f2..ec1ddf0 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
@@ -29,6 +29,7 @@
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
 import static android.view.WindowManager.transitTypeToString;
 import static android.view.WindowManagerPolicyConstants.SPLIT_DIVIDER_LAYER;
+import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
 
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
@@ -1117,9 +1118,9 @@
             return SPLIT_POSITION_UNDEFINED;
         }
 
-        if (token.equals(mMainStage.mRootTaskInfo.getToken())) {
+        if (mMainStage.containsToken(token)) {
             return getMainStagePosition();
-        } else if (token.equals(mSideStage.mRootTaskInfo.getToken())) {
+        } else if (mSideStage.containsToken(token)) {
             return getSideStagePosition();
         }
 
@@ -1171,6 +1172,8 @@
                 updateUnfoldBounds();
                 return;
             }
+
+            mSplitLayout.update(null /* t */);
             onLayoutSizeChanged(mSplitLayout);
         }
     }
@@ -1198,7 +1201,6 @@
         if (!ENABLE_SHELL_TRANSITIONS) return;
 
         final SurfaceControl.Transaction t = mTransactionPool.acquire();
-        setDividerVisibility(false, t);
         mDisplayLayout.rotateTo(mContext.getResources(), toRotation);
         mSplitLayout.rotateTo(toRotation, mDisplayLayout.stableInsets());
         updateWindowBounds(mSplitLayout, wct);
@@ -1255,8 +1257,15 @@
             @Nullable TransitionRequestInfo request) {
         final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
         if (triggerTask == null) {
-            // Still want to monitor everything while in split-screen, so return non-null.
-            return mMainStage.isActive() ? new WindowContainerTransaction() : null;
+            if (mMainStage.isActive()) {
+                if (request.getType() == TRANSIT_CHANGE && request.getDisplayChange() != null) {
+                    mSplitLayout.setFreezeDividerWindow(true);
+                }
+                // Still want to monitor everything while in split-screen, so return non-null.
+                return new WindowContainerTransaction();
+            } else {
+                return null;
+            }
         } else if (triggerTask.displayId != mDisplayId) {
             // Skip handling task on the other display.
             return null;
@@ -1329,8 +1338,11 @@
         // Once the pending enter transition got merged, make sure to bring divider bar visible and
         // clear the pending transition from cache to prevent mess-up the following state.
         if (transition == mSplitTransitions.mPendingEnter) {
-            finishEnterSplitScreen(null);
+            final SurfaceControl.Transaction t = mTransactionPool.acquire();
+            finishEnterSplitScreen(t);
             mSplitTransitions.mPendingEnter = null;
+            t.apply();
+            mTransactionPool.release(t);
         }
     }
 
@@ -1349,8 +1361,14 @@
             // If we're not in split-mode, just abort so something else can handle it.
             if (!mMainStage.isActive()) return false;
 
+            mSplitLayout.setFreezeDividerWindow(false);
             for (int iC = 0; iC < info.getChanges().size(); ++iC) {
                 final TransitionInfo.Change change = info.getChanges().get(iC);
+                if (change.getMode() == TRANSIT_CHANGE
+                        && (change.getFlags() & FLAG_IS_DISPLAY) != 0) {
+                    mSplitLayout.update(startTransaction);
+                }
+
                 final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
                 if (taskInfo == null || !taskInfo.hasParentTask()) continue;
                 final StageTaskListener stage = getStageOfTask(taskInfo);
@@ -1365,10 +1383,6 @@
                         Log.w(TAG, "Expected onTaskVanished on " + stage + " to have been called"
                                 + " with " + taskInfo.taskId + " before startAnimation().");
                     }
-                } else if (info.getType() == TRANSIT_CHANGE
-                        && change.getStartRotation() != change.getEndRotation()) {
-                    // Show the divider after transition finished.
-                    setDividerVisibility(true, finishTransaction);
                 }
             }
             if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index c5aab45..5f0cd01 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -124,6 +124,20 @@
         return mChildrenTaskInfo.contains(taskId);
     }
 
+    boolean containsToken(WindowContainerToken token) {
+        if (token.equals(mRootTaskInfo.token)) {
+            return true;
+        }
+
+        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
+            if (token.equals(mChildrenTaskInfo.valueAt(i).token)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     /**
      * Returns the top visible child task's id.
      */
@@ -280,10 +294,20 @@
 
     @Override
     public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+        b.setParent(findTaskSurface(taskId));
+    }
+
+    @Override
+    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+            SurfaceControl.Transaction t) {
+        t.reparent(sc, findTaskSurface(taskId));
+    }
+
+    private SurfaceControl findTaskSurface(int taskId) {
         if (mRootTaskInfo.taskId == taskId) {
-            b.setParent(mRootLeash);
+            return mRootLeash;
         } else if (mChildrenLeashes.contains(taskId)) {
-            b.setParent(mChildrenLeashes.get(taskId));
+            return mChildrenLeashes.get(taskId);
         } else {
             throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java
index 8b36c94..7b679580 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java
@@ -227,10 +227,20 @@
 
     @Override
     public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
+        b.setParent(findTaskSurface(taskId));
+    }
+
+    @Override
+    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
+            SurfaceControl.Transaction t) {
+        t.reparent(sc, findTaskSurface(taskId));
+    }
+
+    private SurfaceControl findTaskSurface(int taskId) {
         if (mRootTaskInfo.taskId == taskId) {
-            b.setParent(mRootLeash);
+            return mRootLeash;
         } else if (mChildrenLeashes.contains(taskId)) {
-            b.setParent(mChildrenLeashes.get(taskId));
+            return mChildrenLeashes.get(taskId);
         } else {
             throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
index 1bef552e..49f907b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
@@ -62,6 +62,7 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.hardware.HardwareBuffer;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.Trace;
@@ -243,7 +244,7 @@
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "TaskSnapshot#relayout");
             session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0,
                     tmpFrames, tmpMergedConfiguration, surfaceControl, tmpInsetsState,
-                    tmpControls);
+                    tmpControls, new Bundle());
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         } catch (RemoteException e) {
             snapshotSurface.clearWindowSynced();
@@ -517,7 +518,7 @@
 
     private void reportDrawn() {
         try {
-            mSession.finishDrawing(mWindow, null /* postDrawTransaction */);
+            mSession.finishDrawing(mWindow, null /* postDrawTransaction */, Integer.MAX_VALUE);
         } catch (RemoteException e) {
             clearWindowSynced();
         }
@@ -534,7 +535,7 @@
         @Override
         public void resized(ClientWindowFrames frames, boolean reportDraw,
                 MergedConfiguration mergedConfiguration, boolean forceLayout,
-                boolean alwaysConsumeSystemBars, int displayId) {
+                boolean alwaysConsumeSystemBars, int displayId, int seqId) {
             if (mOuter != null) {
                 mOuter.mSplashScreenExecutor.execute(() -> {
                     if (mergedConfiguration != null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 56d5168..a225f4e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -408,7 +408,8 @@
                             || type == TRANSIT_CLOSE
                             || type == TRANSIT_TO_FRONT
                             || type == TRANSIT_TO_BACK;
-                    if (isOpenOrCloseTransition) {
+                    final boolean isTranslucent = (change.getFlags() & FLAG_TRANSLUCENT) != 0;
+                    if (isOpenOrCloseTransition && !isTranslucent) {
                         // Use the overview background as the background for the animation
                         final Context uiContext = ActivityThread.currentActivityThread()
                                 .getSystemUiContext();
@@ -729,14 +730,17 @@
                         ? R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
                         : R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
             } else if (type == TRANSIT_OPEN) {
-                if (isTask) {
+                // We will translucent open animation for translucent activities and tasks. Choose
+                // WindowAnimation_activityOpenEnterAnimation and set translucent here, then
+                // TransitionAnimation loads appropriate animation later.
+                if ((changeFlags & FLAG_TRANSLUCENT) != 0 && enter) {
+                    translucent = true;
+                }
+                if (isTask && !translucent) {
                     animAttr = enter
                             ? R.styleable.WindowAnimation_taskOpenEnterAnimation
                             : R.styleable.WindowAnimation_taskOpenExitAnimation;
                 } else {
-                    if ((changeFlags & FLAG_TRANSLUCENT) != 0 && enter) {
-                        translucent = true;
-                    }
                     animAttr = enter
                             ? R.styleable.WindowAnimation_activityOpenEnterAnimation
                             : R.styleable.WindowAnimation_activityOpenExitAnimation;
@@ -770,7 +774,7 @@
                             .loadAnimationAttr(options.getPackageName(), options.getAnimations(),
                                     animAttr, translucent);
                 } else {
-                    a = mTransitionAnimation.loadDefaultAnimationAttr(animAttr);
+                    a = mTransitionAnimation.loadDefaultAnimationAttr(animAttr, translucent);
                 }
             }
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index efb52a5..fb3cd87 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -73,9 +73,9 @@
 
     /** Set to {@code true} to enable shell transitions. */
     public static final boolean ENABLE_SHELL_TRANSITIONS =
-            SystemProperties.getBoolean("persist.debug.shell_transit", false);
+            SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
     public static final boolean SHELL_TRANSITIONS_ROTATION = ENABLE_SHELL_TRANSITIONS
-            && SystemProperties.getBoolean("persist.debug.shell_transit_rotate", false);
+            && SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false);
 
     /** Transition type for exiting PIP via the Shell, via pressing the expand button. */
     public static final int TRANSIT_EXIT_PIP = TRANSIT_FIRST_CUSTOM + 1;
@@ -363,7 +363,9 @@
             return;
         }
 
-        // apply transfer starting window directly if there is no other task change.
+        // apply transfer starting window directly if there is no other task change. Since this
+        // is an activity->activity situation, we can detect it by selecting transitions with only
+        // 2 changes where neither are tasks and one is a starting-window recipient.
         final int changeSize = info.getChanges().size();
         if (changeSize == 2) {
             boolean nonTaskChange = true;
@@ -380,7 +382,9 @@
             }
             if (nonTaskChange && transferStartingWindow) {
                 t.apply();
-                onFinish(transitionToken, null /* wct */, null /* wctCB */);
+                // Treat this as an abort since we are bypassing any merge logic and effectively
+                // finishing immediately.
+                onAbort(transitionToken);
                 return;
             }
         }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
index 61e27f2..fb404b9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.flicker.bubble
 
+import android.platform.test.annotations.Presubmit
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.RequiresDevice
 import androidx.test.uiautomator.By
@@ -24,6 +25,8 @@
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.annotation.Group4
 import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
+import org.junit.Assume
 import org.junit.runner.RunWith
 import org.junit.Test
 import org.junit.runners.Parameterized
@@ -69,9 +72,19 @@
             }
         }
 
-    @FlakyTest
+    @Presubmit
     @Test
     fun testAppIsVisibleAtEnd() {
+        Assume.assumeFalse(isShellTransitionsEnabled)
+        testSpec.assertLayersEnd {
+            this.isVisible(testApp.component)
+        }
+    }
+
+    @FlakyTest
+    @Test
+    fun testAppIsVisibleAtEnd_ShellTransit() {
+        Assume.assumeTrue(isShellTransitionsEnabled)
         testSpec.assertLayersEnd {
             this.isVisible(testApp.component)
         }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
index a57d3e6..c43230e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.flicker.bubble
 
+import android.platform.test.annotations.Presubmit
 import androidx.test.filters.FlakyTest
 import android.platform.test.annotations.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -57,9 +58,19 @@
             }
         }
 
-    @FlakyTest(bugId = 218642026)
+    @Presubmit
     @Test
     open fun testAppIsAlwaysVisible() {
+        Assume.assumeFalse(isShellTransitionsEnabled)
+        testSpec.assertLayers {
+            this.isVisible(testApp.component)
+        }
+    }
+
+    @FlakyTest(bugId = 218642026)
+    @Test
+    open fun testAppIsAlwaysVisible_ShellTransit() {
+        Assume.assumeTrue(isShellTransitionsEnabled)
         testSpec.assertLayers {
             this.isVisible(testApp.component)
         }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
index 57bc0d5..3dd9e05 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
@@ -61,7 +61,7 @@
         private const val APP_CLOSE_WAIT_TIME_MS = 3_000L
 
         fun isShellTransitionsEnabled() =
-                SystemProperties.getBoolean("persist.debug.shell_transit", false)
+                SystemProperties.getBoolean("persist.wm.debug.shell_transit", false)
 
         fun executeShellCommand(instrumentation: Instrumentation, cmd: String) {
             try {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 9054685..3e7ee25 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -78,6 +78,7 @@
         MockitoAnnotations.initMocks(this);
         mController = new BackAnimationController(
                 mShellExecutor, mTransaction, mActivityTaskManager, mContext);
+        mController.setEnableAnimations(true);
     }
 
     private void createNavigationInfo(RemoteAnimationTarget topAnimationTarget,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java
index 9bb54a1..2e5078d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java
@@ -61,7 +61,7 @@
     public void testInitRelease() {
         mSplitWindowManager.init(mSplitLayout, new InsetsState());
         assertThat(mSplitWindowManager.getSurfaceControl()).isNotNull();
-        mSplitWindowManager.release();
+        mSplitWindowManager.release(null /* t */);
         assertThat(mSplitWindowManager.getSurfaceControl()).isNull();
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index 29e40be..a31b287 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -325,17 +325,17 @@
     }
 
     @Test
-    public void testChangeLayoutsVisibilityOnKeyguardOccludedChanged() {
+    public void testChangeLayoutsVisibilityOnKeyguardShowingChanged() {
         mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
                 /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
 
-        // Verify that the restart button is hidden after keyguard becomes occluded.
-        mController.onKeyguardOccludedChanged(true);
+        // Verify that the restart button is hidden after keyguard becomes showing.
+        mController.onKeyguardShowingChanged(true);
 
         verify(mMockCompatLayout).updateVisibility(false);
         verify(mMockLetterboxEduLayout).updateVisibility(false);
 
-        // Verify button remains hidden while keyguard is occluded.
+        // Verify button remains hidden while keyguard is showing.
         TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                 CAMERA_COMPAT_CONTROL_HIDDEN);
         mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
@@ -345,20 +345,20 @@
         verify(mMockLetterboxEduLayout).updateCompatInfo(taskInfo, mMockTaskListener, /* canShow= */
                 false);
 
-        // Verify button is shown after keyguard becomes not occluded.
-        mController.onKeyguardOccludedChanged(false);
+        // Verify button is shown after keyguard becomes not showing.
+        mController.onKeyguardShowingChanged(false);
 
         verify(mMockCompatLayout).updateVisibility(true);
         verify(mMockLetterboxEduLayout).updateVisibility(true);
     }
 
     @Test
-    public void testLayoutsRemainHiddenOnKeyguardOccludedFalseWhenImeIsShowing() {
+    public void testLayoutsRemainHiddenOnKeyguardShowingFalseWhenImeIsShowing() {
         mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
                 /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
 
         mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
-        mController.onKeyguardOccludedChanged(true);
+        mController.onKeyguardShowingChanged(true);
 
         verify(mMockCompatLayout, times(2)).updateVisibility(false);
         verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);
@@ -366,8 +366,8 @@
         clearInvocations(mMockCompatLayout);
         clearInvocations(mMockLetterboxEduLayout);
 
-        // Verify button remains hidden after keyguard becomes not occluded since IME is showing.
-        mController.onKeyguardOccludedChanged(false);
+        // Verify button remains hidden after keyguard becomes not showing since IME is showing.
+        mController.onKeyguardShowingChanged(false);
 
         verify(mMockCompatLayout).updateVisibility(false);
         verify(mMockLetterboxEduLayout).updateVisibility(false);
@@ -380,12 +380,12 @@
     }
 
     @Test
-    public void testLayoutsRemainHiddenOnImeHideWhenKeyguardIsOccluded() {
+    public void testLayoutsRemainHiddenOnImeHideWhenKeyguardIsShowing() {
         mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
                 /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
 
         mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
-        mController.onKeyguardOccludedChanged(true);
+        mController.onKeyguardShowingChanged(true);
 
         verify(mMockCompatLayout, times(2)).updateVisibility(false);
         verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);
@@ -393,14 +393,14 @@
         clearInvocations(mMockCompatLayout);
         clearInvocations(mMockLetterboxEduLayout);
 
-        // Verify button remains hidden after IME is hidden since keyguard is occluded.
+        // Verify button remains hidden after IME is hidden since keyguard is showing.
         mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ false);
 
         verify(mMockCompatLayout).updateVisibility(false);
         verify(mMockLetterboxEduLayout).updateVisibility(false);
 
-        // Verify button is shown after keyguard becomes not occluded.
-        mController.onKeyguardOccludedChanged(false);
+        // Verify button is shown after keyguard becomes not showing.
+        mController.onKeyguardShowingChanged(false);
 
         verify(mMockCompatLayout).updateVisibility(true);
         verify(mMockLetterboxEduLayout).updateVisibility(true);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java
index 00e4938..1dee88c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java
@@ -70,6 +70,8 @@
     public void testOnFinishInflate() {
         assertEquals(mLayout.getDialogContainer(),
                 mLayout.findViewById(R.id.letterbox_education_dialog_container));
+        assertEquals(mLayout.getDialogTitle(),
+                mLayout.findViewById(R.id.letterbox_education_dialog_title));
         assertEquals(mLayout.getBackgroundDim(), mLayout.getBackground());
         assertEquals(mLayout.getBackground().getAlpha(), 0);
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java
index 0509dd3..337b738 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java
@@ -41,9 +41,11 @@
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.SurfaceControlViewHost;
+import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup.MarginLayoutParams;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
 
 import androidx.test.filters.SmallTest;
 
@@ -173,13 +175,19 @@
         verifyLayout(layout, mWindowAttrsCaptor.getValue(), /* expectedWidth= */ TASK_WIDTH,
                 /* expectedHeight= */ TASK_HEIGHT, /* expectedExtraTopMargin= */ DISPLAY_CUTOUT_TOP,
                 /* expectedExtraBottomMargin= */ DISPLAY_CUTOUT_BOTTOM);
+        View dialogTitle = layout.getDialogTitle();
+        assertNotNull(dialogTitle);
+        spyOn(dialogTitle);
 
         // Clicking the layout does nothing until enter animation is done.
         layout.performClick();
         verify(mAnimationController, never()).startExitAnimation(any(), any());
+        // The dialog title shouldn't be focused for Accessibility until enter animation is done.
+        verify(dialogTitle, never()).sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
 
         verifyAndFinishEnterAnimation(layout);
 
+        verify(dialogTitle).sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
         // Exit animation should start following a click on the layout.
         layout.performClick();
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/fullscreen/FullscreenTaskListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/fullscreen/FullscreenTaskListenerTest.java
index 46fe201..4523e2c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/fullscreen/FullscreenTaskListenerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/fullscreen/FullscreenTaskListenerTest.java
@@ -50,7 +50,7 @@
 @SmallTest
 public class FullscreenTaskListenerTest {
     private static final boolean ENABLE_SHELL_TRANSITIONS =
-            SystemProperties.getBoolean("persist.debug.shell_transit", false);
+            SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
 
     @Mock
     private SyncTransactionQueue mSyncQueue;
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
new file mode 100644
index 0000000..78903dc
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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.wm.shell.kidsmode;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ParceledListSlice;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.view.InsetsState;
+import android.view.SurfaceControl;
+import android.window.ITaskOrganizerController;
+import android.window.TaskAppearedInfo;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.policy.ForceShowNavigationBarSettingsObserver;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayInsetsController;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.compatui.CompatUIController;
+import com.android.wm.shell.startingsurface.StartingWindowController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Optional;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class KidsModeTaskOrganizerTest {
+    @Mock private ITaskOrganizerController mTaskOrganizerController;
+    @Mock private Context mContext;
+    @Mock private Handler mHandler;
+    @Mock private CompatUIController mCompatUI;
+    @Mock private SyncTransactionQueue mSyncTransactionQueue;
+    @Mock private ShellExecutor mTestExecutor;
+    @Mock private DisplayController mDisplayController;
+    @Mock private SurfaceControl mLeash;
+    @Mock private WindowContainerToken mToken;
+    @Mock private WindowContainerTransaction mTransaction;
+    @Mock private ForceShowNavigationBarSettingsObserver mObserver;
+    @Mock private StartingWindowController mStartingWindowController;
+    @Mock private DisplayInsetsController mDisplayInsetsController;
+
+    KidsModeTaskOrganizer mOrganizer;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        try {
+            doReturn(ParceledListSlice.<TaskAppearedInfo>emptyList())
+                    .when(mTaskOrganizerController).registerTaskOrganizer(any());
+        } catch (RemoteException e) { }
+        mOrganizer = spy(new KidsModeTaskOrganizer(mTaskOrganizerController, mTestExecutor,
+                mHandler, mContext, mCompatUI, mSyncTransactionQueue, mDisplayController,
+                mDisplayInsetsController, Optional.empty(), mObserver));
+        mOrganizer.initialize(mStartingWindowController);
+        doReturn(mTransaction).when(mOrganizer).getWindowContainerTransaction();
+        doReturn(new InsetsState()).when(mDisplayController).getInsetsState(DEFAULT_DISPLAY);
+    }
+
+    @Test
+    public void testKidsModeOn() {
+        doReturn(true).when(mObserver).isEnabled();
+
+        mOrganizer.updateKidsModeState();
+
+        verify(mOrganizer, times(1)).enable();
+        verify(mOrganizer, times(1)).registerOrganizer();
+        verify(mOrganizer, times(1)).createRootTask(
+                eq(DEFAULT_DISPLAY), eq(WINDOWING_MODE_FULLSCREEN), eq(mOrganizer.mCookie));
+
+        final ActivityManager.RunningTaskInfo rootTask = createTaskInfo(12,
+                WINDOWING_MODE_FULLSCREEN, mOrganizer.mCookie);
+        mOrganizer.onTaskAppeared(rootTask, mLeash);
+
+        assertThat(mOrganizer.mLaunchRootLeash).isEqualTo(mLeash);
+        assertThat(mOrganizer.mLaunchRootTask).isEqualTo(rootTask);
+    }
+
+    @Test
+    public void testKidsModeOff() {
+        doReturn(true).when(mObserver).isEnabled();
+        mOrganizer.updateKidsModeState();
+        final ActivityManager.RunningTaskInfo rootTask = createTaskInfo(12,
+                WINDOWING_MODE_FULLSCREEN, mOrganizer.mCookie);
+        mOrganizer.onTaskAppeared(rootTask, mLeash);
+
+        doReturn(false).when(mObserver).isEnabled();
+        mOrganizer.updateKidsModeState();
+
+
+        verify(mOrganizer, times(1)).disable();
+        verify(mOrganizer, times(1)).unregisterOrganizer();
+        verify(mOrganizer, times(1)).deleteRootTask(rootTask.token);
+        assertThat(mOrganizer.mLaunchRootLeash).isNull();
+        assertThat(mOrganizer.mLaunchRootTask).isNull();
+    }
+
+    private ActivityManager.RunningTaskInfo createTaskInfo(
+            int taskId, int windowingMode, IBinder cookies) {
+        ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
+        taskInfo.taskId = taskId;
+        taskInfo.token = mToken;
+        taskInfo.configuration.windowConfiguration.setWindowingMode(windowingMode);
+        final ArrayList<IBinder> launchCookies = new ArrayList<>();
+        if (cookies != null) {
+            launchCookies.add(cookies);
+        }
+        taskInfo.launchCookies = launchCookies;
+        return taskInfo;
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 0172cf32..14d9fb9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -48,7 +48,6 @@
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
 import com.android.wm.shell.pip.phone.PhonePipMenuController;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 
@@ -76,7 +75,6 @@
     @Mock private PipTransitionController mMockPipTransitionController;
     @Mock private PipSurfaceTransactionHelper mMockPipSurfaceTransactionHelper;
     @Mock private PipUiEventLogger mMockPipUiEventLogger;
-    @Mock private Optional<LegacySplitScreenController> mMockOptionalLegacySplitScreen;
     @Mock private Optional<SplitScreenController> mMockOptionalSplitScreen;
     @Mock private ShellTaskOrganizer mMockShellTaskOrganizer;
     private TestShellExecutor mMainExecutor;
@@ -101,8 +99,8 @@
                 mMockSyncTransactionQueue, mPipTransitionState, mPipBoundsState,
                 mPipBoundsAlgorithm, mMockPhonePipMenuController,
                 mMockPipAnimationController, mMockPipSurfaceTransactionHelper,
-                mMockPipTransitionController, mMockOptionalLegacySplitScreen,
-                mMockOptionalSplitScreen, mMockDisplayController, mMockPipUiEventLogger,
+                mMockPipTransitionController, mMockOptionalSplitScreen,
+                mMockDisplayController, mMockPipUiEventLogger,
                 mMockShellTaskOrganizer, mMainExecutor));
         mMainExecutor.flushAll();
         preparePipTaskOrg();
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
new file mode 100644
index 0000000..e6ba70e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt
@@ -0,0 +1,469 @@
+/*
+ * 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.wm.shell.pip.tv
+
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.util.Size
+import android.view.Gravity
+import org.junit.runner.RunWith
+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.tv.TvPipKeepClearAlgorithm.Placement
+import org.junit.Before
+import org.junit.Test
+import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertNull
+
+@RunWith(AndroidTestingRunner::class)
+class TvPipKeepClearAlgorithmTest {
+    private val DEFAULT_PIP_SIZE = Size(384, 216)
+    private val EXPANDED_WIDE_PIP_SIZE = Size(384*2, 216)
+    private val DASHBOARD_WIDTH = 484
+    private val BOTTOM_SHEET_HEIGHT = 524
+    private val STASH_OFFSET = 64
+    private val PADDING = 16
+    private val SCREEN_SIZE = Size(1920, 1080)
+    private val SCREEN_EDGE_INSET = 50
+
+    private lateinit var pipSize: Size
+    private lateinit var movementBounds: Rect
+    private lateinit var algorithm: TvPipKeepClearAlgorithm
+    private var currentTime = 0L
+    private var restrictedAreas = mutableSetOf<Rect>()
+    private var unrestrictedAreas = mutableSetOf<Rect>()
+    private var gravity: Int = 0
+
+    @Before
+    fun setup() {
+        movementBounds = Rect(0, 0, SCREEN_SIZE.width, SCREEN_SIZE.height)
+        movementBounds.inset(SCREEN_EDGE_INSET, SCREEN_EDGE_INSET)
+
+        restrictedAreas.clear()
+        unrestrictedAreas.clear()
+        currentTime = 0L
+        pipSize = DEFAULT_PIP_SIZE
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+
+        algorithm = TvPipKeepClearAlgorithm({ currentTime })
+        algorithm.setScreenSize(SCREEN_SIZE)
+        algorithm.setMovementBounds(movementBounds)
+        algorithm.pipAreaPadding = PADDING
+        algorithm.stashOffset = STASH_OFFSET
+        algorithm.stashDuration = 5000L
+        algorithm.setGravity(gravity)
+        algorithm.maxRestrictedDistanceFraction = 0.3
+    }
+
+    @Test
+    fun testAnchorPosition_BottomRight() {
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+        testAnchorPosition()
+    }
+
+    @Test
+    fun testAnchorPosition_TopRight() {
+        gravity = Gravity.TOP or Gravity.RIGHT
+        testAnchorPosition()
+    }
+
+    @Test
+    fun testAnchorPosition_TopLeft() {
+        gravity = Gravity.TOP or Gravity.LEFT
+        testAnchorPosition()
+    }
+
+    @Test
+    fun testAnchorPosition_BottomLeft() {
+        gravity = Gravity.BOTTOM or Gravity.LEFT
+        testAnchorPosition()
+    }
+
+    @Test
+    fun testAnchorPosition_Right() {
+        gravity = Gravity.RIGHT
+        testAnchorPosition()
+    }
+
+    @Test
+    fun testAnchorPosition_Left() {
+        gravity = Gravity.LEFT
+        testAnchorPosition()
+    }
+
+    @Test
+    fun testAnchorPosition_Top() {
+        gravity = Gravity.TOP
+        testAnchorPosition()
+    }
+
+    @Test
+    fun testAnchorPosition_Bottom() {
+        gravity = Gravity.BOTTOM
+        testAnchorPosition()
+    }
+
+    @Test
+    fun testAnchorPosition_TopCenterHorizontal() {
+        gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL
+        testAnchorPosition()
+    }
+
+    @Test
+    fun testAnchorPosition_BottomCenterHorizontal() {
+        gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
+        testAnchorPosition()
+    }
+
+    @Test
+    fun testAnchorPosition_RightCenterVertical() {
+        gravity = Gravity.RIGHT or Gravity.CENTER_VERTICAL
+        testAnchorPosition()
+    }
+
+    @Test
+    fun testAnchorPosition_LeftCenterVertical() {
+        gravity = Gravity.LEFT or Gravity.CENTER_VERTICAL
+        testAnchorPosition()
+    }
+
+    fun testAnchorPosition() {
+        val placement = getActualPlacement()
+
+        assertEquals(getExpectedAnchorBounds(), placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun test_AnchorBottomRight_KeepClearNotObstructing_StayAtAnchor() {
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+
+        val sidebar = makeSideBar(DASHBOARD_WIDTH, Gravity.LEFT)
+        unrestrictedAreas.add(sidebar)
+
+        val expectedBounds = getExpectedAnchorBounds()
+
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun test_AnchorBottomRight_UnrestrictedRightSidebar_PushedLeft() {
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+
+        val sidebar = makeSideBar(DASHBOARD_WIDTH, Gravity.RIGHT)
+        unrestrictedAreas.add(sidebar)
+
+        val expectedBounds = anchorBoundsOffsetBy(SCREEN_EDGE_INSET - sidebar.width() - PADDING, 0)
+
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun test_AnchorTopRight_UnrestrictedRightSidebar_PushedLeft() {
+        gravity = Gravity.TOP or Gravity.RIGHT
+
+        val sidebar = makeSideBar(DASHBOARD_WIDTH, Gravity.RIGHT)
+        unrestrictedAreas.add(sidebar)
+
+        val expectedBounds = anchorBoundsOffsetBy(SCREEN_EDGE_INSET - sidebar.width() - PADDING, 0)
+
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun test_AnchorBottomLeft_UnrestrictedRightSidebar_StayAtAnchor() {
+        gravity = Gravity.BOTTOM or Gravity.LEFT
+
+        val sidebar = makeSideBar(DASHBOARD_WIDTH, Gravity.RIGHT)
+        unrestrictedAreas.add(sidebar)
+
+        val expectedBounds = anchorBoundsOffsetBy(0, 0)
+
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun test_AnchorBottom_UnrestrictedRightSidebar_StayAtAnchor() {
+        gravity = Gravity.BOTTOM
+
+        val sidebar = makeSideBar(DASHBOARD_WIDTH, Gravity.RIGHT)
+        unrestrictedAreas.add(sidebar)
+
+        val expectedBounds = anchorBoundsOffsetBy(0, 0)
+
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun testExpanded_AnchorBottom_UnrestrictedRightSidebar_StayAtAnchor() {
+        pipSize = EXPANDED_WIDE_PIP_SIZE
+        gravity = Gravity.BOTTOM
+
+        val sidebar = makeSideBar(DASHBOARD_WIDTH, Gravity.RIGHT)
+        unrestrictedAreas.add(sidebar)
+
+        val expectedBounds = anchorBoundsOffsetBy(0, 0)
+
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun test_AnchorBottomRight_RestrictedSmallBottomBar_PushedUp() {
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+
+        val bottomBar = makeBottomBar(96)
+        restrictedAreas.add(bottomBar)
+
+        val expectedBounds = anchorBoundsOffsetBy(0,
+                SCREEN_EDGE_INSET - bottomBar.height() - PADDING)
+
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun test_AnchorBottomRight_RestrictedBottomSheet_StashDownAtAnchor() {
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+
+        val bottomBar = makeBottomBar(BOTTOM_SHEET_HEIGHT)
+        restrictedAreas.add(bottomBar)
+
+        val expectedBounds = getExpectedAnchorBounds()
+        expectedBounds.offsetTo(expectedBounds.left, SCREEN_SIZE.height - STASH_OFFSET)
+
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertEquals(STASH_TYPE_BOTTOM, placement.stashType)
+        assertEquals(getExpectedAnchorBounds(), placement.unstashDestinationBounds)
+        assertEquals(algorithm.stashDuration, placement.unstashTime)
+    }
+
+    @Test
+    fun test_AnchorBottomRight_UnrestrictedBottomSheet_PushUp() {
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+
+        val bottomBar = makeBottomBar(BOTTOM_SHEET_HEIGHT)
+        unrestrictedAreas.add(bottomBar)
+
+        val expectedBounds = anchorBoundsOffsetBy(0,
+                SCREEN_EDGE_INSET - bottomBar.height() - PADDING)
+
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun test_AnchorBottomRight_UnrestrictedBottomSheet_RestrictedSidebar_StashAboveBottomSheet() {
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+
+        val bottomBar = makeBottomBar(BOTTOM_SHEET_HEIGHT)
+        unrestrictedAreas.add(bottomBar)
+
+        val maxRestrictedHorizontalPush =
+                (algorithm.maxRestrictedDistanceFraction * SCREEN_SIZE.width).toInt()
+        val sideBar = makeSideBar(maxRestrictedHorizontalPush + 100, Gravity.RIGHT)
+        restrictedAreas.add(sideBar)
+
+        val expectedUnstashBounds =
+                anchorBoundsOffsetBy(0, SCREEN_EDGE_INSET - bottomBar.height() - PADDING)
+
+        val expectedBounds = Rect(expectedUnstashBounds)
+        expectedBounds.offsetTo(SCREEN_SIZE.width - STASH_OFFSET, expectedBounds.top)
+
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertEquals(STASH_TYPE_RIGHT, placement.stashType)
+        assertEquals(expectedUnstashBounds, placement.unstashDestinationBounds)
+        assertEquals(algorithm.stashDuration, placement.unstashTime)
+    }
+
+    @Test
+    fun test_AnchorBottomRight_UnrestrictedBottomSheet_UnrestrictedSidebar_PushUpLeft() {
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+
+        val bottomBar = makeBottomBar(BOTTOM_SHEET_HEIGHT)
+        unrestrictedAreas.add(bottomBar)
+
+        val maxRestrictedHorizontalPush =
+                (algorithm.maxRestrictedDistanceFraction * SCREEN_SIZE.width).toInt()
+        val sideBar = makeSideBar(maxRestrictedHorizontalPush + 100, Gravity.RIGHT)
+        unrestrictedAreas.add(sideBar)
+
+        val expectedBounds = anchorBoundsOffsetBy(
+                SCREEN_EDGE_INSET - sideBar.width() - PADDING,
+                SCREEN_EDGE_INSET - bottomBar.height() - PADDING
+        )
+
+        val placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun test_Stashed_UnstashBoundsBecomeUnobstructed_Unstashes() {
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+
+        val bottomBar = makeBottomBar(BOTTOM_SHEET_HEIGHT)
+        unrestrictedAreas.add(bottomBar)
+
+        val maxRestrictedHorizontalPush =
+                (algorithm.maxRestrictedDistanceFraction * SCREEN_SIZE.width).toInt()
+        val sideBar = makeSideBar(maxRestrictedHorizontalPush + 100, Gravity.RIGHT)
+        restrictedAreas.add(sideBar)
+
+        val expectedUnstashBounds =
+                anchorBoundsOffsetBy(0, SCREEN_EDGE_INSET - bottomBar.height() - PADDING)
+
+        val expectedBounds = Rect(expectedUnstashBounds)
+        expectedBounds.offsetTo(SCREEN_SIZE.width - STASH_OFFSET, expectedBounds.top)
+
+        var placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertEquals(STASH_TYPE_RIGHT, placement.stashType)
+        assertEquals(expectedUnstashBounds, placement.unstashDestinationBounds)
+        assertEquals(algorithm.stashDuration, placement.unstashTime)
+
+        currentTime += 1000
+
+        restrictedAreas.remove(sideBar)
+        placement = getActualPlacement()
+        assertEquals(expectedUnstashBounds, placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun test_Stashed_UnstashBoundsStaysObstructed_UnstashesAfterTimeout() {
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+
+        val bottomBar = makeBottomBar(BOTTOM_SHEET_HEIGHT)
+        unrestrictedAreas.add(bottomBar)
+
+        val maxRestrictedHorizontalPush =
+                (algorithm.maxRestrictedDistanceFraction * SCREEN_SIZE.width).toInt()
+        val sideBar = makeSideBar(maxRestrictedHorizontalPush + 100, Gravity.RIGHT)
+        restrictedAreas.add(sideBar)
+
+        val expectedUnstashBounds =
+                anchorBoundsOffsetBy(0, SCREEN_EDGE_INSET - bottomBar.height() - PADDING)
+
+        val expectedBounds = Rect(expectedUnstashBounds)
+        expectedBounds.offsetTo(SCREEN_SIZE.width - STASH_OFFSET, expectedBounds.top)
+
+        var placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertEquals(STASH_TYPE_RIGHT, placement.stashType)
+        assertEquals(expectedUnstashBounds, placement.unstashDestinationBounds)
+        assertEquals(algorithm.stashDuration, placement.unstashTime)
+
+        currentTime += algorithm.stashDuration
+
+        placement = getActualPlacement()
+        assertEquals(expectedUnstashBounds, placement.bounds)
+        assertNotStashed(placement)
+    }
+
+    @Test
+    fun test_Stashed_UnstashBoundsObstructionChanges_UnstashTimeExtended() {
+        gravity = Gravity.BOTTOM or Gravity.RIGHT
+
+        val bottomBar = makeBottomBar(BOTTOM_SHEET_HEIGHT)
+        unrestrictedAreas.add(bottomBar)
+
+        val maxRestrictedHorizontalPush =
+                (algorithm.maxRestrictedDistanceFraction * SCREEN_SIZE.width).toInt()
+        val sideBar = makeSideBar(maxRestrictedHorizontalPush + 100, Gravity.RIGHT)
+        restrictedAreas.add(sideBar)
+
+        val expectedUnstashBounds =
+                anchorBoundsOffsetBy(0, SCREEN_EDGE_INSET - bottomBar.height() - PADDING)
+
+        val expectedBounds = Rect(expectedUnstashBounds)
+        expectedBounds.offsetTo(SCREEN_SIZE.width - STASH_OFFSET, expectedBounds.top)
+
+        var placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertEquals(STASH_TYPE_RIGHT, placement.stashType)
+        assertEquals(expectedUnstashBounds, placement.unstashDestinationBounds)
+        assertEquals(algorithm.stashDuration, placement.unstashTime)
+
+        currentTime += 1000
+
+        val newObstruction = Rect(
+                0,
+                expectedUnstashBounds.top,
+                expectedUnstashBounds.right,
+                expectedUnstashBounds.bottom
+        )
+        restrictedAreas.add(newObstruction)
+
+        placement = getActualPlacement()
+        assertEquals(expectedBounds, placement.bounds)
+        assertEquals(STASH_TYPE_RIGHT, placement.stashType)
+        assertEquals(expectedUnstashBounds, placement.unstashDestinationBounds)
+        assertEquals(currentTime + algorithm.stashDuration, placement.unstashTime)
+    }
+
+    private fun makeSideBar(width: Int, @Gravity.GravityFlags side: Int): Rect {
+        val sidebar = Rect(0, 0, width, SCREEN_SIZE.height)
+        if (side == Gravity.RIGHT) {
+            sidebar.offsetTo(SCREEN_SIZE.width - width, 0)
+        }
+        return sidebar
+    }
+
+    private fun makeBottomBar(height: Int): Rect {
+        return Rect(0, SCREEN_SIZE.height - height, SCREEN_SIZE.width, SCREEN_SIZE.height)
+    }
+
+    private fun getExpectedAnchorBounds(): Rect {
+        val expectedBounds = Rect()
+        Gravity.apply(gravity, pipSize.width, pipSize.height, movementBounds, expectedBounds)
+        return expectedBounds
+    }
+
+    private fun anchorBoundsOffsetBy(dx: Int, dy: Int): Rect {
+        val bounds = getExpectedAnchorBounds()
+        bounds.offset(dx, dy)
+        return bounds
+    }
+
+    private fun getActualPlacement(): Placement {
+        algorithm.setGravity(gravity)
+        return algorithm.calculatePipPosition(pipSize, restrictedAreas, unrestrictedAreas)
+    }
+
+    private fun assertNotStashed(actual: Placement) {
+        assertEquals(STASH_TYPE_NONE, actual.stashType)
+        assertNull(actual.unstashDestinationBounds)
+        assertEquals(0L, actual.unstashTime)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
index 13b726e..157c30b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
@@ -62,7 +62,7 @@
 @RunWith(AndroidJUnit4.class)
 public final class StageTaskListenerTests extends ShellTestCase {
     private static final boolean ENABLE_SHELL_TRANSITIONS =
-            SystemProperties.getBoolean("persist.debug.shell_transit", false);
+            SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
 
     @Mock
     private ShellTaskOrganizer mTaskOrganizer;
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index 63b831d..c80fb18 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -118,7 +118,7 @@
                 "libz",
             ],
         },
-        linux_glibc: {
+        host_linux: {
             srcs: [
                 "CursorWindow.cpp",
             ],
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index f6ad4c2..ece150a 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -535,7 +535,10 @@
 
     target: {
         android: {
-            header_libs: ["libandroid_headers_private"],
+            header_libs: [
+                "libandroid_headers_private",
+                "libtonemap_headers",
+            ],
 
             srcs: [
                 "hwui/AnimatedImageThread.cpp",
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index bcfe9c3..30ca7d15 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -135,7 +135,7 @@
     skpCaptureEnabled = debuggingEnabled && base::GetBoolProperty(PROPERTY_CAPTURE_SKP_ENABLED, false);
 
     SkAndroidFrameworkTraceUtil::setEnableTracing(
-            base::GetBoolProperty(PROPERTY_SKIA_ATRACE_ENABLED, false));
+            base::GetBoolProperty(PROPERTY_SKIA_ATRACE_ENABLED, true));
 
     runningInEmulator = base::GetBoolProperty(PROPERTY_IS_EMULATOR, false);
 
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index fd6e6e9..99508a2 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -48,8 +48,6 @@
     TRANSACTION_isObbMounted,
     TRANSACTION_getMountedObbPath,
     TRANSACTION_isExternalStorageEmulated,
-    TRANSACTION_decryptStorage,
-    TRANSACTION_encryptStorage,
 };
 
 class BpMountService: public BpInterface<IMountService>
@@ -442,14 +440,13 @@
         reply.readExceptionCode();
     }
 
-    void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key,
+    void mountObb(const String16& rawPath, const String16& canonicalPath,
             const sp<IObbActionListener>& token, int32_t nonce, const sp<ObbInfo>& obbInfo)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
         data.writeString16(rawPath);
         data.writeString16(canonicalPath);
-        data.writeString16(key);
         data.writeStrongBinder(IInterface::asBinder(token));
         data.writeInt32(nonce);
         obbInfo->writeToParcel(&data);
@@ -518,40 +515,6 @@
         path = reply.readString16();
         return true;
     }
-
-    int32_t decryptStorage(const String16& password)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
-        data.writeString16(password);
-        if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) {
-            ALOGD("decryptStorage could not contact remote\n");
-            return -1;
-        }
-        int32_t err = reply.readExceptionCode();
-        if (err < 0) {
-            ALOGD("decryptStorage caught exception %d\n", err);
-            return err;
-        }
-        return reply.readInt32();
-    }
-
-    int32_t encryptStorage(const String16& password)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
-        data.writeString16(password);
-        if (remote()->transact(TRANSACTION_encryptStorage, data, &reply) != NO_ERROR) {
-            ALOGD("encryptStorage could not contact remote\n");
-            return -1;
-        }
-        int32_t err = reply.readExceptionCode();
-        if (err < 0) {
-            ALOGD("encryptStorage caught exception %d\n", err);
-            return err;
-        }
-        return reply.readInt32();
-    }
 };
 
 IMPLEMENT_META_INTERFACE(MountService, "android.os.storage.IStorageManager")
diff --git a/libs/storage/include/storage/IMountService.h b/libs/storage/include/storage/IMountService.h
index 2463e02..5a9c39b 100644
--- a/libs/storage/include/storage/IMountService.h
+++ b/libs/storage/include/storage/IMountService.h
@@ -64,14 +64,12 @@
     virtual void shutdown(const sp<IMountShutdownObserver>& observer) = 0;
     virtual void finishMediaUpdate() = 0;
     virtual void mountObb(const String16& rawPath, const String16& canonicalPath,
-            const String16& key, const sp<IObbActionListener>& token,
-            const int32_t nonce, const sp<ObbInfo>& obbInfo) = 0;
+            const sp<IObbActionListener>& token, const int32_t nonce,
+            const sp<ObbInfo>& obbInfo) = 0;
     virtual void unmountObb(const String16& filename, const bool force,
             const sp<IObbActionListener>& token, const int32_t nonce) = 0;
     virtual bool isObbMounted(const String16& filename) = 0;
     virtual bool getMountedObbPath(const String16& filename, String16& path) = 0;
-    virtual int32_t decryptStorage(const String16& password) = 0;
-    virtual int32_t encryptStorage(const String16& password) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 3a2f0d9..1a56b15 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -6952,7 +6952,8 @@
         for (Integer format : formatsList) {
             int btSourceCodec = AudioSystem.audioFormatToBluetoothSourceCodec(format);
             if (btSourceCodec != BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID) {
-                codecConfigList.add(new BluetoothCodecConfig(btSourceCodec));
+                codecConfigList.add(
+                        new BluetoothCodecConfig.Builder().setCodecType(btSourceCodec).build());
             }
         }
         return codecConfigList;
@@ -8450,6 +8451,22 @@
         }
     }
 
+    /**
+     * Returns the audio HAL version in the form MAJOR.MINOR. If there is no audio HAL found, null
+     * will be returned.
+     *
+     * @hide
+     */
+    @TestApi
+    public static @Nullable String getHalVersion() {
+        try {
+            return getService().getHalVersion();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error querying getHalVersion", e);
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private final Object mMuteAwaitConnectionListenerLock = new Object();
 
     @GuardedBy("mMuteAwaitConnectionListenerLock")
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index fa3057a..bdbb740 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -480,7 +480,6 @@
 
     boolean sendFocusLoss(in AudioFocusInfo focusLoser, in IAudioPolicyCallback apcb);
 
-
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
     void addAssistantServicesUids(in int[] assistantUID);
 
@@ -501,4 +500,6 @@
             in IAudioDeviceVolumeDispatcher cb,
             in String packageName,
             in AudioDeviceAttributes device, in List<VolumeInfo> volumes);
+
+    String getHalVersion();
 }
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 311476c..d8995b4 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -76,6 +76,7 @@
 
     @GuardedBy("sSystemRouterLock")
     private static Map<String, MediaRouter2> sSystemMediaRouter2Map = new ArrayMap<>();
+
     private static MediaRouter2Manager sManager;
 
     @GuardedBy("sRouterLock")
@@ -119,14 +120,12 @@
     private final AtomicInteger mNextRequestId = new AtomicInteger(1);
 
     final Handler mHandler;
-    @GuardedBy("mLock")
-    private boolean mShouldUpdateRoutes = true;
+
+    private volatile ArrayMap<String, MediaRoute2Info> mPreviousRoutes = new ArrayMap<>();
     private volatile List<MediaRoute2Info> mFilteredRoutes = Collections.emptyList();
     private volatile OnGetControllerHintsListener mOnGetControllerHintsListener;
 
-    /**
-     * Gets an instance of the media router associated with the context.
-     */
+    /** Gets an instance of the media router associated with the context. */
     @NonNull
     public static MediaRouter2 getInstance(@NonNull Context context) {
         Objects.requireNonNull(context, "context must not be null");
@@ -139,29 +138,31 @@
     }
 
     /**
-     * Gets an instance of the system media router which controls the app's media routing.
-     * Returns {@code null} if the given package name is invalid.
-     * There are several things to note when using the media routers created with this method.
-     * <p>
-     * First of all, the discovery preference passed to {@link #registerRouteCallback}
-     * will have no effect. The callback will be called accordingly with the client app's
-     * discovery preference. Therefore, it is recommended to pass
-     * {@link RouteDiscoveryPreference#EMPTY} there.
-     * <p>
-     * Also, do not keep/compare the instances of the {@link RoutingController}, since they are
+     * Gets an instance of the system media router which controls the app's media routing. Returns
+     * {@code null} if the given package name is invalid. There are several things to note when
+     * using the media routers created with this method.
+     *
+     * <p>First of all, the discovery preference passed to {@link #registerRouteCallback} will have
+     * no effect. The callback will be called accordingly with the client app's discovery
+     * preference. Therefore, it is recommended to pass {@link RouteDiscoveryPreference#EMPTY}
+     * there.
+     *
+     * <p>Also, do not keep/compare the instances of the {@link RoutingController}, since they are
      * always newly created with the latest session information whenever below methods are called:
+     *
      * <ul>
-     * <li> {@link #getControllers()} </li>
-     * <li> {@link #getController(String)}} </li>
-     * <li> {@link TransferCallback#onTransfer(RoutingController, RoutingController)} </li>
-     * <li> {@link TransferCallback#onStop(RoutingController)} </li>
-     * <li> {@link ControllerCallback#onControllerUpdated(RoutingController)} </li>
+     *   <li>{@link #getControllers()}
+     *   <li>{@link #getController(String)}}
+     *   <li>{@link TransferCallback#onTransfer(RoutingController, RoutingController)}
+     *   <li>{@link TransferCallback#onStop(RoutingController)}
+     *   <li>{@link ControllerCallback#onControllerUpdated(RoutingController)}
      * </ul>
+     *
      * Therefore, in order to track the current routing status, keep the controller's ID instead,
-     * and use {@link #getController(String)} and {@link #getSystemController()} for
-     * getting controllers.
-     * <p>
-     * Finally, it will have no effect to call {@link #setOnGetControllerHintsListener}.
+     * and use {@link #getController(String)} and {@link #getSystemController()} for getting
+     * controllers.
+     *
+     * <p>Finally, it will have no effect to call {@link #setOnGetControllerHintsListener}.
      *
      * @param clientPackageName the package name of the app to control
      * @throws SecurityException if the caller doesn't have MODIFY_AUDIO_ROUTING permission.
@@ -170,15 +171,16 @@
     @SystemApi
     @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
     @Nullable
-    public static MediaRouter2 getInstance(@NonNull Context context,
-            @NonNull String clientPackageName) {
+    public static MediaRouter2 getInstance(
+            @NonNull Context context, @NonNull String clientPackageName) {
         Objects.requireNonNull(context, "context must not be null");
         Objects.requireNonNull(clientPackageName, "clientPackageName must not be null");
 
         // Note: Even though this check could be somehow bypassed, the other permission checks
         // in system server will not allow MediaRouter2Manager to be registered.
-        IMediaRouterService serviceBinder = IMediaRouterService.Stub.asInterface(
-                ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
+        IMediaRouterService serviceBinder =
+                IMediaRouterService.Stub.asInterface(
+                        ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
         try {
             // SecurityException will be thrown if there's no permission.
             serviceBinder.enforceMediaContentControlPermission();
@@ -212,17 +214,17 @@
 
     /**
      * Starts scanning remote routes.
-     * <p>
-     * Route discovery can happen even when the {@link #startScan()} is not called.
-     * This is because the scanning could be started before by other apps.
-     * Therefore, calling this method after calling {@link #stopScan()} does not necessarily mean
-     * that the routes found before are removed and added again.
-     * <p>
-     * Use {@link RouteCallback} to get the route related events.
-     * <p>
-     * Note that calling start/stopScan is applied to all system routers in the same process.
-     * <p>
-     * This will be no-op for non-system media routers.
+     *
+     * <p>Route discovery can happen even when the {@link #startScan()} is not called. This is
+     * because the scanning could be started before by other apps. Therefore, calling this method
+     * after calling {@link #stopScan()} does not necessarily mean that the routes found before are
+     * removed and added again.
+     *
+     * <p>Use {@link RouteCallback} to get the route related events.
+     *
+     * <p>Note that calling start/stopScan is applied to all system routers in the same process.
+     *
+     * <p>This will be no-op for non-system media routers.
      *
      * @see #stopScan()
      * @see #getInstance(Context, String)
@@ -238,18 +240,17 @@
 
     /**
      * Stops scanning remote routes to reduce resource consumption.
-     * <p>
-     * Route discovery can be continued even after this method is called.
-     * This is because the scanning is only turned off when all the apps stop scanning.
-     * Therefore, calling this method does not necessarily mean the routes are removed.
-     * Also, for the same reason it does not mean that {@link RouteCallback#onRoutesAdded(List)}
-     * is not called afterwards.
-     * <p>
-     * Use {@link RouteCallback} to get the route related events.
-     * <p>
-     * Note that calling start/stopScan is applied to all system routers in the same process.
-     * <p>
-     * This will be no-op for non-system media routers.
+     *
+     * <p>Route discovery can be continued even after this method is called. This is because the
+     * scanning is only turned off when all the apps stop scanning. Therefore, calling this method
+     * does not necessarily mean the routes are removed. Also, for the same reason it does not mean
+     * that {@link RouteCallback#onRoutesAdded(List)} is not called afterwards.
+     *
+     * <p>Use {@link RouteCallback} to get the route related events.
+     *
+     * <p>Note that calling start/stopScan is applied to all system routers in the same process.
+     *
+     * <p>This will be no-op for non-system media routers.
      *
      * @see #startScan()
      * @see #getInstance(Context, String)
@@ -265,8 +266,9 @@
 
     private MediaRouter2(Context appContext) {
         mContext = appContext;
-        mMediaRouterService = IMediaRouterService.Stub.asInterface(
-                ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
+        mMediaRouterService =
+                IMediaRouterService.Stub.asInterface(
+                        ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
         mPackageName = mContext.getPackageName();
         mHandler = new Handler(Looper.getMainLooper());
 
@@ -302,9 +304,10 @@
         mClientPackageName = clientPackageName;
         mManagerCallback = new ManagerCallback();
         mHandler = new Handler(Looper.getMainLooper());
-        mSystemController = new SystemRoutingController(
-                ensureClientPackageNameForSystemSession(
-                        sManager.getSystemRoutingSession(clientPackageName)));
+        mSystemController =
+                new SystemRoutingController(
+                        ensureClientPackageNameForSystemSession(
+                                sManager.getSystemRoutingSession(clientPackageName)));
         mDiscoveryPreference = sManager.getDiscoveryPreference(clientPackageName);
         updateAllRoutesFromManager();
 
@@ -318,8 +321,8 @@
      *
      * @hide
      */
-    static boolean checkRouteListContainsRouteId(@NonNull List<MediaRoute2Info> routeList,
-            @NonNull String routeId) {
+    static boolean checkRouteListContainsRouteId(
+            @NonNull List<MediaRoute2Info> routeList, @NonNull String routeId) {
         for (MediaRoute2Info info : routeList) {
             if (TextUtils.equals(routeId, info.getId())) {
                 return true;
@@ -330,8 +333,8 @@
 
     /**
      * Gets the client package name of the app which this media router controls.
-     * <p>
-     * This will return null for non-system media routers.
+     *
+     * <p>This will return null for non-system media routers.
      *
      * @see #getInstance(Context, String)
      * @hide
@@ -344,12 +347,12 @@
 
     /**
      * Registers a callback to discover routes and to receive events when they change.
-     * <p>
-     * If the specified callback is already registered, its registration will be updated for the
+     *
+     * <p>If the specified callback is already registered, its registration will be updated for the
      * given {@link Executor executor} and {@link RouteDiscoveryPreference discovery preference}.
-     * </p>
      */
-    public void registerRouteCallback(@NonNull @CallbackExecutor Executor executor,
+    public void registerRouteCallback(
+            @NonNull @CallbackExecutor Executor executor,
             @NonNull RouteCallback routeCallback,
             @NonNull RouteDiscoveryPreference preference) {
         Objects.requireNonNull(executor, "executor must not be null");
@@ -391,8 +394,8 @@
     }
 
     /**
-     * Unregisters the given callback. The callback will no longer receive events.
-     * If the callback has not been added or been removed already, it is ignored.
+     * Unregisters the given callback. The callback will no longer receive events. If the callback
+     * has not been added or been removed already, it is ignored.
      *
      * @param routeCallback the callback to unregister
      * @see #registerRouteCallback
@@ -400,8 +403,7 @@
     public void unregisterRouteCallback(@NonNull RouteCallback routeCallback) {
         Objects.requireNonNull(routeCallback, "callback must not be null");
 
-        if (!mRouteCallbackRecords.remove(
-                new RouteCallbackRecord(null, routeCallback, null))) {
+        if (!mRouteCallbackRecords.remove(new RouteCallbackRecord(null, routeCallback, null))) {
             Log.w(TAG, "unregisterRouteCallback: Ignoring unknown callback");
             return;
         }
@@ -416,8 +418,7 @@
             }
             if (updateDiscoveryPreferenceIfNeededLocked()) {
                 try {
-                    mMediaRouterService.setDiscoveryRequestWithRouter2(
-                            mStub, mDiscoveryPreference);
+                    mMediaRouterService.setDiscoveryRequestWithRouter2(mStub, mDiscoveryPreference);
                 } catch (RemoteException ex) {
                     Log.e(TAG, "unregisterRouteCallback: Unable to set discovery request.", ex);
                 }
@@ -430,27 +431,28 @@
                 }
                 mStub = null;
             }
-            mShouldUpdateRoutes = true;
         }
     }
 
+    @GuardedBy("mLock")
     private boolean updateDiscoveryPreferenceIfNeededLocked() {
         RouteDiscoveryPreference newDiscoveryPreference = new RouteDiscoveryPreference.Builder(
                 mRouteCallbackRecords.stream().map(record -> record.mPreference).collect(
                         Collectors.toList())).build();
+
         if (Objects.equals(mDiscoveryPreference, newDiscoveryPreference)) {
             return false;
         }
         mDiscoveryPreference = newDiscoveryPreference;
-        mShouldUpdateRoutes = true;
+        updateFilteredRoutesLocked();
         return true;
     }
 
     /**
-     * Gets the list of all discovered routes.
-     * This list includes the routes that are not related to the client app.
-     * <p>
-     * This will return an empty list for non-system media routers.
+     * Gets the list of all discovered routes. This list includes the routes that are not related to
+     * the client app.
+     *
+     * <p>This will return an empty list for non-system media routers.
      *
      * @hide
      */
@@ -464,25 +466,19 @@
     }
 
     /**
-     * Gets the unmodifiable list of {@link MediaRoute2Info routes} currently
-     * known to the media router.
-     * <p>
-     * Please note that the list can be changed before callbacks are invoked.
-     * </p>
+     * Gets the unmodifiable list of {@link MediaRoute2Info routes} currently known to the media
+     * router.
+     *
+     * <p>Please note that the list can be changed before callbacks are invoked.
+     *
      * @return the list of routes that contains at least one of the route features in discovery
-     * preferences registered by the application
+     *     preferences registered by the application
      */
     @NonNull
     public List<MediaRoute2Info> getRoutes() {
         synchronized (mLock) {
-            if (mShouldUpdateRoutes) {
-                mShouldUpdateRoutes = false;
-
-                mFilteredRoutes = Collections.unmodifiableList(
-                        filterRoutes(List.copyOf(mRoutes.values()), mDiscoveryPreference));
-            }
+            return mFilteredRoutes;
         }
-        return mFilteredRoutes;
     }
 
     /**
@@ -493,8 +489,8 @@
      * @param callback the callback to register
      * @see #unregisterTransferCallback
      */
-    public void registerTransferCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull TransferCallback callback) {
+    public void registerTransferCallback(
+            @NonNull @CallbackExecutor Executor executor, @NonNull TransferCallback callback) {
         Objects.requireNonNull(executor, "executor must not be null");
         Objects.requireNonNull(callback, "callback must not be null");
 
@@ -522,12 +518,13 @@
     }
 
     /**
-     * Registers a {@link ControllerCallback}.
-     * If you register the same callback twice or more, it will be ignored.
+     * Registers a {@link ControllerCallback}. If you register the same callback twice or more, it
+     * will be ignored.
+     *
      * @see #unregisterControllerCallback(ControllerCallback)
      */
-    public void registerControllerCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull ControllerCallback callback) {
+    public void registerControllerCallback(
+            @NonNull @CallbackExecutor Executor executor, @NonNull ControllerCallback callback) {
         Objects.requireNonNull(executor, "executor must not be null");
         Objects.requireNonNull(callback, "callback must not be null");
 
@@ -539,12 +536,12 @@
     }
 
     /**
-     * Unregisters a {@link ControllerCallback}. The callback will no longer receive
-     * events. If the callback has not been added or been removed already, it is ignored.
+     * Unregisters a {@link ControllerCallback}. The callback will no longer receive events.
+     * If the callback has not been added or been removed already, it is ignored.
+     *
      * @see #registerControllerCallback(Executor, ControllerCallback)
      */
-    public void unregisterControllerCallback(
-            @NonNull ControllerCallback callback) {
+    public void unregisterControllerCallback(@NonNull ControllerCallback callback) {
         Objects.requireNonNull(callback, "callback must not be null");
 
         if (!mControllerCallbackRecords.remove(new ControllerCallbackRecord(null, callback))) {
@@ -559,7 +556,7 @@
      * {@link #transferTo(MediaRoute2Info)}.
      *
      * @param listener A listener to send optional app-specific hints when creating a controller.
-     *                 {@code null} for unset.
+     *     {@code null} for unset.
      */
     public void setOnGetControllerHintsListener(@Nullable OnGetControllerHintsListener listener) {
         if (isSystemRouter()) {
@@ -569,13 +566,11 @@
     }
 
     /**
-     * Transfers the current media to the given route.
-     * If it's necessary a new {@link RoutingController} is created or it is handled within
-     * the current routing controller.
+     * Transfers the current media to the given route. If it's necessary a new
+     * {@link RoutingController} is created or it is handled within the current routing controller.
      *
      * @param route the route you want to transfer the current media to. Pass {@code null} to
      *              stop routing of the current media.
-     *
      * @see TransferCallback#onTransfer
      * @see TransferCallback#onTransferFailure
      */
@@ -622,8 +617,8 @@
 
     /**
      * Transfers the media of a routing controller to the given route.
-     * <p>
-     * This will be no-op for non-system media routers.
+     *
+     * <p>This will be no-op for non-system media routers.
      *
      * @param controller a routing controller controlling media routing.
      * @param route the route you want to transfer the media to.
@@ -638,13 +633,15 @@
         }
     }
 
-    void requestCreateController(@NonNull RoutingController controller,
-            @NonNull MediaRoute2Info route, long managerRequestId) {
+    void requestCreateController(
+            @NonNull RoutingController controller,
+            @NonNull MediaRoute2Info route,
+            long managerRequestId) {
 
         final int requestId = mNextRequestId.getAndIncrement();
 
-        ControllerCreationRequest request = new ControllerCreationRequest(requestId,
-                managerRequestId, route, controller);
+        ControllerCreationRequest request =
+                new ControllerCreationRequest(requestId, managerRequestId, route, controller);
         mControllerCreationRequests.add(request);
 
         OnGetControllerHintsListener listener = mOnGetControllerHintsListener;
@@ -663,11 +660,15 @@
         if (stub != null) {
             try {
                 mMediaRouterService.requestCreateSessionWithRouter2(
-                        stub, requestId, managerRequestId,
-                        controller.getRoutingSessionInfo(), route, controllerHints);
+                        stub,
+                        requestId,
+                        managerRequestId,
+                        controller.getRoutingSessionInfo(),
+                        route,
+                        controllerHints);
             } catch (RemoteException ex) {
                 Log.e(TAG, "createControllerForTransfer: "
-                        + "Failed to request for creating a controller.", ex);
+                                + "Failed to request for creating a controller.", ex);
                 mControllerCreationRequests.remove(request);
                 if (managerRequestId == MANAGER_REQUEST_ID_NONE) {
                     notifyTransferFailure(route);
@@ -685,11 +686,11 @@
     /**
      * Gets a {@link RoutingController} which can control the routes provided by system.
      * e.g. Phone speaker, wired headset, Bluetooth, etc.
-     * <p>
-     * Note: The system controller can't be released. Calling {@link RoutingController#release()}
+     *
+     * <p>Note: The system controller can't be released. Calling {@link RoutingController#release()}
      * will be ignored.
-     * <p>
-     * This method always returns the same instance.
+     *
+     * <p>This method always returns the same instance.
      */
     @NonNull
     public RoutingController getSystemController() {
@@ -714,8 +715,8 @@
     /**
      * Gets the list of currently active {@link RoutingController routing controllers} on which
      * media can be played.
-     * <p>
-     * Note: The list returned here will never be empty. The first element in the list is
+     *
+     * <p>Note: The list returned here will never be empty. The first element in the list is
      * always the {@link #getSystemController() system controller}.
      */
     @NonNull
@@ -750,8 +751,8 @@
     /**
      * Requests a volume change for the route asynchronously.
      * It may have no effect if the route is currently not selected.
-     * <p>
-     * This will be no-op for non-system media routers.
+     *
+     * <p>This will be no-op for non-system media routers.
      *
      * @param volume The new volume value between 0 and {@link MediaRoute2Info#getVolumeMax}.
      * @see #getInstance(Context, String)
@@ -769,65 +770,20 @@
         // If this API needs to be public, use IMediaRouterService#setRouteVolumeWithRouter2()
     }
 
-    void syncRoutesOnHandler(List<MediaRoute2Info> currentRoutes,
-            RoutingSessionInfo currentSystemSessionInfo) {
+    void syncRoutesOnHandler(
+            List<MediaRoute2Info> currentRoutes, RoutingSessionInfo currentSystemSessionInfo) {
         if (currentRoutes == null || currentRoutes.isEmpty() || currentSystemSessionInfo == null) {
             Log.e(TAG, "syncRoutesOnHandler: Received wrong data. currentRoutes=" + currentRoutes
                     + ", currentSystemSessionInfo=" + currentSystemSessionInfo);
             return;
         }
 
-        List<MediaRoute2Info> addedRoutes = new ArrayList<>();
-        List<MediaRoute2Info> removedRoutes = new ArrayList<>();
-        List<MediaRoute2Info> changedRoutes = new ArrayList<>();
-
         synchronized (mLock) {
-            List<String> currentRoutesIds = currentRoutes.stream().map(MediaRoute2Info::getId)
-                    .collect(Collectors.toList());
-
-            for (String routeId : mRoutes.keySet()) {
-                if (!currentRoutesIds.contains(routeId)) {
-                    // This route is removed while the callback is unregistered.
-                    MediaRoute2Info route = mRoutes.get(routeId);
-                    if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
-                        removedRoutes.add(mRoutes.get(routeId));
-                    }
-                }
-            }
-
-            for (MediaRoute2Info route : currentRoutes) {
-                if (mRoutes.containsKey(route.getId())) {
-                    if (!route.equals(mRoutes.get(route.getId()))) {
-                        // This route is changed while the callback is unregistered.
-                        if (route.hasAnyFeatures(
-                                        mDiscoveryPreference.getPreferredFeatures())) {
-                            changedRoutes.add(route);
-                        }
-                    }
-                } else {
-                    // This route is added while the callback is unregistered.
-                    if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
-                        addedRoutes.add(route);
-                    }
-                }
-            }
-
             mRoutes.clear();
             for (MediaRoute2Info route : currentRoutes) {
                 mRoutes.put(route.getId(), route);
             }
-
-            mShouldUpdateRoutes = true;
-        }
-
-        if (!addedRoutes.isEmpty()) {
-            notifyRoutesAdded(addedRoutes);
-        }
-        if (!removedRoutes.isEmpty()) {
-            notifyRoutesRemoved(removedRoutes);
-        }
-        if (!changedRoutes.isEmpty()) {
-            notifyRoutesChanged(changedRoutes);
+            updateFilteredRoutesLocked();
         }
 
         RoutingSessionInfo oldInfo = mSystemController.getRoutingSessionInfo();
@@ -837,35 +793,66 @@
         }
     }
 
-    void addRoutesOnHandler(List<MediaRoute2Info> routes) {
+    void dispatchFilteredRoutesChangedLocked(List<MediaRoute2Info> newRoutes) {
         List<MediaRoute2Info> addedRoutes = new ArrayList<>();
+        List<MediaRoute2Info> removedRoutes = new ArrayList<>();
+        List<MediaRoute2Info> changedRoutes = new ArrayList<>();
+
+        Set<String> newRouteIds =
+                newRoutes.stream().map(MediaRoute2Info::getId).collect(Collectors.toSet());
+
+        for (MediaRoute2Info route : newRoutes) {
+            MediaRoute2Info prevRoute = mPreviousRoutes.get(route.getId());
+            if (prevRoute == null) {
+                addedRoutes.add(route);
+            } else if (!prevRoute.equals(route)) {
+                changedRoutes.add(route);
+            }
+        }
+
+        for (int i = 0; i < mPreviousRoutes.size(); i++) {
+            if (!newRouteIds.contains(mPreviousRoutes.keyAt(i))) {
+                removedRoutes.add(mPreviousRoutes.valueAt(i));
+            }
+        }
+
+        // update previous routes
+        for (MediaRoute2Info route : removedRoutes) {
+            mPreviousRoutes.remove(route.getId());
+        }
+        for (MediaRoute2Info route : addedRoutes) {
+            mPreviousRoutes.put(route.getId(), route);
+        }
+        for (MediaRoute2Info route : changedRoutes) {
+            mPreviousRoutes.put(route.getId(), route);
+        }
+
+        if (!addedRoutes.isEmpty()) {
+            notifyRoutesAdded(addedRoutes);
+        }
+        if (!removedRoutes.isEmpty()) {
+            notifyRoutesRemoved(removedRoutes);
+        }
+        if (!changedRoutes.isEmpty()) {
+            notifyRoutesChanged(changedRoutes);
+        }
+    }
+
+    void addRoutesOnHandler(List<MediaRoute2Info> routes) {
         synchronized (mLock) {
             for (MediaRoute2Info route : routes) {
                 mRoutes.put(route.getId(), route);
-                if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
-                    addedRoutes.add(route);
-                }
             }
-            mShouldUpdateRoutes = true;
-        }
-        if (!addedRoutes.isEmpty()) {
-            notifyRoutesAdded(addedRoutes);
+            updateFilteredRoutesLocked();
         }
     }
 
     void removeRoutesOnHandler(List<MediaRoute2Info> routes) {
-        List<MediaRoute2Info> removedRoutes = new ArrayList<>();
         synchronized (mLock) {
             for (MediaRoute2Info route : routes) {
                 mRoutes.remove(route.getId());
-                if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
-                    removedRoutes.add(route);
-                }
             }
-            mShouldUpdateRoutes = true;
-        }
-        if (!removedRoutes.isEmpty()) {
-            notifyRoutesRemoved(removedRoutes);
+            updateFilteredRoutesLocked();
         }
     }
 
@@ -874,23 +861,27 @@
         synchronized (mLock) {
             for (MediaRoute2Info route : routes) {
                 mRoutes.put(route.getId(), route);
-                if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
-                    changedRoutes.add(route);
-                }
             }
-            mShouldUpdateRoutes = true;
-        }
-        if (!changedRoutes.isEmpty()) {
-            notifyRoutesChanged(changedRoutes);
+            updateFilteredRoutesLocked();
         }
     }
 
+    /** Updates filtered routes and dispatch callbacks */
+    @GuardedBy("mLock")
+    void updateFilteredRoutesLocked() {
+        mFilteredRoutes =
+                Collections.unmodifiableList(
+                        filterRoutesWithCompositePreferenceLocked(List.copyOf(mRoutes.values())));
+        mHandler.sendMessage(
+                obtainMessage(MediaRouter2::dispatchFilteredRoutesChangedLocked,
+                        this, mFilteredRoutes));
+    }
+
     /**
-     * Creates a controller and calls the {@link TransferCallback#onTransfer}.
-     * If the controller creation has failed, then it calls
-     * {@link TransferCallback#onTransferFailure}.
-     * <p>
-     * Pass {@code null} to sessionInfo for the failure case.
+     * Creates a controller and calls the {@link TransferCallback#onTransfer}. If the controller
+     * creation has failed, then it calls {@link TransferCallback#onTransferFailure}.
+     *
+     * <p>Pass {@code null} to sessionInfo for the failure case.
      */
     void createControllerOnHandler(int requestId, @Nullable RoutingSessionInfo sessionInfo) {
         ControllerCreationRequest matchingRequest = null;
@@ -913,12 +904,15 @@
         if (sessionInfo == null) {
             notifyTransferFailure(requestedRoute);
             return;
-        } else if (!TextUtils.equals(requestedRoute.getProviderId(),
-                sessionInfo.getProviderId())) {
-            Log.w(TAG, "The session's provider ID does not match the requested route's. "
-                    + "(requested route's providerId=" + requestedRoute.getProviderId()
-                    + ", actual providerId=" + sessionInfo.getProviderId()
-                    + ")");
+        } else if (!TextUtils.equals(requestedRoute.getProviderId(), sessionInfo.getProviderId())) {
+            Log.w(
+                    TAG,
+                    "The session's provider ID does not match the requested route's. "
+                            + "(requested route's providerId="
+                            + requestedRoute.getProviderId()
+                            + ", actual providerId="
+                            + sessionInfo.getProviderId()
+                            + ")");
             notifyTransferFailure(requestedRoute);
             return;
         }
@@ -927,9 +921,12 @@
         // When the old controller is released before transferred, treat it as a failure.
         // This could also happen when transfer is requested twice or more.
         if (!oldController.scheduleRelease()) {
-            Log.w(TAG, "createControllerOnHandler: "
-                    + "Ignoring controller creation for released old controller. "
-                    + "oldController=" + oldController);
+            Log.w(
+                    TAG,
+                    "createControllerOnHandler: "
+                            + "Ignoring controller creation for released old controller. "
+                            + "oldController="
+                            + oldController);
             if (!sessionInfo.isSystemSession()) {
                 new RoutingController(sessionInfo).release();
             }
@@ -971,15 +968,21 @@
         }
 
         if (matchingController == null) {
-            Log.w(TAG, "updateControllerOnHandler: Matching controller not found. uniqueSessionId="
-                    + sessionInfo.getId());
+            Log.w(
+                    TAG,
+                    "updateControllerOnHandler: Matching controller not found. uniqueSessionId="
+                            + sessionInfo.getId());
             return;
         }
 
         RoutingSessionInfo oldInfo = matchingController.getRoutingSessionInfo();
         if (!TextUtils.equals(oldInfo.getProviderId(), sessionInfo.getProviderId())) {
-            Log.w(TAG, "updateControllerOnHandler: Provider IDs are not matched. old="
-                    + oldInfo.getProviderId() + ", new=" + sessionInfo.getProviderId());
+            Log.w(
+                    TAG,
+                    "updateControllerOnHandler: Provider IDs are not matched. old="
+                            + oldInfo.getProviderId()
+                            + ", new="
+                            + sessionInfo.getProviderId());
             return;
         }
 
@@ -1000,24 +1003,31 @@
 
         if (matchingController == null) {
             if (DEBUG) {
-                Log.d(TAG, "releaseControllerOnHandler: Matching controller not found. "
-                        + "uniqueSessionId=" + sessionInfo.getId());
+                Log.d(
+                        TAG,
+                        "releaseControllerOnHandler: Matching controller not found. "
+                                + "uniqueSessionId="
+                                + sessionInfo.getId());
             }
             return;
         }
 
         RoutingSessionInfo oldInfo = matchingController.getRoutingSessionInfo();
         if (!TextUtils.equals(oldInfo.getProviderId(), sessionInfo.getProviderId())) {
-            Log.w(TAG, "releaseControllerOnHandler: Provider IDs are not matched. old="
-                    + oldInfo.getProviderId() + ", new=" + sessionInfo.getProviderId());
+            Log.w(
+                    TAG,
+                    "releaseControllerOnHandler: Provider IDs are not matched. old="
+                            + oldInfo.getProviderId()
+                            + ", new="
+                            + sessionInfo.getProviderId());
             return;
         }
 
         matchingController.releaseInternal(/* shouldReleaseSession= */ false);
     }
 
-    void onRequestCreateControllerByManagerOnHandler(RoutingSessionInfo oldSession,
-            MediaRoute2Info route, long managerRequestId) {
+    void onRequestCreateControllerByManagerOnHandler(
+            RoutingSessionInfo oldSession, MediaRoute2Info route, long managerRequestId) {
         RoutingController controller;
         if (oldSession.isSystemSession()) {
             controller = getSystemController();
@@ -1033,17 +1043,17 @@
     }
 
     /**
-     * Returns whether this router is created with {@link #getInstance(Context, String)}.
-     * This kind of router can control the target app's media routing.
+     * Returns whether this router is created with {@link #getInstance(Context, String)}. This kind
+     * of router can control the target app's media routing.
      */
     private boolean isSystemRouter() {
         return mClientPackageName != null;
     }
 
     /**
-     * Returns a {@link RoutingSessionInfo} which has the client package name.
-     * The client package name is set only when the given sessionInfo doesn't have it.
-     * Should only used for system media routers.
+     * Returns a {@link RoutingSessionInfo} which has the client package name. The client package
+     * name is set only when the given sessionInfo doesn't have it. Should only used for system
+     * media routers.
      */
     private RoutingSessionInfo ensureClientPackageNameForSystemSession(
             @NonNull RoutingSessionInfo sessionInfo) {
@@ -1057,46 +1067,73 @@
                 .build();
     }
 
-    private List<MediaRoute2Info> getSortedRoutes(List<MediaRoute2Info> routes,
-            RouteDiscoveryPreference preference) {
-        if (!preference.shouldRemoveDuplicates()) {
+    private List<MediaRoute2Info> getSortedRoutes(
+            List<MediaRoute2Info> routes, List<String> packageOrder) {
+        if (packageOrder.isEmpty()) {
             return routes;
         }
         Map<String, Integer> packagePriority = new ArrayMap<>();
-        int count = preference.getDeduplicationPackageOrder().size();
+        int count = packageOrder.size();
         for (int i = 0; i < count; i++) {
             // the last package will have 1 as the priority
-            packagePriority.put(preference.getDeduplicationPackageOrder().get(i), count - i);
+            packagePriority.put(packageOrder.get(i), count - i);
         }
         ArrayList<MediaRoute2Info> sortedRoutes = new ArrayList<>(routes);
         // take the negative for descending order
-        sortedRoutes.sort(Comparator.comparingInt(
-                r -> -packagePriority.getOrDefault(r.getPackageName(), 0)));
+        sortedRoutes.sort(
+                Comparator.comparingInt(r -> -packagePriority.getOrDefault(r.getPackageName(), 0)));
         return sortedRoutes;
     }
 
-    private List<MediaRoute2Info> filterRoutes(List<MediaRoute2Info> routes,
-            RouteDiscoveryPreference discoveryPreference) {
+    @GuardedBy("mLock")
+    private List<MediaRoute2Info> filterRoutesWithCompositePreferenceLocked(
+            List<MediaRoute2Info> routes) {
 
         Set<String> deduplicationIdSet = new ArraySet<>();
 
         List<MediaRoute2Info> filteredRoutes = new ArrayList<>();
-        for (MediaRoute2Info route : getSortedRoutes(routes, discoveryPreference)) {
+        for (MediaRoute2Info route :
+                getSortedRoutes(routes, mDiscoveryPreference.getDeduplicationPackageOrder())) {
+            if (!route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+                continue;
+            }
+            if (!mDiscoveryPreference.getAllowedPackages().isEmpty()
+                    && (route.getPackageName() == null
+                            || !mDiscoveryPreference
+                                    .getAllowedPackages()
+                                    .contains(route.getPackageName()))) {
+                continue;
+            }
+            if (mDiscoveryPreference.shouldRemoveDuplicates()) {
+                if (!Collections.disjoint(deduplicationIdSet, route.getDeduplicationIds())) {
+                    continue;
+                }
+                deduplicationIdSet.addAll(route.getDeduplicationIds());
+            }
+            filteredRoutes.add(route);
+        }
+        return filteredRoutes;
+    }
+
+    private List<MediaRoute2Info> filterRoutesWithIndividualPreference(
+            List<MediaRoute2Info> routes, RouteDiscoveryPreference discoveryPreference) {
+        List<MediaRoute2Info> filteredRoutes = new ArrayList<>();
+        if (isSystemRouter()) {
+            // Individual discovery preferences do not apply for the system router.
+            filteredRoutes.addAll(routes);
+            return filteredRoutes;
+        }
+        for (MediaRoute2Info route : routes) {
             if (!route.hasAnyFeatures(discoveryPreference.getPreferredFeatures())) {
                 continue;
             }
             if (!discoveryPreference.getAllowedPackages().isEmpty()
                     && (route.getPackageName() == null
-                    || !discoveryPreference.getAllowedPackages()
-                            .contains(route.getPackageName()))) {
+                            || !discoveryPreference
+                                    .getAllowedPackages()
+                                    .contains(route.getPackageName()))) {
                 continue;
             }
-            if (discoveryPreference.shouldRemoveDuplicates()) {
-                if (!Collections.disjoint(deduplicationIdSet, route.getDeduplicationIds())) {
-                    continue;
-                }
-                deduplicationIdSet.addAll(route.getDeduplicationIds());
-            }
             filteredRoutes.add(route);
         }
         return filteredRoutes;
@@ -1111,23 +1148,24 @@
             for (MediaRoute2Info route : sManager.getAllRoutes()) {
                 mRoutes.put(route.getId(), route);
             }
-            mShouldUpdateRoutes = true;
+            updateFilteredRoutesLocked();
         }
     }
 
     private void notifyRoutesAdded(List<MediaRoute2Info> routes) {
-        for (RouteCallbackRecord record: mRouteCallbackRecords) {
-            List<MediaRoute2Info> filteredRoutes = filterRoutes(routes, record.mPreference);
+        for (RouteCallbackRecord record : mRouteCallbackRecords) {
+            List<MediaRoute2Info> filteredRoutes =
+                    filterRoutesWithIndividualPreference(routes, record.mPreference);
             if (!filteredRoutes.isEmpty()) {
-                record.mExecutor.execute(
-                        () -> record.mRouteCallback.onRoutesAdded(filteredRoutes));
+                record.mExecutor.execute(() -> record.mRouteCallback.onRoutesAdded(filteredRoutes));
             }
         }
     }
 
     private void notifyRoutesRemoved(List<MediaRoute2Info> routes) {
-        for (RouteCallbackRecord record: mRouteCallbackRecords) {
-            List<MediaRoute2Info> filteredRoutes = filterRoutes(routes, record.mPreference);
+        for (RouteCallbackRecord record : mRouteCallbackRecords) {
+            List<MediaRoute2Info> filteredRoutes =
+                    filterRoutesWithIndividualPreference(routes, record.mPreference);
             if (!filteredRoutes.isEmpty()) {
                 record.mExecutor.execute(
                         () -> record.mRouteCallback.onRoutesRemoved(filteredRoutes));
@@ -1136,8 +1174,9 @@
     }
 
     private void notifyRoutesChanged(List<MediaRoute2Info> routes) {
-        for (RouteCallbackRecord record: mRouteCallbackRecords) {
-            List<MediaRoute2Info> filteredRoutes = filterRoutes(routes, record.mPreference);
+        for (RouteCallbackRecord record : mRouteCallbackRecords) {
+            List<MediaRoute2Info> filteredRoutes =
+                    filterRoutesWithIndividualPreference(routes, record.mPreference);
             if (!filteredRoutes.isEmpty()) {
                 record.mExecutor.execute(
                         () -> record.mRouteCallback.onRoutesChanged(filteredRoutes));
@@ -1146,46 +1185,42 @@
     }
 
     private void notifyPreferredFeaturesChanged(List<String> features) {
-        for (RouteCallbackRecord record: mRouteCallbackRecords) {
+        for (RouteCallbackRecord record : mRouteCallbackRecords) {
             record.mExecutor.execute(
                     () -> record.mRouteCallback.onPreferredFeaturesChanged(features));
         }
     }
 
     private void notifyTransfer(RoutingController oldController, RoutingController newController) {
-        for (TransferCallbackRecord record: mTransferCallbackRecords) {
+        for (TransferCallbackRecord record : mTransferCallbackRecords) {
             record.mExecutor.execute(
                     () -> record.mTransferCallback.onTransfer(oldController, newController));
         }
     }
 
     private void notifyTransferFailure(MediaRoute2Info route) {
-        for (TransferCallbackRecord record: mTransferCallbackRecords) {
-            record.mExecutor.execute(
-                    () -> record.mTransferCallback.onTransferFailure(route));
+        for (TransferCallbackRecord record : mTransferCallbackRecords) {
+            record.mExecutor.execute(() -> record.mTransferCallback.onTransferFailure(route));
         }
     }
 
     private void notifyStop(RoutingController controller) {
-        for (TransferCallbackRecord record: mTransferCallbackRecords) {
-            record.mExecutor.execute(
-                    () -> record.mTransferCallback.onStop(controller));
+        for (TransferCallbackRecord record : mTransferCallbackRecords) {
+            record.mExecutor.execute(() -> record.mTransferCallback.onStop(controller));
         }
     }
 
     private void notifyControllerUpdated(RoutingController controller) {
-        for (ControllerCallbackRecord record: mControllerCallbackRecords) {
+        for (ControllerCallbackRecord record : mControllerCallbackRecords) {
             record.mExecutor.execute(() -> record.mCallback.onControllerUpdated(controller));
         }
     }
 
-    /**
-     * Callback for receiving events about media route discovery.
-     */
+    /** Callback for receiving events about media route discovery. */
     public abstract static class RouteCallback {
         /**
-         * Called when routes are added. Whenever you registers a callback, this will
-         * be invoked with known routes.
+         * Called when routes are added. Whenever you registers a callback, this will be invoked
+         * with known routes.
          *
          * @param routes the list of routes that have been added. It's never empty.
          */
@@ -1199,17 +1234,17 @@
         public void onRoutesRemoved(@NonNull List<MediaRoute2Info> routes) {}
 
         /**
-         * Called when routes are changed. For example, it is called when the route's name
-         * or volume have been changed.
+         * Called when routes are changed. For example, it is called when the route's name or volume
+         * have been changed.
          *
          * @param routes the list of routes that have been changed. It's never empty.
          */
         public void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {}
 
         /**
-         * Called when the client app's preferred features are changed.
-         * When this is called, it is recommended to {@link #getRoutes()} to get the routes
-         * that are currently available to the app.
+         * Called when the client app's preferred features are changed. When this is called, it is
+         * recommended to {@link #getRoutes()} to get the routes that are currently available to the
+         * app.
          *
          * @param preferredFeatures the new preferred features set by the application
          * @hide
@@ -1218,26 +1253,25 @@
         public void onPreferredFeaturesChanged(@NonNull List<String> preferredFeatures) {}
     }
 
-    /**
-     * Callback for receiving events on media transfer.
-     */
+    /** Callback for receiving events on media transfer. */
     public abstract static class TransferCallback {
         /**
-         * Called when a media is transferred between two different routing controllers.
-         * This can happen by calling {@link #transferTo(MediaRoute2Info)}.
-         * <p> Override this to start playback with {@code newController}. You may want to get
-         * the status of the media that is being played with {@code oldController} and resume it
-         * continuously with {@code newController}.
-         * After this is called, any callbacks with {@code oldController} will not be invoked
-         * unless {@code oldController} is the {@link #getSystemController() system controller}.
-         * You need to {@link RoutingController#release() release} {@code oldController} before
-         * playing the media with {@code newController}.
+         * Called when a media is transferred between two different routing controllers. This can
+         * happen by calling {@link #transferTo(MediaRoute2Info)}.
+         *
+         * <p>Override this to start playback with {@code newController}. You may want to get the
+         * status of the media that is being played with {@code oldController} and resume it
+         * continuously with {@code newController}. After this is called, any callbacks with {@code
+         * oldController} will not be invoked unless {@code oldController} is the {@link
+         * #getSystemController() system controller}. You need to {@link RoutingController#release()
+         * release} {@code oldController} before playing the media with {@code newController}.
          *
          * @param oldController the previous controller that controlled routing
          * @param newController the new controller to control routing
          * @see #transferTo(MediaRoute2Info)
          */
-        public void onTransfer(@NonNull RoutingController oldController,
+        public void onTransfer(
+                @NonNull RoutingController oldController,
                 @NonNull RoutingController newController) {}
 
         /**
@@ -1248,61 +1282,58 @@
         public void onTransferFailure(@NonNull MediaRoute2Info requestedRoute) {}
 
         /**
-         * Called when a media routing stops. It can be stopped by a user or a provider.
-         * App should not continue playing media locally when this method is called.
-         * The {@code controller} is released before this method is called.
+         * Called when a media routing stops. It can be stopped by a user or a provider. App should
+         * not continue playing media locally when this method is called. The {@code controller} is
+         * released before this method is called.
          *
          * @param controller the controller that controlled the stopped media routing
          */
-        public void onStop(@NonNull RoutingController controller) { }
+        public void onStop(@NonNull RoutingController controller) {}
     }
 
     /**
-     * A listener interface to send optional app-specific hints when creating a
-     * {@link RoutingController}.
+     * A listener interface to send optional app-specific hints when creating a {@link
+     * RoutingController}.
      */
     public interface OnGetControllerHintsListener {
         /**
-         * Called when the {@link MediaRouter2} or the system is about to request
-         * a media route provider service to create a controller with the given route.
-         * The {@link Bundle} returned here will be sent to media route provider service as a hint.
-         * <p>
-         * Since controller creation can be requested by the {@link MediaRouter2} and the system,
-         * set the listener as soon as possible after acquiring {@link MediaRouter2} instance.
-         * The method will be called on the same thread that calls
-         * {@link #transferTo(MediaRoute2Info)} or the main thread if it is requested by the system.
+         * Called when the {@link MediaRouter2} or the system is about to request a media route
+         * provider service to create a controller with the given route. The {@link Bundle} returned
+         * here will be sent to media route provider service as a hint.
+         *
+         * <p>Since controller creation can be requested by the {@link MediaRouter2} and the system,
+         * set the listener as soon as possible after acquiring {@link MediaRouter2} instance. The
+         * method will be called on the same thread that calls {@link #transferTo(MediaRoute2Info)}
+         * or the main thread if it is requested by the system.
          *
          * @param route the route to create a controller with
-         * @return An optional bundle of app-specific arguments to send to the provider,
-         *         or {@code null} if none. The contents of this bundle may affect the result of
-         *         controller creation.
+         * @return An optional bundle of app-specific arguments to send to the provider, or {@code
+         *     null} if none. The contents of this bundle may affect the result of controller
+         *     creation.
          * @see MediaRoute2ProviderService#onCreateSession(long, String, String, Bundle)
          */
         @Nullable
         Bundle onGetControllerHints(@NonNull MediaRoute2Info route);
     }
 
-    /**
-     * Callback for receiving {@link RoutingController} updates.
-     */
+    /** Callback for receiving {@link RoutingController} updates. */
     public abstract static class ControllerCallback {
         /**
-         * Called when a controller is updated. (e.g., when the selected routes of the
-         * controller is changed or when the volume of the controller is changed.)
+         * Called when a controller is updated. (e.g., when the selected routes of the controller is
+         * changed or when the volume of the controller is changed.)
          *
-         * @param controller the updated controller. It may be the
-         * {@link #getSystemController() system controller}.
+         * @param controller the updated controller. It may be the {@link #getSystemController()
+         *     system controller}.
          * @see #getSystemController()
          */
-        public void onControllerUpdated(@NonNull RoutingController controller) { }
+        public void onControllerUpdated(@NonNull RoutingController controller) {}
     }
 
     /**
-     * A class to control media routing session in media route provider.
-     * For example, selecting/deselecting/transferring to routes of a session can be done through
-     * this. Instances are created when
-     * {@link TransferCallback#onTransfer(RoutingController, RoutingController)} is called,
-     * which is invoked after {@link #transferTo(MediaRoute2Info)} is called.
+     * A class to control media routing session in media route provider. For example,
+     * selecting/deselecting/transferring to routes of a session can be done through this. Instances
+     * are created when {@link TransferCallback#onTransfer(RoutingController, RoutingController)} is
+     * called, which is invoked after {@link #transferTo(MediaRoute2Info)} is called.
      */
     public class RoutingController {
         private final Object mControllerLock = new Object();
@@ -1339,8 +1370,8 @@
         }
 
         /**
-         * Gets the original session ID set by
-         * {@link RoutingSessionInfo.Builder#Builder(String, String)}.
+         * Gets the original session ID set by {@link RoutingSessionInfo.Builder#Builder(String,
+         * String)}.
          *
          * @hide
          */
@@ -1353,8 +1384,8 @@
         }
 
         /**
-         * Gets the control hints used to control routing session if available.
-         * It is set by the media route provider.
+         * Gets the control hints used to control routing session if available. It is set by the
+         * media route provider.
          */
         @Nullable
         public Bundle getControlHints() {
@@ -1401,11 +1432,12 @@
 
         /**
          * Gets the information about how volume is handled on the session.
-         * <p>Please note that you may not control the volume of the session even when
-         * you can control the volume of each selected route in the session.
          *
-         * @return {@link MediaRoute2Info#PLAYBACK_VOLUME_FIXED} or
-         * {@link MediaRoute2Info#PLAYBACK_VOLUME_VARIABLE}
+         * <p>Please note that you may not control the volume of the session even when you can
+         * control the volume of each selected route in the session.
+         *
+         * @return {@link MediaRoute2Info#PLAYBACK_VOLUME_FIXED} or {@link
+         *     MediaRoute2Info#PLAYBACK_VOLUME_VARIABLE}
          */
         @MediaRoute2Info.PlaybackVolume
         public int getVolumeHandling() {
@@ -1414,9 +1446,7 @@
             }
         }
 
-        /**
-         * Gets the maximum volume of the session.
-         */
+        /** Gets the maximum volume of the session. */
         public int getVolumeMax() {
             synchronized (mControllerLock) {
                 return mSessionInfo.getVolumeMax();
@@ -1425,11 +1455,10 @@
 
         /**
          * Gets the current volume of the session.
-         * <p>
-         * When it's available, it represents the volume of routing session, which is a group
-         * of selected routes. Use {@link MediaRoute2Info#getVolume()}
-         * to get the volume of a route,
-         * </p>
+         *
+         * <p>When it's available, it represents the volume of routing session, which is a group of
+         * selected routes. Use {@link MediaRoute2Info#getVolume()} to get the volume of a route,
+         *
          * @see MediaRoute2Info#getVolume()
          */
         public int getVolume() {
@@ -1439,9 +1468,9 @@
         }
 
         /**
-         * Returns true if this controller is released, false otherwise.
-         * If it is released, then all other getters from this instance may return invalid values.
-         * Also, any operations to this instance will be ignored once released.
+         * Returns true if this controller is released, false otherwise. If it is released, then all
+         * other getters from this instance may return invalid values. Also, any operations to this
+         * instance will be ignored once released.
          *
          * @see #release
          */
@@ -1454,14 +1483,16 @@
         /**
          * Selects a route for the remote session. After a route is selected, the media is expected
          * to be played to the all the selected routes. This is different from {@link
-         * MediaRouter2#transferTo(MediaRoute2Info)} transferring to a route},
-         * where the media is expected to 'move' from one route to another.
-         * <p>
-         * The given route must satisfy all of the following conditions:
+         * MediaRouter2#transferTo(MediaRoute2Info)} transferring to a route}, where the media is
+         * expected to 'move' from one route to another.
+         *
+         * <p>The given route must satisfy all of the following conditions:
+         *
          * <ul>
-         * <li>It should not be included in {@link #getSelectedRoutes()}</li>
-         * <li>It should be included in {@link #getSelectableRoutes()}</li>
+         *   <li>It should not be included in {@link #getSelectedRoutes()}
+         *   <li>It should be included in {@link #getSelectableRoutes()}
          * </ul>
+         *
          * If the route doesn't meet any of above conditions, it will be ignored.
          *
          * @see #deselectRoute(MediaRoute2Info)
@@ -1509,12 +1540,14 @@
         /**
          * Deselects a route from the remote session. After a route is deselected, the media is
          * expected to be stopped on the deselected route.
-         * <p>
-         * The given route must satisfy all of the following conditions:
+         *
+         * <p>The given route must satisfy all of the following conditions:
+         *
          * <ul>
-         * <li>It should be included in {@link #getSelectedRoutes()}</li>
-         * <li>It should be included in {@link #getDeselectableRoutes()}</li>
+         *   <li>It should be included in {@link #getSelectedRoutes()}
+         *   <li>It should be included in {@link #getDeselectableRoutes()}
          * </ul>
+         *
          * If the route doesn't meet any of above conditions, it will be ignored.
          *
          * @see #getSelectedRoutes()
@@ -1559,8 +1592,8 @@
         }
 
         /**
-         * Transfers to a given route for the remote session. The given route must be included
-         * in {@link RoutingSessionInfo#getTransferableRoutes()}.
+         * Transfers to a given route for the remote session. The given route must be included in
+         * {@link RoutingSessionInfo#getTransferableRoutes()}.
          *
          * @see RoutingSessionInfo#getSelectedRoutes()
          * @see RoutingSessionInfo#getTransferableRoutes()
@@ -1597,7 +1630,7 @@
          * Requests a volume change for the remote session asynchronously.
          *
          * @param volume The new volume value between 0 and {@link RoutingController#getVolumeMax}
-         *               (inclusive).
+         *     (inclusive).
          * @see #getVolume()
          */
         public void setVolume(int volume) {
@@ -1634,9 +1667,9 @@
         }
 
         /**
-         * Releases this controller and the corresponding session.
-         * Any operations on this controller after calling this method will be ignored.
-         * The devices that are playing media will stop playing it.
+         * Releases this controller and the corresponding session. Any operations on this controller
+         * after calling this method will be ignored. The devices that are playing media will stop
+         * playing it.
          */
         public void release() {
             releaseInternal(/* shouldReleaseSession= */ true);
@@ -1644,8 +1677,9 @@
 
         /**
          * Schedules release of the controller.
+         *
          * @return {@code true} if it's successfully scheduled, {@code false} if it's already
-         * scheduled to be released or released.
+         *     scheduled to be released or released.
          */
         boolean scheduleRelease() {
             synchronized (mControllerLock) {
@@ -1701,11 +1735,15 @@
                 }
 
                 if (shouldNotifyStop) {
-                    mHandler.sendMessage(obtainMessage(MediaRouter2::notifyStop, MediaRouter2.this,
-                            RoutingController.this));
+                    mHandler.sendMessage(
+                            obtainMessage(
+                                    MediaRouter2::notifyStop,
+                                    MediaRouter2.this,
+                                    RoutingController.this));
                 }
 
-                if (mRouteCallbackRecords.isEmpty() && mNonSystemRoutingControllers.isEmpty()
+                if (mRouteCallbackRecords.isEmpty()
+                        && mNonSystemRoutingControllers.isEmpty()
                         && mStub != null) {
                     try {
                         mMediaRouterService.unregisterRouter2(mStub);
@@ -1720,26 +1758,34 @@
         @Override
         public String toString() {
             // To prevent logging spam, we only print the ID of each route.
-            List<String> selectedRoutes = getSelectedRoutes().stream()
-                    .map(MediaRoute2Info::getId).collect(Collectors.toList());
-            List<String> selectableRoutes = getSelectableRoutes().stream()
-                    .map(MediaRoute2Info::getId).collect(Collectors.toList());
-            List<String> deselectableRoutes = getDeselectableRoutes().stream()
-                    .map(MediaRoute2Info::getId).collect(Collectors.toList());
+            List<String> selectedRoutes =
+                    getSelectedRoutes().stream()
+                            .map(MediaRoute2Info::getId)
+                            .collect(Collectors.toList());
+            List<String> selectableRoutes =
+                    getSelectableRoutes().stream()
+                            .map(MediaRoute2Info::getId)
+                            .collect(Collectors.toList());
+            List<String> deselectableRoutes =
+                    getDeselectableRoutes().stream()
+                            .map(MediaRoute2Info::getId)
+                            .collect(Collectors.toList());
 
-            StringBuilder result = new StringBuilder()
-                    .append("RoutingController{ ")
-                    .append("id=").append(getId())
-                    .append(", selectedRoutes={")
-                    .append(selectedRoutes)
-                    .append("}")
-                    .append(", selectableRoutes={")
-                    .append(selectableRoutes)
-                    .append("}")
-                    .append(", deselectableRoutes={")
-                    .append(deselectableRoutes)
-                    .append("}")
-                    .append(" }");
+            StringBuilder result =
+                    new StringBuilder()
+                            .append("RoutingController{ ")
+                            .append("id=")
+                            .append(getId())
+                            .append(", selectedRoutes={")
+                            .append(selectedRoutes)
+                            .append("}")
+                            .append(", selectableRoutes={")
+                            .append(selectableRoutes)
+                            .append("}")
+                            .append(", deselectableRoutes={")
+                            .append(deselectableRoutes)
+                            .append("}")
+                            .append(" }");
             return result.toString();
         }
 
@@ -1764,7 +1810,8 @@
             }
 
             synchronized (mLock) {
-                return routeIds.stream().map(mRoutes::get)
+                return routeIds.stream()
+                        .map(mRoutes::get)
                         .filter(Objects::nonNull)
                         .collect(Collectors.toList());
             }
@@ -1799,7 +1846,9 @@
         public final RouteCallback mRouteCallback;
         public final RouteDiscoveryPreference mPreference;
 
-        RouteCallbackRecord(@Nullable Executor executor, @NonNull RouteCallback routeCallback,
+        RouteCallbackRecord(
+                @Nullable Executor executor,
+                @NonNull RouteCallback routeCallback,
                 @Nullable RouteDiscoveryPreference preference) {
             mRouteCallback = routeCallback;
             mExecutor = executor;
@@ -1827,8 +1876,8 @@
         public final Executor mExecutor;
         public final TransferCallback mTransferCallback;
 
-        TransferCallbackRecord(@NonNull Executor executor,
-                @NonNull TransferCallback transferCallback) {
+        TransferCallbackRecord(
+                @NonNull Executor executor, @NonNull TransferCallback transferCallback) {
             mTransferCallback = transferCallback;
             mExecutor = executor;
         }
@@ -1854,8 +1903,8 @@
         public final Executor mExecutor;
         public final ControllerCallback mCallback;
 
-        ControllerCallbackRecord(@Nullable Executor executor,
-                @NonNull ControllerCallback callback) {
+        ControllerCallbackRecord(
+                @Nullable Executor executor, @NonNull ControllerCallback callback) {
             mCallback = callback;
             mExecutor = executor;
         }
@@ -1883,66 +1932,87 @@
         public final MediaRoute2Info mRoute;
         public final RoutingController mOldController;
 
-        ControllerCreationRequest(int requestId, long managerRequestId,
-                @NonNull MediaRoute2Info route, @NonNull RoutingController oldController) {
+        ControllerCreationRequest(
+                int requestId,
+                long managerRequestId,
+                @NonNull MediaRoute2Info route,
+                @NonNull RoutingController oldController) {
             mRequestId = requestId;
             mManagerRequestId = managerRequestId;
             mRoute = Objects.requireNonNull(route, "route must not be null");
-            mOldController = Objects.requireNonNull(oldController,
-                    "oldController must not be null");
+            mOldController =
+                    Objects.requireNonNull(oldController, "oldController must not be null");
         }
     }
 
     class MediaRouter2Stub extends IMediaRouter2.Stub {
         @Override
-        public void notifyRouterRegistered(List<MediaRoute2Info> currentRoutes,
-                RoutingSessionInfo currentSystemSessionInfo) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2::syncRoutesOnHandler,
-                    MediaRouter2.this, currentRoutes, currentSystemSessionInfo));
+        public void notifyRouterRegistered(
+                List<MediaRoute2Info> currentRoutes, RoutingSessionInfo currentSystemSessionInfo) {
+            mHandler.sendMessage(
+                    obtainMessage(
+                            MediaRouter2::syncRoutesOnHandler,
+                            MediaRouter2.this,
+                            currentRoutes,
+                            currentSystemSessionInfo));
         }
 
         @Override
         public void notifyRoutesAdded(List<MediaRoute2Info> routes) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2::addRoutesOnHandler,
-                    MediaRouter2.this, routes));
+            mHandler.sendMessage(
+                    obtainMessage(MediaRouter2::addRoutesOnHandler, MediaRouter2.this, routes));
         }
 
         @Override
         public void notifyRoutesRemoved(List<MediaRoute2Info> routes) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2::removeRoutesOnHandler,
-                    MediaRouter2.this, routes));
+            mHandler.sendMessage(
+                    obtainMessage(MediaRouter2::removeRoutesOnHandler, MediaRouter2.this, routes));
         }
 
         @Override
         public void notifyRoutesChanged(List<MediaRoute2Info> routes) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2::changeRoutesOnHandler,
-                    MediaRouter2.this, routes));
+            mHandler.sendMessage(
+                    obtainMessage(MediaRouter2::changeRoutesOnHandler, MediaRouter2.this, routes));
         }
 
         @Override
         public void notifySessionCreated(int requestId, @Nullable RoutingSessionInfo sessionInfo) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2::createControllerOnHandler,
-                    MediaRouter2.this, requestId, sessionInfo));
+            mHandler.sendMessage(
+                    obtainMessage(
+                            MediaRouter2::createControllerOnHandler,
+                            MediaRouter2.this,
+                            requestId,
+                            sessionInfo));
         }
 
         @Override
         public void notifySessionInfoChanged(@Nullable RoutingSessionInfo sessionInfo) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2::updateControllerOnHandler,
-                    MediaRouter2.this, sessionInfo));
+            mHandler.sendMessage(
+                    obtainMessage(
+                            MediaRouter2::updateControllerOnHandler,
+                            MediaRouter2.this,
+                            sessionInfo));
         }
 
         @Override
         public void notifySessionReleased(RoutingSessionInfo sessionInfo) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2::releaseControllerOnHandler,
-                    MediaRouter2.this, sessionInfo));
+            mHandler.sendMessage(
+                    obtainMessage(
+                            MediaRouter2::releaseControllerOnHandler,
+                            MediaRouter2.this,
+                            sessionInfo));
         }
 
         @Override
-        public void requestCreateSessionByManager(long managerRequestId,
-                RoutingSessionInfo oldSession, MediaRoute2Info route) {
-            mHandler.sendMessage(obtainMessage(
-                    MediaRouter2::onRequestCreateControllerByManagerOnHandler,
-                    MediaRouter2.this, oldSession, route, managerRequestId));
+        public void requestCreateSessionByManager(
+                long managerRequestId, RoutingSessionInfo oldSession, MediaRoute2Info route) {
+            mHandler.sendMessage(
+                    obtainMessage(
+                            MediaRouter2::onRequestCreateControllerByManagerOnHandler,
+                            MediaRouter2.this,
+                            oldSession,
+                            route,
+                            managerRequestId));
         }
     }
 
@@ -1952,57 +2022,21 @@
         @Override
         public void onRoutesAdded(@NonNull List<MediaRoute2Info> routes) {
             updateAllRoutesFromManager();
-
-            List<MediaRoute2Info> filteredRoutes;
-            synchronized (mLock) {
-                filteredRoutes = filterRoutes(routes, mDiscoveryPreference);
-            }
-            if (filteredRoutes.isEmpty()) {
-                return;
-            }
-            for (RouteCallbackRecord record: mRouteCallbackRecords) {
-                record.mExecutor.execute(
-                        () -> record.mRouteCallback.onRoutesAdded(filteredRoutes));
-            }
         }
 
         @Override
         public void onRoutesRemoved(@NonNull List<MediaRoute2Info> routes) {
             updateAllRoutesFromManager();
-
-            List<MediaRoute2Info> filteredRoutes;
-            synchronized (mLock) {
-                filteredRoutes = filterRoutes(routes, mDiscoveryPreference);
-            }
-            if (filteredRoutes.isEmpty()) {
-                return;
-            }
-            for (RouteCallbackRecord record: mRouteCallbackRecords) {
-                record.mExecutor.execute(
-                        () -> record.mRouteCallback.onRoutesRemoved(filteredRoutes));
-            }
         }
 
         @Override
         public void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {
             updateAllRoutesFromManager();
-
-            List<MediaRoute2Info> filteredRoutes;
-            synchronized (mLock) {
-                filteredRoutes = filterRoutes(routes, mDiscoveryPreference);
-            }
-            if (filteredRoutes.isEmpty()) {
-                return;
-            }
-            for (RouteCallbackRecord record: mRouteCallbackRecords) {
-                record.mExecutor.execute(
-                        () -> record.mRouteCallback.onRoutesChanged(filteredRoutes));
-            }
         }
 
         @Override
-        public void onTransferred(@NonNull RoutingSessionInfo oldSession,
-                @NonNull RoutingSessionInfo newSession) {
+        public void onTransferred(
+                @NonNull RoutingSessionInfo oldSession, @NonNull RoutingSessionInfo newSession) {
             if (!oldSession.isSystemSession()
                     && !TextUtils.equals(mClientPackageName, oldSession.getClientPackageName())) {
                 return;
@@ -2018,7 +2052,6 @@
                 return;
             }
 
-
             RoutingController oldController;
             if (oldSession.isSystemSession()) {
                 mSystemController.setRoutingSessionInfo(
@@ -2041,8 +2074,8 @@
         }
 
         @Override
-        public void onTransferFailed(@NonNull RoutingSessionInfo session,
-                @NonNull MediaRoute2Info route) {
+        public void onTransferFailed(
+                @NonNull RoutingSessionInfo session, @NonNull MediaRoute2Info route) {
             if (!session.isSystemSession()
                     && !TextUtils.equals(mClientPackageName, session.getClientPackageName())) {
                 return;
@@ -2083,8 +2116,8 @@
         }
 
         @Override
-        public void onDiscoveryPreferenceChanged(@NonNull String packageName,
-                @NonNull RouteDiscoveryPreference preference) {
+        public void onDiscoveryPreferenceChanged(
+                @NonNull String packageName, @NonNull RouteDiscoveryPreference preference) {
             if (!TextUtils.equals(mClientPackageName, packageName)) {
                 return;
             }
diff --git a/media/java/android/media/NearbyDevice.java b/media/java/android/media/NearbyDevice.java
index c203e7b..dbcc6b7 100644
--- a/media/java/android/media/NearbyDevice.java
+++ b/media/java/android/media/NearbyDevice.java
@@ -22,9 +22,10 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * A parcelable representing a nearby device that can be used for media transfer.
@@ -35,6 +36,7 @@
  *   <li>a range zone specifying how far away this device is from the device with the media route.
  *   </li>
  * </ul>
+ *
  * @hide
  */
 @SystemApi
@@ -69,7 +71,7 @@
      *
      * @hide
      */
-    @IntDef(prefix = { "RANGE_" }, value = {
+    @IntDef(prefix = {"RANGE_"}, value = {
             RANGE_UNKNOWN,
             RANGE_FAR,
             RANGE_LONG,
@@ -77,7 +79,8 @@
             RANGE_WITHIN_REACH
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface RangeZone {}
+    public @interface RangeZone {
+    }
 
     /**
      * Gets a human-readable string of the range zone.
@@ -102,8 +105,17 @@
         }
     }
 
-    @NonNull private final String mMediaRoute2Id;
-    @RangeZone private final int mRangeZone;
+    /**
+     * A list stores all the range and list from far to close, used for range comparison.
+     */
+    private static final List<Integer> RANGE_WEIGHT_LIST =
+            Arrays.asList(RANGE_UNKNOWN,
+                    RANGE_FAR, RANGE_LONG, RANGE_CLOSE, RANGE_WITHIN_REACH);
+
+    @NonNull
+    private final String mMediaRoute2Id;
+    @RangeZone
+    private final int mRangeZone;
 
     /** Creates a device object with the given ID and range zone. */
     public NearbyDevice(@NonNull String mediaRoute2Id, @RangeZone int rangeZone) {
@@ -129,6 +141,22 @@
         }
     };
 
+    /**
+     * Compares two ranges and return result.
+     *
+     * @return 0 means two ranges are the same, -1 means first range is closer, 1 means farther
+     *
+     * @hide
+     */
+    public static int compareRangeZones(@RangeZone int rangeZone, @RangeZone int anotherRangeZone) {
+        if (rangeZone == anotherRangeZone) {
+            return 0;
+        } else {
+            return RANGE_WEIGHT_LIST.indexOf(rangeZone) > RANGE_WEIGHT_LIST.indexOf(
+                    anotherRangeZone) ? -1 : 1;
+        }
+    }
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/media/java/android/media/tv/interactive/AppLinkInfo.java b/media/java/android/media/tv/interactive/AppLinkInfo.java
index cd201f7..0eb6fa8 100644
--- a/media/java/android/media/tv/interactive/AppLinkInfo.java
+++ b/media/java/android/media/tv/interactive/AppLinkInfo.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.ComponentName;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -25,8 +26,7 @@
  * App link information used by TV interactive app to launch Android apps.
  */
 public final class AppLinkInfo implements Parcelable {
-    private @NonNull String mPackageName;
-    private @NonNull String mClassName;
+    private @NonNull ComponentName mComponentName;
     private @Nullable String mUriScheme;
     private @Nullable String mUriHost;
     private @Nullable String mUriPrefix;
@@ -41,12 +41,11 @@
             @Nullable String uriScheme,
             @Nullable String uriHost,
             @Nullable String uriPrefix) {
-        this.mPackageName = packageName;
         com.android.internal.util.AnnotationValidations.validate(
-                NonNull.class, null, mPackageName);
-        this.mClassName = className;
+                NonNull.class, null, packageName);
         com.android.internal.util.AnnotationValidations.validate(
-                NonNull.class, null, mClassName);
+                NonNull.class, null, className);
+        this.mComponentName = new ComponentName(packageName, className);
         this.mUriScheme = uriScheme;
         this.mUriHost = uriHost;
         this.mUriPrefix = uriPrefix;
@@ -57,7 +56,7 @@
      */
     @NonNull
     public String getPackageName() {
-        return mPackageName;
+        return mComponentName.getPackageName();
     }
 
     /**
@@ -65,7 +64,7 @@
      */
     @NonNull
     public String getClassName() {
-        return mClassName;
+        return mComponentName.getClassName();
     }
 
     /**
@@ -95,8 +94,8 @@
     @Override
     public String toString() {
         return "AppLinkInfo { "
-                + "packageName = " + mPackageName + ", "
-                + "className = " + mClassName + ", "
+                + "packageName = " + mComponentName.getPackageName() + ", "
+                + "className = " + mComponentName.getClassName() + ", "
                 + "uriScheme = " + mUriScheme + ", "
                 + "uriHost = " + mUriHost + ", "
                 + "uriPrefix = " + mUriPrefix
@@ -105,8 +104,8 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeString(mPackageName);
-        dest.writeString(mClassName);
+        dest.writeString(mComponentName.getPackageName());
+        dest.writeString(mComponentName.getClassName());
         dest.writeString(mUriScheme);
         dest.writeString(mUriHost);
         dest.writeString(mUriPrefix);
@@ -124,12 +123,11 @@
         String uriHost = in.readString();
         String uriPrefix = in.readString();
 
-        this.mPackageName = packageName;
         com.android.internal.util.AnnotationValidations.validate(
-                NonNull.class, null, mPackageName);
-        this.mClassName = className;
+                NonNull.class, null, packageName);
         com.android.internal.util.AnnotationValidations.validate(
-                NonNull.class, null, mClassName);
+                NonNull.class, null, className);
+        this.mComponentName = new ComponentName(packageName, className);
         this.mUriScheme = uriScheme;
         this.mUriHost = uriHost;
         this.mUriPrefix = uriPrefix;
@@ -174,28 +172,10 @@
         }
 
         /**
-         * Sets package name of the App link.
-         */
-        @NonNull
-        public Builder setPackageName(@NonNull String value) {
-            mPackageName = value;
-            return this;
-        }
-
-        /**
-         * Sets app name of the App link.
-         */
-        @NonNull
-        public Builder setClassName(@NonNull String value) {
-            mClassName = value;
-            return this;
-        }
-
-        /**
          * Sets URI scheme of the App link.
          */
         @NonNull
-        public Builder setUriScheme(@Nullable String value) {
+        public Builder setUriScheme(@NonNull String value) {
             mUriScheme = value;
             return this;
         }
@@ -204,7 +184,7 @@
          * Sets URI host of the App link.
          */
         @NonNull
-        public Builder setUriHost(@Nullable String value) {
+        public Builder setUriHost(@NonNull String value) {
             mUriHost = value;
             return this;
         }
@@ -213,7 +193,7 @@
          * Sets URI prefix of the App link.
          */
         @NonNull
-        public Builder setUriPrefix(@Nullable String value) {
+        public Builder setUriPrefix(@NonNull String value) {
             mUriPrefix = value;
             return this;
         }
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppInfo.java b/media/java/android/media/tv/interactive/TvInteractiveAppInfo.java
index e1f535c..6103db0 100644
--- a/media/java/android/media/tv/interactive/TvInteractiveAppInfo.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppInfo.java
@@ -131,6 +131,10 @@
         dest.writeInt(mTypes);
     }
 
+    /**
+     * Returns a unique ID for this TV interactive app service. The ID is generated from the package
+     * and class name implementing the TV interactive app service.
+     */
     @NonNull
     public String getId() {
         return mId;
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
index f75aa56..9eb4a6c 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
@@ -626,6 +626,7 @@
         /**
          * This is called when the state of the interactive app service is changed.
          *
+         * @param iAppServiceId The ID of the TV Interactive App service.
          * @param type the interactive app type
          * @param state the current state of the service of the given type
          * @param err the error code for error state. {@link #ERROR_NONE} is used when the state is
@@ -760,7 +761,12 @@
     }
 
     /**
-     * Registers app link info.
+     * Registers an Android application link info record which can be used to launch the specific
+     * Android application by TV interactive App RTE.
+     *
+     * @param tvIAppServiceId The ID of TV interactive service which the command to be sent to. The
+     *                        ID can be found in {@link TvInputInfo#getId()}.
+     * @param appLinkInfo The Android application link info record to be registered.
      */
     public void registerAppLinkInfo(
             @NonNull String tvIAppServiceId, @NonNull AppLinkInfo appLinkInfo) {
@@ -772,7 +778,12 @@
     }
 
     /**
-     * Unregisters app link info.
+     * Unregisters an Android application link info record which can be used to launch the specific
+     * Android application by TV interactive App RTE.
+     *
+     * @param tvIAppServiceId The ID of TV interactive service which the command to be sent to. The
+     *                        ID can be found in {@link TvInputInfo#getId()}.
+     * @param appLinkInfo The Android application link info record to be unregistered.
      */
     public void unregisterAppLinkInfo(
             @NonNull String tvIAppServiceId, @NonNull AppLinkInfo appLinkInfo) {
@@ -805,8 +816,8 @@
      * @param executor A {@link Executor} that the status change will be delivered to.
      */
     public void registerCallback(
-            @NonNull TvInteractiveAppCallback callback,
-            @CallbackExecutor @NonNull Executor executor) {
+            @CallbackExecutor @NonNull Executor executor,
+            @NonNull TvInteractiveAppCallback callback) {
         Preconditions.checkNotNull(callback);
         Preconditions.checkNotNull(executor);
         synchronized (mLock) {
@@ -1813,8 +1824,8 @@
         }
 
         /**
-         * This is called when {@link TvIAppService.Session#notifyTeletextAppStateChanged} is
-         * called.
+         * This is called when {@link TvInteractiveAppService.Session#notifyTeletextAppStateChanged}
+         * is called.
          *
          * @param session A {@link TvInteractiveAppManager.Session} associated with this callback.
          * @param state the current state.
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
index 57730ac..d22fd83 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
@@ -16,9 +16,11 @@
 
 package android.media.tv.interactive;
 
+import android.annotation.CallSuper;
 import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SdkConstant;
 import android.annotation.StringDef;
 import android.annotation.SuppressLint;
 import android.app.ActivityManager;
@@ -76,15 +78,14 @@
 
     private static final int DETACH_MEDIA_VIEW_TIMEOUT_MS = 5000;
 
-    // TODO: cleanup and unhide APIs.
-
     /**
      * This is the interface name that a service implementing a TV Interactive App service should
      * say that it supports -- that is, this is the action it uses for its intent filter. To be
      * supported, the service must also require the
-     * android.Manifest.permission#BIND_TV_INTERACTIVE_APP permission so that other applications
-     * cannot abuse it.
+     * {@link android.Manifest.permission#BIND_TV_INTERACTIVE_APP} permission so that other
+     * applications cannot abuse it.
      */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
     public static final String SERVICE_INTERFACE =
             "android.media.tv.interactive.TvInteractiveAppService";
 
@@ -244,13 +245,13 @@
     public abstract void onPrepare(@TvInteractiveAppInfo.InteractiveAppType int type);
 
     /**
-     * Registers App link info.
+     * Called when a request to register an Android application link info record is received.
      */
     public void onRegisterAppLinkInfo(@NonNull AppLinkInfo appLinkInfo) {
     }
 
     /**
-     * Unregisters App link info.
+     * Called when a request to unregister an Android application link info record is received.
      */
     public void onUnregisterAppLinkInfo(@NonNull AppLinkInfo appLinkInfo) {
     }
@@ -351,6 +352,7 @@
          * @param enable {@code true} if you want to enable the media view. {@code false}
          *            otherwise.
          */
+        @CallSuper
         public void setMediaViewEnabled(final boolean enable) {
             mHandler.post(new Runnable() {
                 @Override
@@ -383,7 +385,7 @@
         }
 
         /**
-         * Resets TvIAppService session.
+         * Resets TvInteractiveAppService session.
          */
         public void onResetInteractiveApp() {
         }
@@ -467,11 +469,11 @@
          * in {@link #onSetSurface}. This method is always called at least once, after
          * {@link #onSetSurface} is called with non-null surface.
          *
-         * @param format The new PixelFormat of the surface.
+         * @param format The new {@link PixelFormat} of the surface.
          * @param width The new width of the surface.
          * @param height The new height of the surface.
          */
-        public void onSurfaceChanged(int format, int width, int height) {
+        public void onSurfaceChanged(@PixelFormat.Format int format, int width, int height) {
         }
 
         /**
@@ -631,6 +633,7 @@
          * @param right Right position in pixels, relative to the overlay view.
          * @param bottom Bottom position in pixels, relative to the overlay view.
          */
+        @CallSuper
         public void layoutSurface(final int left, final int top, final int right,
                 final int bottom) {
             if (left > right || top > bottom) {
@@ -659,6 +662,7 @@
          * Requests broadcast related information from the related TV input.
          * @param request the request for broadcast info
          */
+        @CallSuper
         public void requestBroadcastInfo(@NonNull final BroadcastInfoRequest request) {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
@@ -683,6 +687,7 @@
          * Remove broadcast information request from the related TV input.
          * @param requestId the ID of the request
          */
+        @CallSuper
         public void removeBroadcastInfo(final int requestId) {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
@@ -709,6 +714,7 @@
          * @param cmdType type of the specific command
          * @param parameters parameters of the specific command
          */
+        @CallSuper
         public void sendPlaybackCommandRequest(
                 @PlaybackCommandType @NonNull String cmdType, @Nullable Bundle parameters) {
             executeOrPostRunnableOnMainThread(new Runnable() {
@@ -733,6 +739,7 @@
         /**
          * Sets broadcast video bounds.
          */
+        @CallSuper
         public void setVideoBounds(@NonNull Rect rect) {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
@@ -755,6 +762,7 @@
         /**
          * Requests the URI of the current channel.
          */
+        @CallSuper
         public void requestCurrentChannelUri() {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
@@ -777,6 +785,7 @@
         /**
          * Requests the logic channel number (LCN) of the current channel.
          */
+        @CallSuper
         public void requestCurrentChannelLcn() {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
@@ -799,6 +808,7 @@
         /**
          * Requests stream volume.
          */
+        @CallSuper
         public void requestStreamVolume() {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
@@ -821,6 +831,7 @@
         /**
          * Requests the list of {@link TvTrackInfo}.
          */
+        @CallSuper
         public void requestTrackInfoList() {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
@@ -845,6 +856,7 @@
          *
          * @see android.media.tv.TvInputInfo
          */
+        @CallSuper
         public void requestCurrentTvInputId() {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
@@ -869,6 +881,7 @@
          *
          * @param request The advertisement request
          */
+        @CallSuper
         public void requestAd(@NonNull final AdRequest request) {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
@@ -986,7 +999,7 @@
             if (DEBUG) {
                 Log.d(TAG, "notifyContentAllowed");
             }
-            notifyContentAllowed();
+            onContentAllowed();
         }
 
         void notifyContentBlocked(TvContentRating rating) {
@@ -1032,6 +1045,7 @@
          *            used when the state is not
          *            {@link TvInteractiveAppManager#INTERACTIVE_APP_STATE_ERROR}.
          */
+        @CallSuper
         public void notifySessionStateChanged(
                 @TvInteractiveAppManager.InteractiveAppState int state,
                 @TvInteractiveAppManager.ErrorCode int err) {
@@ -1062,6 +1076,7 @@
          *
          * @see #onCreateBiInteractiveApp(Uri, Bundle)
          */
+        @CallSuper
         public final void notifyBiInteractiveAppCreated(
                 @NonNull Uri biIAppUri, @Nullable String biIAppId) {
             executeOrPostRunnableOnMainThread(new Runnable() {
@@ -1087,6 +1102,7 @@
          * Notifies when the digital teletext app state is changed.
          * @param state the current state.
          */
+        @CallSuper
         public final void notifyTeletextAppStateChanged(
                 @TvInteractiveAppManager.TeletextAppState int state) {
             executeOrPostRunnableOnMainThread(new Runnable() {
diff --git a/media/java/android/media/tv/tuner/Lnb.java b/media/java/android/media/tv/tuner/Lnb.java
index 50a2083..3b70890 100644
--- a/media/java/android/media/tv/tuner/Lnb.java
+++ b/media/java/android/media/tv/tuner/Lnb.java
@@ -167,10 +167,10 @@
 
     private Lnb() {}
 
-    void setCallbackAndOwner(Executor executor, @Nullable LnbCallback callback, Tuner tuner) {
+    void setCallbackAndOwner(Tuner tuner, Executor executor, @Nullable LnbCallback callback) {
         synchronized (mCallbackLock) {
             if (callback != null && executor != null) {
-                addCallback(callback, executor);
+                addCallback(executor, callback);
             }
         }
         setOwner(tuner);
@@ -179,12 +179,12 @@
     /**
      * Adds LnbCallback
      *
-     * @param callback the callback to receive notifications from LNB.
      * @param executor the executor on which callback will be invoked. Cannot be null.
+     * @param callback the callback to receive notifications from LNB.
      */
-    public void addCallback(@NonNull  LnbCallback callback, @NonNull Executor executor) {
-        Objects.requireNonNull(callback, "callback must not be null");
+    public void addCallback(@NonNull Executor executor, @NonNull LnbCallback callback) {
         Objects.requireNonNull(executor, "executor must not be null");
+        Objects.requireNonNull(callback, "callback must not be null");
         synchronized (mCallbackLock) {
             mCallbackMap.put(callback, executor);
         }
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 1e32cad..ef0270b 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -62,7 +62,9 @@
 import android.os.Message;
 import android.os.Process;
 import android.util.Log;
+
 import com.android.internal.util.FrameworkStatsLog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
@@ -2147,12 +2149,12 @@
             Objects.requireNonNull(executor, "executor must not be null");
             Objects.requireNonNull(cb, "LnbCallback must not be null");
             if (mLnb != null) {
-                mLnb.setCallbackAndOwner(executor, cb, this);
+                mLnb.setCallbackAndOwner(this, executor, cb);
                 return mLnb;
             }
             if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB, mLnbLock)
                     && mLnb != null) {
-                mLnb.setCallbackAndOwner(executor, cb, this);
+                mLnb.setCallbackAndOwner(this, executor, cb);
                 setLnb(mLnb);
                 return mLnb;
             }
@@ -2186,7 +2188,7 @@
                     mLnbHandle = null;
                 }
                 mLnb = newLnb;
-                mLnb.setCallbackAndOwner(executor, cb, this);
+                mLnb.setCallbackAndOwner(this, executor, cb);
                 setLnb(mLnb);
             }
             return mLnb;
diff --git a/native/android/storage_manager.cpp b/native/android/storage_manager.cpp
index 2272525..9e0a6eb 100644
--- a/native/android/storage_manager.cpp
+++ b/native/android/storage_manager.cpp
@@ -140,8 +140,7 @@
         }
     }
 
-    void mountObb(const char* rawPath, const char* key, AStorageManager_obbCallbackFunc func,
-            void* data) {
+    void mountObb(const char* rawPath, AStorageManager_obbCallbackFunc func, void* data) {
         // Resolve path before sending to MountService
         char canonicalPath[PATH_MAX];
         if (realpath(rawPath, canonicalPath) == NULL) {
@@ -158,9 +157,7 @@
         ObbCallback* cb = registerObbCallback(func, data);
         String16 rawPath16(rawPath);
         String16 canonicalPath16(canonicalPath);
-        String16 key16(key);
-        mMountService->mountObb(rawPath16, canonicalPath16, key16, mObbActionListener,
-                cb->nonce, obbInfo);
+        mMountService->mountObb(rawPath16, canonicalPath16, mObbActionListener, cb->nonce, obbInfo);
     }
 
     void unmountObb(const char* filename, const bool force, AStorageManager_obbCallbackFunc func, void* data) {
@@ -207,7 +204,11 @@
 
 void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key,
         AStorageManager_obbCallbackFunc cb, void* data) {
-    mgr->mountObb(filename, key, cb, data);
+    if (key != nullptr && key[0] != '\0') {
+        ALOGE("mounting encrypted OBBs is no longer supported");
+        return;
+    }
+    mgr->mountObb(filename, cb, data);
 }
 
 void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force,
diff --git a/packages/BackupRestoreConfirmation/res/values/strings.xml b/packages/BackupRestoreConfirmation/res/values/strings.xml
index 3fb3fd4..5c90fd0 100644
--- a/packages/BackupRestoreConfirmation/res/values/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values/strings.xml
@@ -44,8 +44,6 @@
     <string name="backup_enc_password_text">Please enter a password to use for encrypting the full backup data. If this is left blank, your current backup password will be used:</string>
     <!-- Text for message to user that they may optionally supply an encryption password to use for a full backup operation. -->
     <string name="backup_enc_password_optional">If you wish to encrypt the full backup data, enter a password below:</string>
-    <!-- Text for message to user that they must supply an encryption password to use for a full backup operation because their phone is locked. -->
-    <string name="backup_enc_password_required">Since your device is encrypted, you are required to encrypt your backup. Please enter a password below:</string>
 
     <!-- Text for message to user when performing a full restore operation, explaining that they must enter the password originally used to encrypt the full backup data. -->
     <string name="restore_enc_password_text">If the restore data is encrypted, please enter the password below:</string>
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index d6b6bf8..3c790f0 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -27,8 +27,6 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.storage.IStorageManager;
-import android.os.storage.StorageManager;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.util.Slog;
@@ -66,10 +64,8 @@
 
     Handler mHandler;
     IBackupManager mBackupManager;
-    IStorageManager mStorageManager;
     FullObserver mObserver;
     int mToken;
-    boolean mIsEncrypted;
     boolean mDidAcknowledge;
     String mAction;
 
@@ -144,7 +140,6 @@
         }
 
         mBackupManager = IBackupManager.Stub.asInterface(ServiceManager.getService(Context.BACKUP_SERVICE));
-        mStorageManager = IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
 
         mHandler = new ObserverHandler(getApplicationContext());
         final Object oldObserver = getLastNonConfigurationInstance();
@@ -248,20 +243,13 @@
             mDenyButton.setEnabled(!mDidAcknowledge);
         }
 
-        // We vary the password prompt depending on whether one is predefined, and whether
-        // the device is encrypted.
-        mIsEncrypted = deviceIsEncrypted();
+        // We vary the password prompt depending on whether one is predefined.
         if (!haveBackupPassword()) {
             curPwDesc.setVisibility(View.GONE);
             mCurPassword.setVisibility(View.GONE);
             if (layoutId == R.layout.confirm_backup) {
                 TextView encPwDesc = findViewById(R.id.enc_password_desc);
-                if (mIsEncrypted) {
-                    encPwDesc.setText(R.string.backup_enc_password_required);
-                    monitorEncryptionPassword();
-                } else {
-                    encPwDesc.setText(R.string.backup_enc_password_optional);
-                }
+                encPwDesc.setText(R.string.backup_enc_password_optional);
             }
         }
     }
@@ -312,20 +300,6 @@
         }
     }
 
-    boolean deviceIsEncrypted() {
-        try {
-            return mStorageManager.getEncryptionState()
-                     != StorageManager.ENCRYPTION_STATE_NONE
-                && mStorageManager.getPasswordType()
-                     != StorageManager.CRYPT_TYPE_DEFAULT;
-        } catch (Exception e) {
-            // If we can't talk to the storagemanager service we have a serious problem; fail
-            // "secure" i.e. assuming that the device is encrypted.
-            Slog.e(TAG, "Unable to communicate with storagemanager service: " + e.getMessage());
-            return true;
-        }
-    }
-
     boolean haveBackupPassword() {
         try {
             return mBackupManager.hasBackupPassword();
diff --git a/packages/CompanionDeviceManager/res/drawable/btn_negative_multiple_devices.xml b/packages/CompanionDeviceManager/res/drawable/btn_negative_multiple_devices.xml
new file mode 100644
index 0000000..ece7bba
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/btn_negative_multiple_devices.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="@android:color/transparent" />
+    <corners android:topLeftRadius="16dp" android:topRightRadius="16dp"
+             android:bottomLeftRadius="16dp" android:bottomRightRadius="16dp"/>
+    <stroke
+        android:width="1dp"
+        android:color="@android:color/system_accent1_600" />
+</shape>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/btn_negative_top.xml b/packages/CompanionDeviceManager/res/drawable/btn_negative_top.xml
new file mode 100644
index 0000000..7df92bb
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/btn_negative_top.xml
@@ -0,0 +1,22 @@
+<!--
+  ~ 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">
+    <solid android:color="@android:color/system_accent1_100"/>
+    <corners android:topLeftRadius="12dp" android:topRightRadius="12dp"
+             android:bottomLeftRadius="4dp" android:bottomRightRadius="4dp"/>
+</shape>
diff --git a/packages/CompanionDeviceManager/res/drawable/btn_positive_bottom.xml b/packages/CompanionDeviceManager/res/drawable/btn_positive_bottom.xml
new file mode 100644
index 0000000..55e96f6
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/btn_positive_bottom.xml
@@ -0,0 +1,22 @@
+<!--
+  ~ 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">
+    <solid android:color="@android:color/system_accent1_100"/>
+    <corners android:topLeftRadius="4dp" android:topRightRadius="4dp"
+             android:bottomLeftRadius="12dp" android:bottomRightRadius="12dp"/>
+</shape>
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_apps.xml b/packages/CompanionDeviceManager/res/drawable/ic_apps.xml
new file mode 100644
index 0000000..93a0cba
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_apps.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:pathData="M6.2529,18.5H16.2529V17.5H18.2529V21.5C18.2529,22.6 17.3529,23.5 16.2529,23.5H6.2529C5.1529,23.5 4.2529,22.6 4.2529,21.5V3.5C4.2529,2.4 5.1529,1.51 6.2529,1.51L16.2529,1.5C17.3529,1.5 18.2529,2.4 18.2529,3.5V7.5H16.2529V6.5H6.2529V18.5ZM16.2529,3.5H6.2529V4.5H16.2529V3.5ZM6.2529,21.5V20.5H16.2529V21.5H6.2529ZM12.6553,9.4049C12.6553,8.8526 13.103,8.4049 13.6553,8.4049H20.5254C21.0776,8.4049 21.5254,8.8526 21.5254,9.4049V14.6055C21.5254,15.1578 21.0776,15.6055 20.5254,15.6055H14.355L12.6553,17.0871V9.4049Z"
+        android:fillColor="#3C4043"
+        android:fillType="evenOdd"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml b/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml
new file mode 100644
index 0000000..f8515c3
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp" android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="?attr/colorControlNormal">
+    <path android:fillColor="@android:color/white"
+          android:pathData="M7,20H4Q3.175,20 2.588,19.413Q2,18.825 2,18V6Q2,5.175 2.588,4.588Q3.175,4 4,4H20V6H4Q4,6 4,6Q4,6 4,6V18Q4,18 4,18Q4,18 4,18H7ZM9,20V18.2Q8.55,17.775 8.275,17.225Q8,16.675 8,16Q8,15.325 8.275,14.775Q8.55,14.225 9,13.8V12H13V13.8Q13.45,14.225 13.725,14.775Q14,15.325 14,16Q14,16.675 13.725,17.225Q13.45,17.775 13,18.2V20ZM11,17.5Q11.65,17.5 12.075,17.075Q12.5,16.65 12.5,16Q12.5,15.35 12.075,14.925Q11.65,14.5 11,14.5Q10.35,14.5 9.925,14.925Q9.5,15.35 9.5,16Q9.5,16.65 9.925,17.075Q10.35,17.5 11,17.5ZM21,20H16Q15.575,20 15.288,19.712Q15,19.425 15,19V10Q15,9.575 15.288,9.287Q15.575,9 16,9H21Q21.425,9 21.712,9.287Q22,9.575 22,10V19Q22,19.425 21.712,19.712Q21.425,20 21,20ZM17,18H20V11H17Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml b/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml
new file mode 100644
index 0000000..4ac4d04
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="?attr/colorControlNormal">
+    <path android:fillColor="@android:color/white"
+          android:pathData="M4,19V17H6V10Q6,7.925 7.25,6.312Q8.5,4.7 10.5,4.2V3.5Q10.5,2.875 10.938,2.438Q11.375,2 12,2Q12.625,2 13.062,2.438Q13.5,2.875 13.5,3.5V4.2Q15.5,4.7 16.75,6.312Q18,7.925 18,10V17H20V19ZM12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5ZM12,22Q11.175,22 10.588,21.413Q10,20.825 10,20H14Q14,20.825 13.413,21.413Q12.825,22 12,22ZM8,17H16V10Q16,8.35 14.825,7.175Q13.65,6 12,6Q10.35,6 9.175,7.175Q8,8.35 8,10Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_storage.xml b/packages/CompanionDeviceManager/res/drawable/ic_storage.xml
new file mode 100644
index 0000000..d8b7f59
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_storage.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="?attr/colorControlNormal">
+    <path android:fillColor="@android:color/white"
+          android:pathData="M6,17H18L14.25,12L11.25,16L9,13ZM5,21Q4.175,21 3.587,20.413Q3,19.825 3,19V5Q3,4.175 3.587,3.587Q4.175,3 5,3H19Q19.825,3 20.413,3.587Q21,4.175 21,5V19Q21,19.825 20.413,20.413Q19.825,21 19,21ZM5,19H19Q19,19 19,19Q19,19 19,19V5Q19,5 19,5Q19,5 19,5H5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19ZM5,5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19Q5,19 5,19Q5,19 5,19V5Q5,5 5,5Q5,5 5,5Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_watch.xml b/packages/CompanionDeviceManager/res/drawable/ic_watch.xml
new file mode 100644
index 0000000..44a40b9f
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable/ic_watch.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="?attr/colorControlNormal">
+    <path android:fillColor="@android:color/white"
+          android:pathData="M9,22 L7.65,17.45Q6.45,16.5 5.725,15.075Q5,13.65 5,12Q5,10.35 5.725,8.925Q6.45,7.5 7.65,6.55L9,2H15L16.35,6.55Q17.55,7.5 18.275,8.925Q19,10.35 19,12Q19,13.65 18.275,15.075Q17.55,16.5 16.35,17.45L15,22ZM12,17Q14.075,17 15.538,15.537Q17,14.075 17,12Q17,9.925 15.538,8.462Q14.075,7 12,7Q9.925,7 8.463,8.462Q7,9.925 7,12Q7,14.075 8.463,15.537Q9.925,17 12,17ZM10.1,5.25Q11.075,4.975 12,4.975Q12.925,4.975 13.9,5.25L13.5,4H10.5ZM10.5,20H13.5L13.9,18.75Q12.925,19.025 12,19.025Q11.075,19.025 10.1,18.75ZM10.1,4H10.5H13.5H13.9Q12.925,4 12,4Q11.075,4 10.1,4ZM10.5,20H10.1Q11.075,20 12,20Q12.925,20 13.9,20H13.5Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
index f30dadf..8eec33a 100644
--- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
@@ -20,61 +20,98 @@
     <!-- A header for selfManaged devices only. -->
     <include layout="@layout/vendor_header" />
 
+    <ImageView
+        android:id="@+id/profile_icon"
+        android:layout_width="match_parent"
+        android:layout_height="32dp"
+        android:gravity="center"
+        android:layout_marginBottom="12dp"
+        android:layout_marginTop="1dp"
+        android:tint="@android:color/system_accent1_600"/>
+
     <!-- Do NOT change the ID of the root LinearLayout above: it's referenced in CTS tests. -->
 
     <TextView
-            android:id="@+id/title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            android:paddingHorizontal="12dp"
-            style="@*android:style/TextAppearance.Widget.Toolbar.Title"/>
+        android:id="@+id/title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:paddingHorizontal="12dp"
+        android:layout_marginBottom="12dp"
+        style="@*android:style/TextAppearance.Widget.Toolbar.Title" />
 
     <TextView
-            android:id="@+id/summary"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="12dp"
-            android:layout_marginBottom="12dp"
-            android:gravity="center"
-            android:textColor="?android:attr/textColorSecondary"
-            android:textSize="14sp" />
+        android:id="@+id/summary"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="12dp"
+        android:layout_marginBottom="12dp"
+        android:gravity="center"
+        android:textColor="?android:attr/textColorSecondary"
+        android:textSize="14sp" />
 
     <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1">
+
+        <LinearLayout
+            android:id="@+id/multiple_device_list"
             android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1">
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:visibility="gone">
+
+            <View
+                android:id="@+id/border_top"
+                android:layout_marginTop="12dp"
+                style="@style/DeviceListBorder" />
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/device_list"
+                android:layout_width="match_parent"
+                android:scrollbars="vertical"
+                android:layout_height="200dp" />
+
+            <View
+                android:id="@+id/border_bottom"
+                style="@style/DeviceListBorder" />
+
+        </LinearLayout>
 
         <androidx.recyclerview.widget.RecyclerView
-            android:id="@+id/device_list"
+            android:id="@+id/permission_list"
             android:layout_width="match_parent"
-            android:scrollbars="vertical"
-            android:layout_height="200dp" />
+            android:layout_height="wrap_content" />
 
     </RelativeLayout>
 
     <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:gravity="end">
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_marginTop="24dp">
 
         <!-- Do NOT change the IDs of the buttons: they are referenced in CTS tests. -->
 
         <Button
-                android:id="@+id/btn_negative"
-                style="@android:style/Widget.Material.Button.Borderless.Colored"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/consent_no"
-                android:textColor="?android:attr/textColorSecondary" />
+            android:id="@+id/btn_negative"
+            style="@style/NegativeButton"
+            android:text="@string/consent_no" />
 
         <Button
-                android:id="@+id/btn_positive"
-                style="@android:style/Widget.Material.Button.Borderless.Colored"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/consent_yes" />
+            android:id="@+id/btn_positive"
+            style="@style/PositiveButton"
+            android:text="@string/consent_yes" />
+
+        <Button
+            android:id="@+id/btn_negative_multiple_devices"
+            android:layout_marginLeft="170dp"
+            android:layout_marginBottom="10dp"
+            style="@style/NegativeButtonMultipleDevices"
+            android:textColor = "?android:textColorPrimary"
+            android:visibility="gone"
+            android:text="@string/consent_no" />
 
     </LinearLayout>
 
diff --git a/packages/CompanionDeviceManager/res/layout/data_transfer_confirmation.xml b/packages/CompanionDeviceManager/res/layout/data_transfer_confirmation.xml
index a1855fd..7c50814 100644
--- a/packages/CompanionDeviceManager/res/layout/data_transfer_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/data_transfer_confirmation.xml
@@ -28,45 +28,40 @@
     <!-- Do NOT change the ID of the root LinearLayout above: it's referenced in CTS tests. -->
 
     <TextView
-            android:id="@+id/title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            android:paddingHorizontal="12dp"
-            style="@*android:style/TextAppearance.Widget.Toolbar.Title"/>
+        android:id="@+id/title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:paddingHorizontal="12dp"
+        style="@*android:style/TextAppearance.Widget.Toolbar.Title"/>
 
     <TextView
-            android:id="@+id/summary"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="12dp"
-            android:layout_marginBottom="12dp"
-            android:gravity="center"
-            android:textColor="?android:attr/textColorSecondary"
-            android:textSize="14sp" />
+        android:id="@+id/summary"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="12dp"
+        android:layout_marginBottom="12dp"
+        android:gravity="center"
+        android:textColor="?android:attr/textColorSecondary"
+        android:textSize="14sp" />
 
     <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:gravity="end">
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_marginTop="24dp">
 
         <!-- Do NOT change the IDs of the buttons: they are referenced in CTS tests. -->
 
         <Button
-                android:id="@+id/btn_negative"
-                style="@android:style/Widget.Material.Button.Borderless.Colored"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/consent_no"
-                android:textColor="?android:attr/textColorSecondary" />
+            android:id="@+id/btn_negative"
+            style="@style/NegativeButton"
+            android:text="@string/consent_no" />
 
         <Button
-                android:id="@+id/btn_positive"
-                style="@android:style/Widget.Material.Button.Borderless.Colored"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/consent_yes" />
+            android:id="@+id/btn_positive"
+            style="@style/PositiveButton"
+            android:text="@string/consent_yes" />
 
     </LinearLayout>
 
diff --git a/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml b/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml
index 8fd1fb0..c177039 100644
--- a/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml
@@ -60,4 +60,4 @@
 
     </LinearLayout>
 
-</LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_device.xml b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
index 153fc1f..3c8a81f 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_device.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
@@ -25,16 +25,17 @@
     <!-- Do NOT change the ID of the root LinearLayout above: it's referenced in CTS tests. -->
 
     <ImageView
-            android:id="@android:id/icon"
-            android:layout_width="24dp"
-            android:layout_height="24dp"
-            android:layout_marginRight="12dp"/>
+        android:id="@android:id/icon"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:layout_marginRight="12dp"
+        android:tint="@android:color/system_accent1_600"/>
 
     <TextView
-            android:id="@android:id/text1"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:textAppearance="?android:attr/textAppearanceListItemSmall"/>
+        android:id="@android:id/text1"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:textAppearance="?android:attr/textAppearanceListItemSmall"/>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
new file mode 100644
index 0000000..79aa4e7
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
@@ -0,0 +1,56 @@
+<!--
+  ~ 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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/list_item_permission"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:orientation="horizontal"
+              android:padding="5dp">
+
+    <ImageView
+        android:id="@+id/permission_icon"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:layout_marginTop="7dp"
+        android:layout_marginEnd="12dp"
+        android:tint="@android:color/system_accent1_600"
+        android:contentDescription="Permission Icon"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:gravity="center_vertical"
+        android:padding="6dp">
+
+        <TextView
+            android:id="@+id/permission_name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="16sp"
+            android:textAppearance="?android:attr/textAppearanceListItemSmall"/>
+
+        <TextView
+            android:id="@+id/permission_summary"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="14sp"
+            android:textColor="?android:attr/textColorSecondary"/>
+
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values-night/themes.xml b/packages/CompanionDeviceManager/res/values-night/themes.xml
new file mode 100644
index 0000000..6eb16e7
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/values-night/themes.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ 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.
+  -->
+
+<resources>
+
+    <style name="ChooserActivity"
+           parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
+        <item name="*android:windowFixedHeightMajor">100%</item>
+        <item name="*android:windowFixedHeightMinor">100%</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+    </style>
+
+</resources>
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index 9626751..55a1998 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -38,8 +38,14 @@
 
     <!-- ================= DEVICE_PROFILE_APP_STREAMING ================= -->
 
+    <!-- Apps permission will be granted of APP_STREAMING profile [CHAR LIMIT=30] -->
+    <string name="permission_apps">Apps</string>
+
+    <!-- Description of apps permission of APP_STREAMING profile [CHAR LIMIT=NONE] -->
+    <string name="permission_apps_summary">Stream your phone\u2019s apps</string>
+
     <!-- Confirmation for associating an application with a companion device of APP_STREAMING profile (type) [CHAR LIMIT=NONE] -->
-    <string name="title_app_streaming">Allow &lt;strong&gt;<xliff:g id="app_name" example="Exo">%1$s</xliff:g>&lt;/strong&gt; to access this information for your phone</string>
+    <string name="title_app_streaming">Allow &lt;strong&gt;<xliff:g id="app_name" example="Exo">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone</string>
 
     <!-- Description of the privileges the application will get if associated with the companion device of APP_STREAMING profile (type) [CHAR LIMIT=NONE] -->
     <string name="summary_app_streaming" product="default">Let &lt;strong&gt;<xliff:g id="app_name" example="Exo">%1$s</xliff:g>&lt;/strong&gt; to provide &lt;strong&gt;<xliff:g id="device_name" example="Pixelbook Go">%2$s</xliff:g>&lt;/strong&gt; remote access to access to applications installed on this phone when connected.</string>
@@ -72,6 +78,18 @@
     <!-- Description of the privileges the application will get if associated with the companion device of COMPUTER profile (type) [CHAR LIMIT=NONE] -->
     <string name="summary_computer"></string>
 
+    <!-- Notification permission will be granted of COMPUTER profile [CHAR LIMIT=30] -->
+    <string name="permission_notification">Notifications</string>
+
+    <!-- Description of notification permission of COMPUTER profile [CHAR LIMIT=NONE] -->
+    <string name="permission_notification_summary">Can read all notifications, including information like contracts, messages, and photos</string>
+
+    <!-- Storage permission will be granted of COMPUTER profile [CHAR LIMIT=30] -->
+    <string name="permission_storage">Photos and media</string>
+
+    <!-- Description of storage permission of COMPUTER profile [CHAR LIMIT=NONE] -->
+    <string name="permission_storage_summary"></string>
+
     <!-- Title of the helper dialog for COMPUTER profile [CHAR LIMIT=30]. -->
     <string name="helper_title_computer">Google Play services</string>
 
diff --git a/packages/CompanionDeviceManager/res/values/styles.xml b/packages/CompanionDeviceManager/res/values/styles.xml
index bba45e9..6eaffd4 100644
--- a/packages/CompanionDeviceManager/res/values/styles.xml
+++ b/packages/CompanionDeviceManager/res/values/styles.xml
@@ -35,4 +35,40 @@
         <item name="android:background">@drawable/helper_ok_button</item>
     </style>
 
+    <style name="NegativeButton"
+           parent="@android:style/Widget.Material.Button.Borderless.Colored">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textAllCaps">false</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:textColor">@android:color/system_neutral1_900</item>
+        <item name="android:background">@drawable/btn_negative_top</item>
+    </style>
+
+    <style name="PositiveButton"
+           parent="@android:style/Widget.Material.Button.Borderless.Colored">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textAllCaps">false</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:textColor">@android:color/system_neutral1_900</item>
+        <item name="android:layout_marginTop">4dp</item>
+        <item name="android:background">@drawable/btn_positive_bottom</item>
+    </style>
+
+    <style name="NegativeButtonMultipleDevices"
+           parent="@android:style/Widget.Material.Button.Colored">
+        <item name="android:layout_width">100dp</item>
+        <item name="android:layout_height">35dp</item>
+        <item name="android:layout_marginTop">20dp</item>
+        <item name="android:textAllCaps">false</item>
+        <item name="android:background">@drawable/btn_negative_multiple_devices</item>
+    </style>
+
+    <style name="DeviceListBorder">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">1dp</item>
+        <item name="android:background">@android:color/system_accent1_300</item>
+    </style>
+
 </resources>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values/themes.xml b/packages/CompanionDeviceManager/res/values/themes.xml
index 7240432..e3fc67c 100644
--- a/packages/CompanionDeviceManager/res/values/themes.xml
+++ b/packages/CompanionDeviceManager/res/values/themes.xml
@@ -17,11 +17,10 @@
 <resources>
 
     <style name="ChooserActivity"
-           parent="@android:style/Theme.DeviceDefault.Light.Dialog">
+           parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar">
         <item name="*android:windowFixedHeightMajor">100%</item>
         <item name="*android:windowFixedHeightMinor">100%</item>
         <item name="android:windowBackground">@android:color/transparent</item>
-        <item name="android:forceDarkAllowed">true</item>
     </style>
 
 </resources>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index 0fba250..f752b69 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -24,8 +24,12 @@
 
 import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.DiscoveryState;
 import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.DiscoveryState.FINISHED_TIMEOUT;
+import static com.android.companiondevicemanager.PermissionListAdapter.TYPE_APPS;
+import static com.android.companiondevicemanager.PermissionListAdapter.TYPE_NOTIFICATION;
+import static com.android.companiondevicemanager.PermissionListAdapter.TYPE_STORAGE;
 import static com.android.companiondevicemanager.Utils.getApplicationLabel;
 import static com.android.companiondevicemanager.Utils.getHtmlFromResources;
+import static com.android.companiondevicemanager.Utils.getIcon;
 import static com.android.companiondevicemanager.Utils.getVendorHeaderIcon;
 import static com.android.companiondevicemanager.Utils.getVendorHeaderName;
 import static com.android.companiondevicemanager.Utils.prepareResultReceiverForIpc;
@@ -61,6 +65,7 @@
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -102,6 +107,9 @@
     private TextView mTitle;
     private TextView mSummary;
 
+    // Present for single device and multiple device only.
+    private ImageView mProfileIcon;
+
     // Only present for selfManaged devices.
     private ImageView mVendorHeaderImage;
     private TextView mVendorHeaderName;
@@ -114,16 +122,23 @@
     // Present for self-managed association requests and "single-device" regular association
     // regular.
     private Button mButtonAllow;
-    // Present for all associations.
     private Button mButtonNotAllow;
+    // Present for multiple device association requests only.
+    private Button mButtonNotAllowMultipleDevices;
 
     private LinearLayout mAssociationConfirmationDialog;
+    private LinearLayout mMultipleDeviceList;
     private RelativeLayout mVendorHeader;
 
     // The recycler view is only shown for multiple-device regular association request, after
     // at least one matching device is found.
-    private @Nullable RecyclerView mRecyclerView;
-    private @Nullable DeviceListAdapter mAdapter;
+    private @Nullable RecyclerView mDeviceListRecyclerView;
+    private @Nullable DeviceListAdapter mDeviceAdapter;
+
+
+    // The recycler view is only shown for selfManaged association request.
+    private @Nullable RecyclerView mPermissionListRecyclerView;
+    private @Nullable PermissionListAdapter mPermissionListAdapter;
 
     // The flag used to prevent double taps, that may lead to sending several requests for creating
     // an association to CDM.
@@ -133,6 +148,8 @@
     // onActivityResult() after the association is created.
     private @Nullable DeviceFilterPair<?> mSelectedDevice;
 
+    private @Nullable List<Integer> mPermissionTypes;
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         if (DEBUG) Log.d(TAG, "onCreate()");
@@ -232,24 +249,33 @@
 
         setContentView(R.layout.activity_confirmation);
 
+        mMultipleDeviceList = findViewById(R.id.multiple_device_list);
         mAssociationConfirmationDialog = findViewById(R.id.activity_confirmation);
         mVendorHeader = findViewById(R.id.vendor_header);
 
         mTitle = findViewById(R.id.title);
         mSummary = findViewById(R.id.summary);
 
+        mProfileIcon = findViewById(R.id.profile_icon);
+
         mVendorHeaderImage = findViewById(R.id.vendor_header_image);
         mVendorHeaderName = findViewById(R.id.vendor_header_name);
         mVendorHeaderButton = findViewById(R.id.vendor_header_button);
 
-        mRecyclerView = findViewById(R.id.device_list);
-        mAdapter = new DeviceListAdapter(this, this::onListItemClick);
+        mDeviceListRecyclerView = findViewById(R.id.device_list);
+        mDeviceAdapter = new DeviceListAdapter(this, this::onListItemClick);
+
+        mPermissionListRecyclerView = findViewById(R.id.permission_list);
+        mPermissionListAdapter = new PermissionListAdapter(this);
 
         mButtonAllow = findViewById(R.id.btn_positive);
         mButtonNotAllow = findViewById(R.id.btn_negative);
+        mButtonNotAllowMultipleDevices = findViewById(R.id.btn_negative_multiple_devices);
 
         mButtonAllow.setOnClickListener(this::onPositiveButtonClick);
         mButtonNotAllow.setOnClickListener(this::onNegativeButtonClick);
+        mButtonNotAllowMultipleDevices.setOnClickListener(this::onNegativeButtonClick);
+
         mVendorHeaderButton.setOnClickListener(this::onShowHelperDialog);
 
         if (mRequest.isSelfManaged()) {
@@ -359,7 +385,8 @@
         final Drawable vendorIcon;
         final CharSequence vendorName;
         final Spanned title;
-        final Spanned summary;
+
+        mPermissionTypes = new ArrayList<>();
 
         try {
             vendorIcon = getVendorHeaderIcon(this, packageName, userId);
@@ -372,33 +399,37 @@
 
         switch (deviceProfile) {
             case DEVICE_PROFILE_APP_STREAMING:
-                title = getHtmlFromResources(this, R.string.title_app_streaming, appLabel);
-                summary = getHtmlFromResources(
-                        this, R.string.summary_app_streaming, appLabel, deviceName);
+                title = getHtmlFromResources(this, R.string.title_app_streaming, deviceName);
+                mPermissionTypes.add(TYPE_APPS);
                 break;
 
             case DEVICE_PROFILE_AUTOMOTIVE_PROJECTION:
-                title = getHtmlFromResources(this, R.string.title_automotive_projection, appLabel);
-                summary = getHtmlFromResources(
-                        this, R.string.summary_automotive_projection, appLabel, deviceName);
+                title = getHtmlFromResources(
+                        this, R.string.title_automotive_projection, deviceName);
                 break;
 
             case DEVICE_PROFILE_COMPUTER:
-                title = getHtmlFromResources(this, R.string.title_computer, appLabel);
-                summary = getHtmlFromResources(
-                        this, R.string.summary_computer, appLabel, deviceName);
+                title = getHtmlFromResources(this, R.string.title_computer, deviceName);
+                mPermissionTypes.add(TYPE_NOTIFICATION);
+                mPermissionTypes.add(TYPE_STORAGE);
                 break;
 
             default:
                 throw new RuntimeException("Unsupported profile " + deviceProfile);
         }
 
+        mSummary.setVisibility(View.GONE);
+
+        mPermissionListAdapter.setPermissionType(mPermissionTypes);
+        mPermissionListRecyclerView.setAdapter(mPermissionListAdapter);
+        mPermissionListRecyclerView.setLayoutManager(new LinearLayoutManager(this));
+
         mTitle.setText(title);
-        mSummary.setText(summary);
         mVendorHeaderImage.setImageDrawable(vendorIcon);
         mVendorHeaderName.setText(vendorName);
 
-        mRecyclerView.setVisibility(View.GONE);
+        mDeviceListRecyclerView.setVisibility(View.GONE);
+        mProfileIcon.setVisibility(View.GONE);
         mVendorHeader.setVisibility(View.VISIBLE);
     }
 
@@ -411,7 +442,8 @@
                 deviceFilterPairs -> updateSingleDeviceUi(
                         deviceFilterPairs, deviceProfile, appLabel));
 
-        mRecyclerView.setVisibility(View.GONE);
+        mPermissionListRecyclerView.setVisibility(View.GONE);
+        mDeviceListRecyclerView.setVisibility(View.GONE);
     }
 
     private void updateSingleDeviceUi(List<DeviceFilterPair<?>> deviceFilterPairs,
@@ -425,17 +457,22 @@
         final Spanned title = getHtmlFromResources(
                 this, R.string.confirmation_title, appLabel, deviceName);
         final Spanned summary;
+        final Drawable profileIcon;
 
         if (deviceProfile == null) {
             summary = getHtmlFromResources(this, R.string.summary_generic);
+            profileIcon = getIcon(this, R.drawable.ic_device_other);
+            mSummary.setVisibility(View.GONE);
         } else if (deviceProfile.equals(DEVICE_PROFILE_WATCH)) {
             summary = getHtmlFromResources(this, R.string.summary_watch, appLabel, deviceName);
+            profileIcon = getIcon(this, R.drawable.ic_watch);
         } else {
             throw new RuntimeException("Unsupported profile " + deviceProfile);
         }
 
         mTitle.setText(title);
         mSummary.setText(summary);
+        mProfileIcon.setImageDrawable(profileIcon);
     }
 
     private void initUiForMultipleDevices(CharSequence appLabel) {
@@ -445,12 +482,16 @@
 
         final String profileName;
         final Spanned summary;
+        final Drawable profileIcon;
         if (deviceProfile == null) {
             profileName = getString(R.string.profile_name_generic);
             summary = getHtmlFromResources(this, R.string.summary_generic);
+            profileIcon = getIcon(this, R.drawable.ic_device_other);
+            mSummary.setVisibility(View.GONE);
         } else if (deviceProfile.equals(DEVICE_PROFILE_WATCH)) {
             profileName = getString(R.string.profile_name_watch);
             summary = getHtmlFromResources(this, R.string.summary_watch, appLabel);
+            profileIcon = getIcon(this, R.drawable.ic_watch);
         } else {
             throw new RuntimeException("Unsupported profile " + deviceProfile);
         }
@@ -459,32 +500,36 @@
 
         mTitle.setText(title);
         mSummary.setText(summary);
+        mProfileIcon.setImageDrawable(profileIcon);
 
-        mAdapter = new DeviceListAdapter(this, this::onListItemClick);
+        mDeviceAdapter = new DeviceListAdapter(this, this::onListItemClick);
 
         // TODO: hide the list and show a spinner until a first device matching device is found.
-        mRecyclerView.setAdapter(mAdapter);
-        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
+        mDeviceListRecyclerView.setAdapter(mDeviceAdapter);
+        mDeviceListRecyclerView.setLayoutManager(new LinearLayoutManager(this));
 
         CompanionDeviceDiscoveryService.getScanResult().observe(
                 /* lifecycleOwner */ this,
-                /* observer */ mAdapter);
+                /* observer */ mDeviceAdapter);
 
         // "Remove" consent button: users would need to click on the list item.
         mButtonAllow.setVisibility(View.GONE);
+        mButtonNotAllow.setVisibility(View.GONE);
+        mButtonNotAllowMultipleDevices.setVisibility(View.VISIBLE);
+        mMultipleDeviceList.setVisibility(View.VISIBLE);
     }
 
     private void onListItemClick(int position) {
         if (DEBUG) Log.d(TAG, "onListItemClick() " + position);
 
-        final DeviceFilterPair<?> selectedDevice = mAdapter.getItem(position);
+        final DeviceFilterPair<?> selectedDevice = mDeviceAdapter.getItem(position);
 
         if (mSelectedDevice != null) {
             if (DEBUG) Log.w(TAG, "Already selected.");
             return;
         }
         // Notify the adapter to highlight the selected item.
-        mAdapter.setSelectedPosition(position);
+        mDeviceAdapter.setSelectedPosition(position);
 
         mSelectedDevice = requireNonNull(selectedDevice);
 
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
index e5513b0..8babd3a 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
@@ -15,9 +15,10 @@
  */
 
 package com.android.companiondevicemanager;
+
+import static com.android.companiondevicemanager.Utils.getIcon;
+
 import android.content.Context;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -60,11 +61,11 @@
                 R.layout.list_item_device, parent, false);
         ViewHolder viewHolder = new ViewHolder(view);
         if (viewType == TYPE_WIFI) {
-            viewHolder.mImageView.setImageDrawable(getIcon(
-                    com.android.internal.R.drawable.ic_wifi_signal_3));
+            viewHolder.mImageView.setImageDrawable(
+                    getIcon(mContext, com.android.internal.R.drawable.ic_wifi_signal_3));
         } else {
-            viewHolder.mImageView.setImageDrawable(getIcon(
-                    android.R.drawable.stat_sys_data_bluetooth));
+            viewHolder.mImageView.setImageDrawable(
+                    getIcon(mContext, android.R.drawable.stat_sys_data_bluetooth));
         }
         return viewHolder;
     }
@@ -115,12 +116,6 @@
         return mDevices.get(position).getDevice() instanceof android.net.wifi.ScanResult;
     }
 
-    private Drawable getIcon(int resId) {
-        Drawable icon = mContext.getResources().getDrawable(resId, null);
-        icon.setTint(Color.DKGRAY);
-        return icon;
-    }
-
     public interface OnItemClickListener {
         void onItemClick(int position);
     }
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
new file mode 100644
index 0000000..895b729
--- /dev/null
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
@@ -0,0 +1,128 @@
+/*
+ * 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.companiondevicemanager;
+
+import static com.android.companiondevicemanager.Utils.getHtmlFromResources;
+import static com.android.companiondevicemanager.Utils.getIcon;
+
+import static java.util.Collections.unmodifiableMap;
+
+import android.content.Context;
+import android.text.Spanned;
+import android.util.ArrayMap;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.util.List;
+import java.util.Map;
+
+class PermissionListAdapter extends RecyclerView.Adapter<PermissionListAdapter.ViewHolder> {
+    private final Context mContext;
+
+    private List<Integer> mPermissions;
+
+    static final int TYPE_NOTIFICATION = 0;
+    static final int TYPE_STORAGE = 1;
+    static final int TYPE_APPS = 2;
+
+    private static final Map<Integer, Integer> sTitleMap;
+    static {
+        final Map<Integer, Integer> map = new ArrayMap<>();
+        map.put(TYPE_NOTIFICATION, R.string.permission_notification);
+        map.put(TYPE_STORAGE, R.string.permission_storage);
+        map.put(TYPE_APPS, R.string.permission_apps);
+        sTitleMap = unmodifiableMap(map);
+    }
+
+    private static final Map<Integer, Integer> sSummaryMap;
+    static {
+        final Map<Integer, Integer> map = new ArrayMap<>();
+        map.put(TYPE_NOTIFICATION, R.string.permission_notification_summary);
+        map.put(TYPE_STORAGE, R.string.permission_storage_summary);
+        map.put(TYPE_APPS, R.string.permission_apps_summary);
+        sSummaryMap = unmodifiableMap(map);
+    }
+
+    private static final Map<Integer, Integer> sIconMap;
+    static {
+        final Map<Integer, Integer> map = new ArrayMap<>();
+        map.put(TYPE_NOTIFICATION, R.drawable.ic_notifications);
+        map.put(TYPE_STORAGE, R.drawable.ic_storage);
+        map.put(TYPE_APPS, R.drawable.ic_apps);
+        sIconMap = unmodifiableMap(map);
+    }
+
+    PermissionListAdapter(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        View view = LayoutInflater.from(parent.getContext()).inflate(
+                R.layout.list_item_permission, parent, false);
+        ViewHolder viewHolder = new ViewHolder(view);
+        viewHolder.mPermissionIcon.setImageDrawable(getIcon(mContext, sIconMap.get(viewType)));
+
+        return viewHolder;
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder holder, int position) {
+        int type = getItemViewType(position);
+        final Spanned title = getHtmlFromResources(mContext, sTitleMap.get(type));
+        final Spanned summary = getHtmlFromResources(mContext, sSummaryMap.get(type));
+
+        holder.mPermissionName.setText(title);
+        holder.mPermissionSummary.setText(summary);
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        return mPermissions.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public int getItemCount() {
+        return mPermissions != null ? mPermissions.size() : 0;
+    }
+
+    static class ViewHolder extends RecyclerView.ViewHolder {
+        private final TextView mPermissionName;
+        private final TextView mPermissionSummary;
+        private final ImageView mPermissionIcon;
+        ViewHolder(View itemView) {
+            super(itemView);
+            mPermissionName = itemView.findViewById(R.id.permission_name);
+            mPermissionSummary = itemView.findViewById(R.id.permission_summary);
+            mPermissionIcon = itemView.findViewById(R.id.permission_icon);
+        }
+    }
+
+    void setPermissionType(List<Integer> permissions) {
+        mPermissions = permissions;
+    }
+}
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
index 76bbcfb..1852e82 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
@@ -121,6 +121,11 @@
         return appInfo;
     }
 
+    static @NonNull Drawable getIcon(@NonNull Context context, int resId) {
+        Drawable icon = context.getResources().getDrawable(resId, null);
+        return icon;
+    }
+
     static void runOnMainThread(Runnable runnable) {
         if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
             runnable.run();
diff --git a/packages/ConnectivityT/framework-t/Android.bp b/packages/ConnectivityT/framework-t/Android.bp
index 6652780..217a1f67c3 100644
--- a/packages/ConnectivityT/framework-t/Android.bp
+++ b/packages/ConnectivityT/framework-t/Android.bp
@@ -154,17 +154,17 @@
     ],
 }
 
+// TODO: remove this empty filegroup.
 filegroup {
     name: "framework-connectivity-tiramisu-sources",
-    srcs: [
-        ":framework-connectivity-ethernet-sources",
-    ],
+    srcs: [],
     visibility: ["//frameworks/base"],
 }
 
 filegroup {
     name: "framework-connectivity-tiramisu-updatable-sources",
     srcs: [
+        ":framework-connectivity-ethernet-sources",
         ":framework-connectivity-ipsec-sources",
         ":framework-connectivity-netstats-sources",
         ":framework-connectivity-nsd-sources",
diff --git a/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java b/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
index 9bffbfb..61b34d0 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
@@ -34,8 +34,9 @@
     private ConnectivityFrameworkInitializerTiramisu() {}
 
     /**
-     * Called by {@link SystemServiceRegistry}'s static initializer and registers nsd services to
-     * {@link Context}, so that {@link Context#getSystemService} can return them.
+     * Called by {@link SystemServiceRegistry}'s static initializer and registers NetworkStats, nsd,
+     * ipsec and ethernet services to {@link Context}, so that {@link Context#getSystemService} can
+     * return them.
      *
      * @throws IllegalStateException if this is called anywhere besides
      * {@link SystemServiceRegistry}.
@@ -68,5 +69,14 @@
                     return new NetworkStatsManager(context, service);
                 }
         );
+
+        SystemServiceRegistry.registerContextAwareService(
+                Context.ETHERNET_SERVICE,
+                EthernetManager.class,
+                (context, serviceBinder) -> {
+                    IEthernetManager service = IEthernetManager.Stub.asInterface(serviceBinder);
+                    return new EthernetManager(context, service);
+                }
+        );
     }
 }
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java
index 72243f9..793f28d 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java
@@ -33,7 +33,7 @@
 import android.os.RemoteException;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.os.BackgroundThread;
+import com.android.modules.utils.BackgroundThread;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -511,7 +511,6 @@
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
             android.Manifest.permission.NETWORK_STACK,
             android.Manifest.permission.MANAGE_ETHERNET_NETWORKS})
-    @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
     public void updateConfiguration(
             @NonNull String iface,
             @NonNull EthernetNetworkUpdateRequest request,
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
index a626971..43f4c40f 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
@@ -24,36 +24,52 @@
 
 import java.util.Objects;
 
-/** @hide */
+/**
+ * Represents a request to update an existing Ethernet interface.
+ *
+ * @see EthernetManager#updateConfiguration
+ *
+ * @hide
+ */
 @SystemApi
 public final class EthernetNetworkUpdateRequest implements Parcelable {
     @NonNull
     private final IpConfiguration mIpConfig;
-    @NonNull
+    @Nullable
     private final NetworkCapabilities mNetworkCapabilities;
 
+    /**
+     * @return the new {@link IpConfiguration}.
+     */
     @NonNull
     public IpConfiguration getIpConfiguration() {
         return new IpConfiguration(mIpConfig);
     }
 
-    @NonNull
+    /**
+     * Setting the {@link NetworkCapabilities} is optional in {@link EthernetNetworkUpdateRequest}.
+     * When set to null, the existing NetworkCapabilities are not updated.
+     *
+     * @return the new {@link NetworkCapabilities} or null.
+     */
+    @Nullable
     public NetworkCapabilities getNetworkCapabilities() {
-        return new NetworkCapabilities(mNetworkCapabilities);
+        return mNetworkCapabilities == null ? null : new NetworkCapabilities(mNetworkCapabilities);
     }
 
     private EthernetNetworkUpdateRequest(@NonNull final IpConfiguration ipConfig,
-            @NonNull final NetworkCapabilities networkCapabilities) {
+            @Nullable final NetworkCapabilities networkCapabilities) {
         Objects.requireNonNull(ipConfig);
-        Objects.requireNonNull(networkCapabilities);
-        mIpConfig = new IpConfiguration(ipConfig);
-        mNetworkCapabilities = new NetworkCapabilities(networkCapabilities);
+        mIpConfig = ipConfig;
+        mNetworkCapabilities = networkCapabilities;
     }
 
     private EthernetNetworkUpdateRequest(@NonNull final Parcel source) {
         Objects.requireNonNull(source);
-        mIpConfig = IpConfiguration.CREATOR.createFromParcel(source);
-        mNetworkCapabilities = NetworkCapabilities.CREATOR.createFromParcel(source);
+        mIpConfig = source.readParcelable(IpConfiguration.class.getClassLoader(),
+                IpConfiguration.class);
+        mNetworkCapabilities = source.readParcelable(NetworkCapabilities.class.getClassLoader(),
+                NetworkCapabilities.class);
     }
 
     /**
@@ -75,7 +91,8 @@
         public Builder(@NonNull final EthernetNetworkUpdateRequest request) {
             Objects.requireNonNull(request);
             mBuilderIpConfig = new IpConfiguration(request.mIpConfig);
-            mBuilderNetworkCapabilities = new NetworkCapabilities(request.mNetworkCapabilities);
+            mBuilderNetworkCapabilities = null == request.mNetworkCapabilities
+                    ? null : new NetworkCapabilities(request.mNetworkCapabilities);
         }
 
         /**
@@ -85,7 +102,6 @@
          */
         @NonNull
         public Builder setIpConfiguration(@NonNull final IpConfiguration ipConfig) {
-            Objects.requireNonNull(ipConfig);
             mBuilderIpConfig = new IpConfiguration(ipConfig);
             return this;
         }
@@ -96,9 +112,8 @@
          * @return The builder to facilitate chaining.
          */
         @NonNull
-        public Builder setNetworkCapabilities(@NonNull final NetworkCapabilities nc) {
-            Objects.requireNonNull(nc);
-            mBuilderNetworkCapabilities = new NetworkCapabilities(nc);
+        public Builder setNetworkCapabilities(@Nullable final NetworkCapabilities nc) {
+            mBuilderNetworkCapabilities = nc == null ? null : new NetworkCapabilities(nc);
             return this;
         }
 
@@ -135,8 +150,8 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        mIpConfig.writeToParcel(dest, flags);
-        mNetworkCapabilities.writeToParcel(dest, flags);
+        dest.writeParcelable(mIpConfig, flags);
+        dest.writeParcelable(mNetworkCapabilities, flags);
     }
 
     @Override
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
index a48f94b..da5f88d 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
@@ -189,14 +189,14 @@
     public void dumpDebug(ProtoOutputStream proto, long tag) {
         final long start = proto.start(tag);
 
-        proto.write(NetworkIdentityProto.TYPE_FIELD_NUMBER, mType);
+        proto.write(NetworkIdentityProto.TYPE, mType);
 
         // TODO: dump mRatType as well.
 
-        proto.write(NetworkIdentityProto.ROAMING_FIELD_NUMBER, mRoaming);
-        proto.write(NetworkIdentityProto.METERED_FIELD_NUMBER, mMetered);
-        proto.write(NetworkIdentityProto.DEFAULT_NETWORK_FIELD_NUMBER, mDefaultNetwork);
-        proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK_FIELD_NUMBER, mOemManaged);
+        proto.write(NetworkIdentityProto.ROAMING, mRoaming);
+        proto.write(NetworkIdentityProto.METERED, mMetered);
+        proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork);
+        proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged);
 
         proto.end(start);
     }
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
index 56461ba..ad3a958 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
@@ -222,7 +222,7 @@
         final long start = proto.start(tag);
 
         for (NetworkIdentity ident : this) {
-            ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES_FIELD_NUMBER);
+            ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES);
         }
 
         proto.end(start);
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java
index f681ba1..06f2a62 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java
@@ -327,16 +327,11 @@
          * @param uid uid of this {@link Entry}. {@link #UID_TETHERING} if this {@link Entry} is
          *            for tethering. Or {@link #UID_ALL} if this {@link NetworkStats} is only
          *            counting iface stats.
-         * @param set usage state of this {@link Entry}. Should be one of the following
-         *            values: {@link #SET_DEFAULT}, {@link #SET_FOREGROUND}.
+         * @param set usage state of this {@link Entry}.
          * @param tag tag of this {@link Entry}.
-         * @param metered metered state of this {@link Entry}. Should be one of the following
-         *                values: {link #METERED_YES}, {link #METERED_NO}.
-         * @param roaming roaming state of this {@link Entry}. Should be one of the following
-         *                values: {link #ROAMING_YES}, {link #ROAMING_NO}.
-         * @param defaultNetwork default network status of this {@link Entry}. Should be one
-         *                       of the following values: {link #DEFAULT_NETWORK_YES},
-         *                       {link #DEFAULT_NETWORK_NO}.
+         * @param metered metered state of this {@link Entry}.
+         * @param roaming roaming state of this {@link Entry}.
+         * @param defaultNetwork default network status of this {@link Entry}.
          * @param rxBytes Number of bytes received for this {@link Entry}. Statistics should
          *                represent the contents of IP packets, including IP headers.
          * @param rxPackets Number of packets received for this {@link Entry}. Statistics should
@@ -401,8 +396,7 @@
         }
 
         /**
-         * @return the set state of this entry. Should be one of the following
-         * values: {@link #SET_DEFAULT}, {@link #SET_FOREGROUND}.
+         * @return the set state of this entry.
          */
         @State public int getSet() {
             return set;
@@ -416,24 +410,21 @@
         }
 
         /**
-         * @return the metered state. Should be one of the following
-         * values: {link #METERED_YES}, {link #METERED_NO}.
+         * @return the metered state.
          */
         @Meteredness public int getMetered() {
             return metered;
         }
 
         /**
-         * @return the roaming state. Should be one of the following
-         * values: {link #ROAMING_YES}, {link #ROAMING_NO}.
+         * @return the roaming state.
          */
         @Roaming public int getRoaming() {
             return roaming;
         }
 
         /**
-         * @return the default network state. Should be one of the following
-         * values: {link #DEFAULT_NETWORK_YES}, {link #DEFAULT_NETWORK_NO}.
+         * @return the default network state.
          */
         @DefaultNetwork public int getDefaultNetwork() {
             return defaultNetwork;
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
index 67d48f0..e385b33 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
@@ -36,6 +36,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.net.NetworkStats.State;
 import android.net.NetworkStatsHistory.Entry;
 import android.os.Binder;
 import android.service.NetworkStatsCollectionKeyProto;
@@ -102,7 +103,7 @@
 
     private ArrayMap<Key, NetworkStatsHistory> mStats = new ArrayMap<>();
 
-    private final long mBucketDuration;
+    private final long mBucketDurationMillis;
 
     private long mStartMillis;
     private long mEndMillis;
@@ -115,8 +116,8 @@
      * @param bucketDuration duration of the buckets in this object, in milliseconds.
      * @hide
      */
-    public NetworkStatsCollection(long bucketDuration) {
-        mBucketDuration = bucketDuration;
+    public NetworkStatsCollection(long bucketDurationMillis) {
+        mBucketDurationMillis = bucketDurationMillis;
         reset();
     }
 
@@ -148,7 +149,7 @@
         if (mStartMillis == Long.MAX_VALUE) {
             return Long.MAX_VALUE;
         } else {
-            return mStartMillis + mBucketDuration;
+            return mStartMillis + mBucketDurationMillis;
         }
     }
 
@@ -184,10 +185,10 @@
                 || time == SubscriptionPlan.TIME_UNKNOWN) {
             return time;
         } else {
-            final long mod = time % mBucketDuration;
+            final long mod = time % mBucketDurationMillis;
             if (mod > 0) {
                 time -= mod;
-                time += mBucketDuration;
+                time += mBucketDurationMillis;
             }
             return time;
         }
@@ -200,7 +201,7 @@
                 || time == SubscriptionPlan.TIME_UNKNOWN) {
             return time;
         } else {
-            final long mod = time % mBucketDuration;
+            final long mod = time % mBucketDurationMillis;
             if (mod > 0) {
                 time -= mod;
             }
@@ -247,10 +248,10 @@
         // 180 days of history should be enough for anyone; if we end up needing
         // more, we'll dynamically grow the history object.
         final int bucketEstimate = (int) NetworkStatsUtils.constrain(
-                ((end - start) / mBucketDuration), 0,
-                (180 * DateUtils.DAY_IN_MILLIS) / mBucketDuration);
+                ((end - start) / mBucketDurationMillis), 0,
+                (180 * DateUtils.DAY_IN_MILLIS) / mBucketDurationMillis);
         final NetworkStatsHistory combined = new NetworkStatsHistory(
-                mBucketDuration, bucketEstimate, fields);
+                mBucketDurationMillis, bucketEstimate, fields);
 
         // shortcut when we know stats will be empty
         if (start == end) return combined;
@@ -343,7 +344,7 @@
 
             // Finally we can slice data as originally requested
             final NetworkStatsHistory sliced = new NetworkStatsHistory(
-                    mBucketDuration, bucketEstimate, fields);
+                    mBucketDurationMillis, bucketEstimate, fields);
             sliced.recordHistory(combined, start, end);
             return sliced;
         } else {
@@ -458,9 +459,9 @@
         // update when no existing, or when bucket duration changed
         NetworkStatsHistory updated = null;
         if (existing == null) {
-            updated = new NetworkStatsHistory(mBucketDuration, 10);
-        } else if (existing.getBucketDuration() != mBucketDuration) {
-            updated = new NetworkStatsHistory(existing, mBucketDuration);
+            updated = new NetworkStatsHistory(mBucketDurationMillis, 10);
+        } else if (existing.getBucketDuration() != mBucketDurationMillis) {
+            updated = new NetworkStatsHistory(existing, mBucketDurationMillis);
         }
 
         if (updated != null) {
@@ -702,7 +703,7 @@
 
     private int estimateBuckets() {
         return (int) (Math.min(mEndMillis - mStartMillis, WEEK_IN_MILLIS * 5)
-                / mBucketDuration);
+                / mBucketDurationMillis);
     }
 
     private ArrayList<Key> getSortedKeys() {
@@ -732,19 +733,19 @@
         final long start = proto.start(tag);
 
         for (Key key : getSortedKeys()) {
-            final long startStats = proto.start(NetworkStatsCollectionProto.STATS_FIELD_NUMBER);
+            final long startStats = proto.start(NetworkStatsCollectionProto.STATS);
 
             // Key
-            final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY_FIELD_NUMBER);
-            key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY_FIELD_NUMBER);
-            proto.write(NetworkStatsCollectionKeyProto.UID_FIELD_NUMBER, key.uid);
-            proto.write(NetworkStatsCollectionKeyProto.SET_FIELD_NUMBER, key.set);
-            proto.write(NetworkStatsCollectionKeyProto.TAG_FIELD_NUMBER, key.tag);
+            final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY);
+            key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY);
+            proto.write(NetworkStatsCollectionKeyProto.UID, key.uid);
+            proto.write(NetworkStatsCollectionKeyProto.SET, key.set);
+            proto.write(NetworkStatsCollectionKeyProto.TAG, key.tag);
             proto.end(startKey);
 
             // Value
             final NetworkStatsHistory history = mStats.get(key);
-            history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY_FIELD_NUMBER);
+            history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY);
             proto.end(startStats);
         }
 
@@ -828,7 +829,7 @@
      * Builder class for {@link NetworkStatsCollection}.
      */
     public static final class Builder {
-        private final long mBucketDuration;
+        private final long mBucketDurationMillis;
         private final ArrayMap<Key, NetworkStatsHistory> mEntries = new ArrayMap<>();
 
         /**
@@ -836,8 +837,8 @@
          *
          * @param bucketDuration Duration of the buckets of the object, in milliseconds.
          */
-        public Builder(long bucketDuration) {
-            mBucketDuration = bucketDuration;
+        public Builder(long bucketDurationMillis) {
+            mBucketDurationMillis = bucketDurationMillis;
         }
 
         /**
@@ -855,7 +856,7 @@
             final List<Entry> historyEntries = history.getEntries();
 
             final NetworkStatsHistory.Builder historyBuilder =
-                    new NetworkStatsHistory.Builder(mBucketDuration, historyEntries.size());
+                    new NetworkStatsHistory.Builder(mBucketDurationMillis, historyEntries.size());
             for (Entry entry : historyEntries) {
                 historyBuilder.addEntry(entry);
             }
@@ -871,7 +872,8 @@
          */
         @NonNull
         public NetworkStatsCollection build() {
-            final NetworkStatsCollection collection = new NetworkStatsCollection(mBucketDuration);
+            final NetworkStatsCollection collection =
+                    new NetworkStatsCollection(mBucketDurationMillis);
             for (int i = 0; i < mEntries.size(); i++) {
                 collection.recordHistory(mEntries.keyAt(i), mEntries.valueAt(i));
             }
@@ -883,7 +885,7 @@
      * the identifier that associate with the {@link NetworkStatsHistory} object to identify
      * a certain record in the {@link NetworkStatsCollection} object.
      */
-    public static class Key {
+    public static final class Key {
         /** @hide */
         public final NetworkIdentitySet ident;
         /** @hide */
@@ -903,7 +905,7 @@
          * @param set Set of the record, see {@code NetworkStats#SET_*}.
          * @param tag Tag of the record, see {@link TrafficStats#setThreadStatsTag(int)}.
          */
-        public Key(@NonNull Set<NetworkIdentity> ident, int uid, int set, int tag) {
+        public Key(@NonNull Set<NetworkIdentity> ident, int uid, @State int set, int tag) {
             this(new NetworkIdentitySet(Objects.requireNonNull(ident)), uid, set, tag);
         }
 
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
index 822a16e..301fef9 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
@@ -915,18 +915,18 @@
     public void dumpDebug(ProtoOutputStream proto, long tag) {
         final long start = proto.start(tag);
 
-        proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS_FIELD_NUMBER, bucketDuration);
+        proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS, bucketDuration);
 
         for (int i = 0; i < bucketCount; i++) {
-            final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS_FIELD_NUMBER);
+            final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS);
 
-            proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS_FIELD_NUMBER,
+            proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS,
                     bucketStart[i]);
-            dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES_FIELD_NUMBER, rxBytes, i);
-            dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS_FIELD_NUMBER, rxPackets, i);
-            dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES_FIELD_NUMBER, txBytes, i);
-            dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS_FIELD_NUMBER, txPackets, i);
-            dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS_FIELD_NUMBER, operations, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES, rxBytes, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS, rxPackets, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES, txBytes, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS, txPackets, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS, operations, i);
 
             proto.end(startBucket);
         }
diff --git a/packages/ConnectivityT/service/Android.bp b/packages/ConnectivityT/service/Android.bp
index 5100e7c..4b799c5 100644
--- a/packages/ConnectivityT/service/Android.bp
+++ b/packages/ConnectivityT/service/Android.bp
@@ -102,17 +102,16 @@
     ],
     path: "src",
     visibility: [
-        "//frameworks/opt/net/ethernet",
+        "//frameworks/opt/net/ethernet/tests",
     ],
 }
 
 // Connectivity-T common libraries.
 
+// TODO: remove this empty filegroup.
 filegroup {
     name: "services.connectivity-tiramisu-sources",
-    srcs: [
-        ":services.connectivity-ethernet-sources",
-    ],
+    srcs: [],
     path: "src",
     visibility: ["//frameworks/base/services/core"],
 }
@@ -120,6 +119,7 @@
 filegroup {
     name: "services.connectivity-tiramisu-updatable-sources",
     srcs: [
+        ":services.connectivity-ethernet-sources",
         ":services.connectivity-ipsec-sources",
         ":services.connectivity-netstats-sources",
         ":services.connectivity-nsd-sources",
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
index 151c90d..3b93f1a 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
@@ -25,9 +25,9 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
-import android.net.ConnectivityManager;
 import android.net.NetworkStats;
 import android.net.UnderlyingNetworkInfo;
+import android.os.ServiceSpecificException;
 import android.os.StrictMode;
 import android.os.SystemClock;
 
@@ -35,6 +35,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ProcFileReader;
 import com.android.net.module.util.CollectionUtils;
+import com.android.server.BpfNetMaps;
 
 import libcore.io.IoUtils;
 
@@ -74,6 +75,8 @@
 
     private final Context mContext;
 
+    private final BpfNetMaps mBpfNetMaps;
+
     /**
      * Guards persistent data access in this class
      *
@@ -170,6 +173,7 @@
         mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
         mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
         mUseBpfStats = useBpfStats;
+        mBpfNetMaps = new BpfNetMaps();
         synchronized (mPersistentDataLock) {
             mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1);
             mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
@@ -297,12 +301,14 @@
     }
 
     @GuardedBy("mPersistentDataLock")
-    private void requestSwapActiveStatsMapLocked() {
-        // Do a active map stats swap. When the binder call successfully returns,
-        // the system server should be able to safely read and clean the inactive map
-        // without race problem.
-        final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
-        cm.swapActiveStatsMap();
+    private void requestSwapActiveStatsMapLocked() throws IOException {
+        try {
+            // Do a active map stats swap. Once the swap completes, this code
+            // can read and clean the inactive map without races.
+            mBpfNetMaps.swapActiveStatsMap();
+        } catch (ServiceSpecificException e) {
+            throw new IOException(e);
+        }
     }
 
     /**
@@ -328,11 +334,7 @@
                 final NetworkStats stats =
                         new NetworkStats(SystemClock.elapsedRealtime(), 0 /* initialSize */);
                 if (mUseBpfStats) {
-                    try {
-                        requestSwapActiveStatsMapLocked();
-                    } catch (RuntimeException e) {
-                        throw new IOException(e);
-                    }
+                    requestSwapActiveStatsMapLocked();
                     // Stats are always read from the inactive map, so they must be read after the
                     // swap
                     if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), UID_ALL,
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java
index a006cd5..f62765d 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java
@@ -471,11 +471,11 @@
     public void dumpDebugLocked(ProtoOutputStream proto, long tag) {
         final long start = proto.start(tag);
         if (mPending != null) {
-            proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES_FIELD_NUMBER,
+            proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES,
                     mPending.getTotalBytes());
         }
         getOrLoadCompleteLocked().dumpDebug(proto,
-                NetworkStatsRecorderProto.COMPLETE_HISTORY_FIELD_NUMBER);
+                NetworkStatsRecorderProto.COMPLETE_HISTORY);
         proto.end(start);
     }
 
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
index ef6f39a..1d22908 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
@@ -565,7 +565,7 @@
                 return new BpfMap<U32, U8>(UID_COUNTERSET_MAP_PATH, BpfMap.BPF_F_RDWR,
                         U32.class, U8.class);
             } catch (ErrnoException e) {
-                Log.wtf(TAG, "Cannot create uid counter set map: " + e);
+                Log.wtf(TAG, "Cannot open uid counter set map: " + e);
                 return null;
             }
         }
@@ -576,7 +576,7 @@
                 return new BpfMap<CookieTagMapKey, CookieTagMapValue>(COOKIE_TAG_MAP_PATH,
                         BpfMap.BPF_F_RDWR, CookieTagMapKey.class, CookieTagMapValue.class);
             } catch (ErrnoException e) {
-                Log.wtf(TAG, "Cannot create cookie tag map: " + e);
+                Log.wtf(TAG, "Cannot open cookie tag map: " + e);
                 return null;
             }
         }
@@ -587,7 +587,7 @@
                 return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_A_PATH,
                         BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class);
             } catch (ErrnoException e) {
-                Log.wtf(TAG, "Cannot create stats map A: " + e);
+                Log.wtf(TAG, "Cannot open stats map A: " + e);
                 return null;
             }
         }
@@ -598,7 +598,7 @@
                 return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_B_PATH,
                         BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class);
             } catch (ErrnoException e) {
-                Log.wtf(TAG, "Cannot create stats map B: " + e);
+                Log.wtf(TAG, "Cannot open stats map B: " + e);
                 return null;
             }
         }
@@ -609,7 +609,7 @@
                 return new BpfMap<UidStatsMapKey, StatsMapValue>(APP_UID_STATS_MAP_PATH,
                         BpfMap.BPF_F_RDWR, UidStatsMapKey.class, StatsMapValue.class);
             } catch (ErrnoException e) {
-                Log.wtf(TAG, "Cannot create app uid stats map: " + e);
+                Log.wtf(TAG, "Cannot open app uid stats map: " + e);
                 return null;
             }
         }
@@ -2132,15 +2132,15 @@
 
         // TODO Right now it writes all history.  Should it limit to the "since-boot" log?
 
-        dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES_FIELD_NUMBER,
+        dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES,
                 mActiveIfaces);
-        dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES_FIELD_NUMBER,
+        dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES,
                 mActiveUidIfaces);
-        mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS_FIELD_NUMBER);
-        mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS_FIELD_NUMBER);
-        mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS_FIELD_NUMBER);
+        mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
+        mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
+        mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
         mUidTagRecorder.dumpDebugLocked(proto,
-                NetworkStatsServiceDumpProto.UID_TAG_STATS_FIELD_NUMBER);
+                NetworkStatsServiceDumpProto.UID_TAG_STATS);
 
         proto.flush();
     }
@@ -2150,8 +2150,8 @@
         for (int i = 0; i < ifaces.size(); i++) {
             final long start = proto.start(tag);
 
-            proto.write(NetworkInterfaceProto.INTERFACE_FIELD_NUMBER, ifaces.keyAt(i));
-            ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES_FIELD_NUMBER);
+            proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
+            ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES);
 
             proto.end(start);
         }
diff --git a/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java b/packages/ConnectivityT/tests/unit/java/com/android/server/net/IpConfigStoreTest.java
similarity index 92%
rename from services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
rename to packages/ConnectivityT/tests/unit/java/com/android/server/net/IpConfigStoreTest.java
index 2f77126..ad0be58 100644
--- a/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
+++ b/packages/ConnectivityT/tests/unit/java/com/android/server/net/IpConfigStoreTest.java
@@ -48,10 +48,16 @@
  */
 @RunWith(AndroidJUnit4.class)
 public class IpConfigStoreTest {
+    private static final int KEY_CONFIG = 17;
+    private static final String IFACE_1 = "eth0";
+    private static final String IFACE_2 = "eth1";
+    private static final String IP_ADDR_1 = "192.168.1.10/24";
+    private static final String IP_ADDR_2 = "192.168.1.20/24";
+    private static final String DNS_IP_ADDR_1 = "1.2.3.4";
+    private static final String DNS_IP_ADDR_2 = "5.6.7.8";
 
     @Test
     public void backwardCompatibility2to3() throws IOException {
-        final int KEY_CONFIG = 17;
         ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
         DataOutputStream outputStream = new DataOutputStream(byteStream);
 
@@ -73,13 +79,6 @@
 
     @Test
     public void staticIpMultiNetworks() throws Exception {
-        final String IFACE_1 = "eth0";
-        final String IFACE_2 = "eth1";
-        final String IP_ADDR_1 = "192.168.1.10/24";
-        final String IP_ADDR_2 = "192.168.1.20/24";
-        final String DNS_IP_ADDR_1 = "1.2.3.4";
-        final String DNS_IP_ADDR_2 = "5.6.7.8";
-
         final ArrayList<InetAddress> dnsServers = new ArrayList<>();
         dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_1));
         dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_2));
@@ -144,11 +143,11 @@
 
     /** Synchronously writes into given byte steam */
     private static class MockedDelayedDiskWrite extends DelayedDiskWrite {
-        final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+        final ByteArrayOutputStream mByteStream = new ByteArrayOutputStream();
 
         @Override
         public void write(String filePath, Writer w) {
-            DataOutputStream outputStream = new DataOutputStream(byteStream);
+            DataOutputStream outputStream = new DataOutputStream(mByteStream);
 
             try {
                 w.onWriteCalled(outputStream);
diff --git a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
index 44b3b4e..706aba3d 100644
--- a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
+++ b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
@@ -51,27 +51,34 @@
     }
 
     /**
-     * Whether current activity is embedded in the Settings app or not.
+     * Whether the current activity is embedded in the Settings app or not.
+     *
+     * @param activity Activity that needs the check
      */
     public static boolean isActivityEmbedded(Activity activity) {
         return SplitController.getInstance().isActivityEmbedded(activity);
     }
 
     /**
-     * Whether current activity is suggested to show back button or not.
+     * Whether the current activity should hide the navigate up button.
+     *
+     * @param activity             Activity that needs the check
+     * @param isSecondLayerPage indicates if the activity(page) is shown in the 2nd layer of
+     *                             Settings app
      */
-    public static boolean shouldHideBackButton(Activity activity, boolean isSecondaryLayerPage) {
+    public static boolean shouldHideNavigateUpButton(Activity activity, boolean isSecondLayerPage) {
         if (!BuildCompat.isAtLeastT()) {
             return false;
         }
-        if (!isSecondaryLayerPage) {
+        if (!isSecondLayerPage) {
             return false;
         }
-        final String shouldHideBackButton = Settings.Global.getString(activity.getContentResolver(),
-                "settings_hide_secondary_page_back_button_in_two_pane");
+        final String shouldHideNavigateUpButton =
+                Settings.Global.getString(activity.getContentResolver(),
+                        "settings_hide_second_layer_page_navigate_up_button_in_two_pane");
 
-        if (TextUtils.isEmpty(shouldHideBackButton)
-                || TextUtils.equals("true", shouldHideBackButton)) {
+        if (TextUtils.isEmpty(shouldHideNavigateUpButton)
+                || Boolean.parseBoolean(shouldHideNavigateUpButton)) {
             return isActivityEmbedded(activity);
         }
         return false;
diff --git a/packages/SystemUI/res/drawable/ic_account_circle.xml b/packages/SettingsLib/res/drawable/ic_account_circle.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/ic_account_circle.xml
rename to packages/SettingsLib/res/drawable/ic_account_circle.xml
diff --git a/packages/SystemUI/res/drawable/ic_account_circle_filled.xml b/packages/SettingsLib/res/drawable/ic_account_circle_filled.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/ic_account_circle_filled.xml
rename to packages/SettingsLib/res/drawable/ic_account_circle_filled.xml
diff --git a/packages/SystemUI/res/drawable/ic_add_supervised_user.xml b/packages/SettingsLib/res/drawable/ic_add_supervised_user.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/ic_add_supervised_user.xml
rename to packages/SettingsLib/res/drawable/ic_add_supervised_user.xml
diff --git a/packages/SystemUI/res/drawable/kg_bg_avatar.xml b/packages/SettingsLib/res/drawable/user_avatar_bg.xml
similarity index 92%
rename from packages/SystemUI/res/drawable/kg_bg_avatar.xml
rename to packages/SettingsLib/res/drawable/user_avatar_bg.xml
index addb3f7..1f50496 100644
--- a/packages/SystemUI/res/drawable/kg_bg_avatar.xml
+++ b/packages/SettingsLib/res/drawable/user_avatar_bg.xml
@@ -22,7 +22,7 @@
         android:viewportHeight="100">
 
     <path
-        android:fillColor="@color/kg_user_switcher_avatar_background"
+        android:fillColor="@color/user_avatar_color_bg"
         android:pathData="M50,50m-50,0a50,50 0,1 1,100 0a50,50 0,1 1,-100 0"/>
 
 </vector>
diff --git a/packages/SettingsLib/res/values-v31/styles.xml b/packages/SettingsLib/res/values-v31/styles.xml
index 343de2c..0b703c9 100644
--- a/packages/SettingsLib/res/values-v31/styles.xml
+++ b/packages/SettingsLib/res/values-v31/styles.xml
@@ -15,7 +15,8 @@
   limitations under the License.
   -->
 <resources>
-    <style name="SettingsLibTabsTextAppearance" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+    <style name="SettingsLibTabsTextAppearance"
+           parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
         <item name="android:textSize">16sp</item>
     </style>
 
@@ -25,6 +26,7 @@
         <item name="android:layout_height">48dp</item>
         <item name="android:layout_marginStart">?android:attr/listPreferredItemPaddingStart</item>
         <item name="android:layout_marginEnd">?android:attr/listPreferredItemPaddingEnd</item>
+        <item name="tabMaxWidth">0dp</item>
         <item name="tabGravity">fill</item>
         <item name="tabBackground">@drawable/settingslib_tabs_background</item>
         <item name="tabIndicator">@drawable/settingslib_tabs_indicator_background</item>
diff --git a/packages/SettingsLib/res/values/colors.xml b/packages/SettingsLib/res/values/colors.xml
index 5e8779f..7ab2ed9 100644
--- a/packages/SettingsLib/res/values/colors.xml
+++ b/packages/SettingsLib/res/values/colors.xml
@@ -36,7 +36,8 @@
     <color name="bt_color_bg_6">#e9d2fd</color> <!-- Material Purple 100 -->
     <color name="bt_color_bg_7">#cbf0f8</color> <!-- Material Cyan 100 -->
 
-
     <color name="dark_mode_icon_color_single_tone">#99000000</color>
     <color name="light_mode_icon_color_single_tone">#ffffff</color>
+
+    <color name="user_avatar_color_bg">?android:attr/colorBackgroundFloating</color>
 </resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index da0381b..579e3d7 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1293,6 +1293,8 @@
     <string name="cancel">Cancel</string>
     <!-- Button label for generic OK action [CHAR LIMIT=20] -->
     <string name="okay">OK</string>
+    <!-- Button label for generic Done action, to be pressed when an action has been completed [CHAR LIMIT=20] -->
+    <string name="done">Done</string>
 
     <!-- Label for the settings activity for controlling apps that can schedule alarms [CHAR LIMIT=30] -->
     <string name="alarms_and_reminders_label">Alarms and reminders</string>
@@ -1342,7 +1344,9 @@
     <string name="notice_header" translatable="false"></string>
 
     <!-- Name of the phone device. [CHAR LIMIT=30] -->
-    <string name="media_transfer_this_device_name">This phone</string>
+    <string name="media_transfer_this_device_name" product="default">This phone</string>
+    <!-- Name of the tablet device. [CHAR LIMIT=30] -->
+    <string name="media_transfer_this_device_name" product="tablet">This tablet</string>
     <!-- Name of the phone device with an active remote session. [CHAR LIMIT=30] -->
     <string name="media_transfer_this_phone">This phone</string>
 
@@ -1426,8 +1430,12 @@
     <string name="user_switch_to_user">Switch to <xliff:g id="user_name" example="John Doe">%s</xliff:g></string>
     <!-- Dialog message when creating a new user [CHAR LIMIT=NONE] -->
     <string name="creating_new_user_dialog_message">Creating new user…</string>
+    <!-- Dialog message when creating a new guest [CHAR LIMIT=NONE] -->
+    <string name="creating_new_guest_dialog_message">Creating new guest…</string>
     <!-- Text shown to notify that the creation of new user has failed. [CHAR LIMIT=40] -->
     <string name="add_user_failed">Failed to create a new user</string>
+    <!-- Text shown to notify that the creation of new guest has failed. [CHAR LIMIT=40] -->
+    <string name="add_guest_failed">Failed to create a new guest</string>
 
     <!-- Title for the preference to enter the nickname of the user to display in the user switcher [CHAR LIMIT=25]-->
     <string name="user_nickname">Nickname</string>
@@ -1568,4 +1576,10 @@
     <!-- Content description for a default user icon. [CHAR LIMIT=NONE] -->
     <string name="default_user_icon_description">Default user icon</string>
 
+    <!-- Title for the 'physical keyboard' settings screen. [CHAR LIMIT=35] -->
+    <string name="physical_keyboard_title">Physical keyboard</string>
+    <!-- Title for the keyboard layout preference dialog. [CHAR LIMIT=35] -->
+    <string name="keyboard_layout_dialog_title">Choose keyboard layout</string>
+    <!-- Label of the default keyboard layout.  [CHAR LIMIT=35] -->
+    <string name="keyboard_layout_default_label">Default</string>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 17db45d..e4efae2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -23,7 +23,6 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.os.Build;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.AttributeSet;
@@ -33,8 +32,6 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
-import com.android.internal.util.Preconditions;
-
 /**
  * Helper class for managing settings preferences that can be disabled
  * by device admins via user restrictions.
@@ -42,8 +39,8 @@
 public class RestrictedPreferenceHelper {
     private final Context mContext;
     private final Preference mPreference;
-    final String packageName;
-    final int uid;
+    String packageName;
+    int uid;
 
     private boolean mDisabledByAdmin;
     private EnforcedAdmin mEnforcedAdmin;
@@ -219,6 +216,11 @@
         return mDisabledByAppOps;
     }
 
+    public void updatePackageDetails(String packageName, int uid) {
+        this.packageName = packageName;
+        this.uid = uid;
+    }
+
     private void updateDisabledState() {
         if (!(mPreference instanceof RestrictedTopLevelPreference)) {
             mPreference.setEnabled(!(mDisabledByAdmin || mDisabledByAppOps));
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index c607d74..091e322 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -18,8 +18,11 @@
 
 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 
+import android.annotation.NonNull;
+import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.os.Process;
 import android.os.UserHandle;
 import android.util.AttributeSet;
 import android.util.TypedValue;
@@ -28,6 +31,7 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import androidx.annotation.VisibleForTesting;
 import androidx.core.content.res.TypedArrayUtils;
 import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceViewHolder;
@@ -39,6 +43,7 @@
  */
 public class RestrictedSwitchPreference extends SwitchPreference {
     RestrictedPreferenceHelper mHelper;
+    AppOpsManager mAppOpsManager;
     boolean mUseAdditionalSummary = false;
     CharSequence mRestrictedSwitchSummary;
     private int mIconSize;
@@ -90,6 +95,11 @@
         this(context, null);
     }
 
+    @VisibleForTesting
+    public void setAppOps(AppOpsManager appOps) {
+        mAppOpsManager = appOps;
+    }
+
     public void setIconSize(int iconSize) {
         mIconSize = iconSize;
     }
@@ -97,6 +107,12 @@
     @Override
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
+        final View switchView = holder.findViewById(android.R.id.switch_widget);
+        if (switchView != null) {
+            final View rootView = switchView.getRootView();
+            rootView.setFilterTouchesWhenObscured(true);
+        }
+
         mHelper.onBindViewHolder(holder);
 
         CharSequence switchSummary;
@@ -164,11 +180,18 @@
 
     @Override
     public void setEnabled(boolean enabled) {
+        boolean changed = false;
         if (enabled && isDisabledByAdmin()) {
             mHelper.setDisabledByAdmin(null);
-            return;
+            changed = true;
         }
-        super.setEnabled(enabled);
+        if (enabled && isDisabledByAppOps()) {
+            mHelper.setDisabledByAppOps(false);
+            changed = true;
+        }
+        if (!changed) {
+            super.setEnabled(enabled);
+        }
     }
 
     public void setDisabledByAdmin(EnforcedAdmin admin) {
@@ -180,4 +203,38 @@
     public boolean isDisabledByAdmin() {
         return mHelper.isDisabledByAdmin();
     }
+
+    private void setDisabledByAppOps(boolean disabled) {
+        if (mHelper.setDisabledByAppOps(disabled)) {
+            notifyChanged();
+        }
+    }
+
+    public boolean isDisabledByAppOps() {
+        return mHelper.isDisabledByAppOps();
+    }
+
+    public int getUid() {
+        return mHelper != null ? mHelper.uid : Process.INVALID_UID;
+    }
+
+    public String getPackageName() {
+        return mHelper != null ? mHelper.packageName : null;
+    }
+
+    public void updateState(@NonNull String packageName, int uid, boolean isEnabled) {
+        mHelper.updatePackageDetails(packageName, uid);
+        if (mAppOpsManager == null) {
+            mAppOpsManager = getContext().getSystemService(AppOpsManager.class);
+        }
+        final int mode = mAppOpsManager.noteOpNoThrow(
+                AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
+                uid, packageName);
+        final boolean appOpsAllowed = mode == AppOpsManager.MODE_ALLOWED;
+        if (appOpsAllowed || isEnabled) {
+            setEnabled(true);
+        } else {
+            setDisabledByAppOps(true);
+        }
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 1c9d9cf..3d91c5a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -285,6 +285,12 @@
 
     public void disconnect() {
         synchronized (mProfileLock) {
+            if (getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
+                for (CachedBluetoothDevice member : getMemberDevice()) {
+                    Log.d(TAG, "Disconnect the member(" + member.getAddress() + ")");
+                    member.disconnect();
+                }
+            }
             mDevice.disconnect();
         }
         // Disconnect  PBAP server in case its connected
@@ -399,6 +405,12 @@
             }
 
             mDevice.connect();
+            if (getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
+                for (CachedBluetoothDevice member : getMemberDevice()) {
+                    Log.d(TAG, "connect the member(" + member.getAddress() + ")");
+                    member.connect();
+                }
+            }
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 5e2f310..7573177 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -24,9 +24,9 @@
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothHeadsetClient;
 import android.bluetooth.BluetoothHearingAid;
-import android.bluetooth.BluetoothLeAudio;
 import android.bluetooth.BluetoothHidDevice;
 import android.bluetooth.BluetoothHidHost;
+import android.bluetooth.BluetoothLeAudio;
 import android.bluetooth.BluetoothMap;
 import android.bluetooth.BluetoothMapClient;
 import android.bluetooth.BluetoothPan;
@@ -159,10 +159,8 @@
         if (mHfpClientProfile == null && supportedList.contains(BluetoothProfile.HEADSET_CLIENT)) {
             if (DEBUG) Log.d(TAG, "Adding local HfpClient profile");
             mHfpClientProfile = new HfpClientProfile(mContext, mDeviceManager, this);
-            addHeadsetProfile(mHfpClientProfile, HfpClientProfile.NAME,
-                    BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED,
-                    BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED,
-                    BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED);
+            addProfile(mHfpClientProfile, HfpClientProfile.NAME,
+                    BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
         }
         if (mMapClientProfile == null && supportedList.contains(BluetoothProfile.MAP_CLIENT)) {
             if (DEBUG) Log.d(TAG, "Adding local MAP CLIENT profile");
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index fcb56d2..01d0cc4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -248,9 +248,6 @@
     }
 
     public @WhenToDream int getWhenToDreamSetting() {
-        if (!isEnabled()) {
-            return NEVER;
-        }
         return isActivatedOnDock() && isActivatedOnSleep() ? EITHER
                 : isActivatedOnDock() ? WHILE_DOCKED
                 : isActivatedOnSleep() ? WHILE_CHARGING
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index c759962..3984ee9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -35,6 +35,7 @@
 import android.graphics.drawable.Drawable;
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2Manager;
+import android.media.NearbyDevice;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -77,6 +78,8 @@
 
     private int mConnectedRecord;
     private int mState;
+    @NearbyDevice.RangeZone
+    private int mRangeZone = NearbyDevice.RANGE_UNKNOWN;
 
     protected final Context mContext;
     protected final MediaRoute2Info mRouteInfo;
@@ -136,6 +139,14 @@
                 getId());
     }
 
+    public @NearbyDevice.RangeZone int getRangeZone() {
+        return mRangeZone;
+    }
+
+    public void setRangeZone(@NearbyDevice.RangeZone int rangeZone) {
+        mRangeZone = rangeZone;
+    }
+
     /**
      * Get name from MediaDevice.
      *
@@ -319,6 +330,11 @@
             }
         }
 
+        // Both devices have same connection status, compare the range zone
+        if (NearbyDevice.compareRangeZones(getRangeZone(), another.getRangeZone()) != 0) {
+            return NearbyDevice.compareRangeZones(getRangeZone(), another.getRangeZone());
+        }
+
         if (mType == another.mType) {
             // Check device is muting expected device
             if (isMutingExpectedDevice()) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java b/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java
index 75bb70a..8a1e91b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java
@@ -106,13 +106,13 @@
 
         FooterButton secondaryButton =
                 new FooterButton.Builder(this)
-                        .setText("Cancel")
+                        .setText(getString(android.R.string.cancel))
                         .setListener(view -> cancel())
                         .build();
 
         mDoneButton =
                 new FooterButton.Builder(this)
-                        .setText("Done")
+                        .setText(getString(R.string.done))
                         .setListener(view -> mAdapter.returnSelectionResult())
                         .build();
         mDoneButton.setEnabled(false);
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/UserCreatingDialog.java b/packages/SettingsLib/src/com/android/settingslib/users/UserCreatingDialog.java
index 075635c..dd86bec 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/UserCreatingDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/UserCreatingDialog.java
@@ -31,11 +31,15 @@
 public class UserCreatingDialog extends AlertDialog {
 
     public UserCreatingDialog(Context context) {
+        this(context, false);
+    }
+
+    public UserCreatingDialog(Context context, boolean isGuest) {
         // hardcoding theme to be consistent with UserSwitchingDialog's theme
         // todo replace both to adapt to the device's theme
         super(context, com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog_Alert);
 
-        inflateContent();
+        inflateContent(isGuest);
         getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
 
         WindowManager.LayoutParams attrs = getWindow().getAttributes();
@@ -44,12 +48,14 @@
         getWindow().setAttributes(attrs);
     }
 
-    private void inflateContent() {
+    private void inflateContent(boolean isGuest) {
         // using the same design as UserSwitchingDialog
         setCancelable(false);
         View view = LayoutInflater.from(getContext())
                 .inflate(R.layout.user_creation_progress_dialog, null);
-        String message = getContext().getString(R.string.creating_new_user_dialog_message);
+        String message = getContext().getString(isGuest
+                ? R.string.creating_new_guest_dialog_message
+                : R.string.creating_new_user_dialog_message);
         view.setAccessibilityPaneTitle(message);
         ((TextView) view.findViewById(R.id.message)).setText(message);
         setView(view);
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
index 4ab6542..9ef6bdf 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
@@ -43,6 +43,31 @@
     private static final int INVALID_RSSI = -127;
 
     /**
+     * The intent action shows Wi-Fi dialog to connect Wi-Fi network.
+     * <p>
+     * Input: The calling package should put the chosen
+     * com.android.wifitrackerlib.WifiEntry#getKey() to a string extra in the request bundle into
+     * the {@link #EXTRA_CHOSEN_WIFI_ENTRY_KEY}.
+     * <p>
+     * Output: Nothing.
+     */
+    @VisibleForTesting
+    static final String ACTION_WIFI_DIALOG = "com.android.settings.WIFI_DIALOG";
+
+    /**
+     * Specify a key that indicates the WifiEntry to be configured.
+     */
+    @VisibleForTesting
+    static final String EXTRA_CHOSEN_WIFI_ENTRY_KEY = "key_chosen_wifientry_key";
+
+    /**
+     * The lookup key for a boolean that indicates whether a chosen WifiEntry request to connect to.
+     * {@code true} means a chosen WifiEntry request to connect to.
+     */
+    @VisibleForTesting
+    static final String EXTRA_CONNECT_FOR_CALLER = "connect_for_caller";
+
+    /**
      * The intent action shows network details settings to allow configuration of Wi-Fi.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -325,6 +350,19 @@
     }
 
     /**
+     * Returns the Intent for Wi-Fi dialog.
+     *
+     * @param key              The Wi-Fi entry key
+     * @param connectForCaller True if a chosen WifiEntry request to connect to
+     */
+    public static Intent getWifiDialogIntent(String key, boolean connectForCaller) {
+        final Intent intent = new Intent(ACTION_WIFI_DIALOG);
+        intent.putExtra(EXTRA_CHOSEN_WIFI_ENTRY_KEY, key);
+        intent.putExtra(EXTRA_CONNECT_FOR_CALLER, connectForCaller);
+        return intent;
+    }
+
+    /**
      * Returns the Intent for Wi-Fi network details settings.
      *
      * @param key The Wi-Fi entry key
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java
index 9ebdba3..d988111 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java
@@ -89,6 +89,10 @@
 
     @After
     public void tearDown() {
+        String[] entries = mImagesDir.list();
+        for (String entry : entries) {
+            new File(mImagesDir, entry).delete();
+        }
         mImagesDir.delete();
     }
 
@@ -150,23 +154,6 @@
     }
 
     @Test
-    public void takePhotoIsNotFollowedByCropIntentWhenCropNotSupported() throws IOException {
-        when(mMockAvatarUi.startSystemActivityForResult(any(), anyInt())).thenReturn(false);
-
-        File file = new File(mImagesDir, "file.txt");
-        saveBitmapToFile(file);
-
-        Intent intent = new Intent();
-        intent.setData(Uri.parse(
-                "content://com.android.settingslib.test/my_cache/multi_user/file.txt"));
-        mController.onActivityResult(
-                REQUEST_CODE_TAKE_PHOTO, Activity.RESULT_OK, intent);
-
-        verify(mMockAvatarUi, never()).startActivityForResult(any(), anyInt());
-        verify(mMockAvatarUi, never()).startSystemActivityForResult(any(), anyInt());
-    }
-
-    @Test
     public void choosePhotoIsFollowedByCrop() throws IOException {
         new File(mImagesDir, "file.txt").createNewFile();
 
@@ -250,7 +237,8 @@
     public void internalCropUsedIfNoSystemCropperFound() throws IOException {
         when(mMockAvatarUi.startSystemActivityForResult(any(), anyInt())).thenReturn(false);
 
-        new File(mImagesDir, "file.txt").createNewFile();
+        File file = new File(mImagesDir, "file.txt");
+        saveBitmapToFile(file);
 
         Intent intent = new Intent();
         intent.setData(Uri.parse(
@@ -258,10 +246,6 @@
         mController.onActivityResult(
                 REQUEST_CODE_TAKE_PHOTO, Activity.RESULT_OK, intent);
 
-        Intent startIntent = verifyStartSystemActivityForResult(
-                "com.android.camera.action.CROP", REQUEST_CODE_CROP_PHOTO);
-        assertThat(startIntent.getData()).isNotEqualTo(mTakePhotoUri);
-
         verify(mMockAvatarUi, timeout(TIMEOUT_MILLIS)).returnUriResult(mCropPhotoUri);
 
         InputStream imageStream = mContext.getContentResolver().openInputStream(mCropPhotoUri);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
index c122a37..179a498 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
@@ -31,6 +31,7 @@
 import android.content.Context;
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2Manager;
+import android.media.NearbyDevice;
 import android.os.Parcel;
 
 import com.android.settingslib.bluetooth.A2dpProfile;
@@ -200,6 +201,18 @@
     }
 
     @Test
+    public void compareTo_differentRange_sortWithRange() {
+        mBluetoothMediaDevice1.setRangeZone(NearbyDevice.RANGE_FAR);
+        mBluetoothMediaDevice2.setRangeZone(NearbyDevice.RANGE_CLOSE);
+        mMediaDevices.add(mBluetoothMediaDevice1);
+        mMediaDevices.add(mBluetoothMediaDevice2);
+
+        assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1);
+        Collections.sort(mMediaDevices, COMPARATOR);
+        assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice2);
+    }
+
+    @Test
     public void compareTo_carKit_info_carKitFirst() {
         when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass);
         mMediaDevices.add(mInfoMediaDevice1);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java
index e7b3fe9..6956105 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java
@@ -156,6 +156,27 @@
     }
 
     @Test
+    public void getWifiDialogIntent_returnsCorrectValues() {
+        String key = "test_key";
+
+        // Test that connectForCaller is true.
+        Intent intent = WifiUtils.getWifiDialogIntent(key, true /* connectForCaller */);
+
+        assertThat(intent.getAction()).isEqualTo(WifiUtils.ACTION_WIFI_DIALOG);
+        assertThat(intent.getStringExtra(WifiUtils.EXTRA_CHOSEN_WIFI_ENTRY_KEY)).isEqualTo(key);
+        assertThat(intent.getBooleanExtra(WifiUtils.EXTRA_CONNECT_FOR_CALLER, true))
+                .isEqualTo(true /* connectForCaller */);
+
+        // Test that connectForCaller is false.
+        intent = WifiUtils.getWifiDialogIntent(key, false /* connectForCaller */);
+
+        assertThat(intent.getAction()).isEqualTo(WifiUtils.ACTION_WIFI_DIALOG);
+        assertThat(intent.getStringExtra(WifiUtils.EXTRA_CHOSEN_WIFI_ENTRY_KEY)).isEqualTo(key);
+        assertThat(intent.getBooleanExtra(WifiUtils.EXTRA_CONNECT_FOR_CALLER, true))
+                .isEqualTo(false /* connectForCaller */);
+    }
+
+    @Test
     public void getWifiDetailsSettingsIntent_returnsCorrectValues() {
         final String key = "test_key";
 
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index fa3360c..cbd71c0 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -328,7 +328,5 @@
             return true;
         });
         VALIDATORS.put(Secure.ODI_CAPTIONS_VOLUME_UI_ENABLED, BOOLEAN_VALIDATOR);
-        VALIDATORS.put(Secure.FAST_PAIR_SCAN_ENABLED, BOOLEAN_VALIDATOR);
-
     }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 1c5bf81..3c29a80 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2252,12 +2252,14 @@
                 Settings.Secure.MULTI_PRESS_TIMEOUT,
                 SecureSettingsProto.MULTI_PRESS_TIMEOUT);
 
+        final long navBar = p.start(SecureSettingsProto.NAV_BAR);
         dumpSetting(s, p,
                 Settings.Secure.NAV_BAR_FORCE_VISIBLE,
                 SecureSettingsProto.NavBar.NAV_BAR_FORCE_VISIBLE);
         dumpSetting(s, p,
                 Settings.Secure.NAV_BAR_KIDS_MODE,
                 SecureSettingsProto.NavBar.NAV_BAR_KIDS_MODE);
+        p.end(navBar);
 
         dumpSetting(s, p,
                 Settings.Secure.NAVIGATION_MODE,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 3f4372b..057a9b0 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -271,6 +271,7 @@
                     Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
                     Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS,
                     Settings.Global.SMART_SUGGESTIONS_IN_NOTIFICATIONS_FLAGS,
+                    Settings.Global.STYLUS_HANDWRITING_ENABLED,
                     Settings.Global.ENABLE_ADB_INCREMENTAL_INSTALL_DEFAULT,
                     Settings.Global.ENABLE_MULTI_SLOT_TIMEOUT_MILLIS,
                     Settings.Global.ENHANCED_4G_MODE_ENABLED,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index c0e2b2e..e93371d 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -210,6 +210,7 @@
     <uses-permission android:name="android.permission.MANAGE_CREDENTIAL_MANAGEMENT_APP" />
     <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
     <uses-permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS" />
+    <uses-permission android:name="android.permission.PROVISION_DEMO_DEVICE" />
     <uses-permission android:name="android.permission.QUERY_ADMIN_POLICY" />
     <uses-permission android:name="android.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES" />
     <uses-permission android:name="android.permission.FORCE_DEVICE_POLICY_MANAGER_LOGS" />
@@ -535,10 +536,11 @@
     <uses-permission android:name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS" />
     <uses-permission android:name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" />
     <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
+    <uses-permission android:name="android.permission.MANAGE_WIFI_INTERFACES" />
     <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
     <!-- Permission needed for CTS test - ConcurrencyTest#testP2pExternalApprover
-         P2P external approver API sets require MANAGE_WIFI_AUTO_JOIN permission. -->
-    <uses-permission android:name="android.permission.MANAGE_WIFI_AUTO_JOIN" />
+         P2P external approver API sets require MANAGE_WIFI_NETWORK_SELECTION permission. -->
+    <uses-permission android:name="android.permission.MANAGE_WIFI_NETWORK_SELECTION" />
 
     <!-- Permission required for CTS tests to enable/disable rate limiting toasts. -->
     <uses-permission android:name="android.permission.MANAGE_TOAST_RATE_LIMITING" />
@@ -667,6 +669,9 @@
     <!-- Permission required for CTS test - CtsTelephonyTestCases -->
     <uses-permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE" />
 
+    <!-- Permission required for CTS test - CtsAppEnumerationTestCases -->
+    <uses-permission android:name="android.permission.MAKE_UID_VISIBLE" />
+
     <application android:label="@string/app_label"
                 android:theme="@android:style/Theme.DeviceDefault.DayNight"
                 android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 7f8b2f5..4b45cc3 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -314,6 +314,11 @@
     <!-- To change system captions state -->
     <uses-permission android:name="android.permission.SET_SYSTEM_AUDIO_CAPTION" />
 
+    <!-- Compat framework -->
+    <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
+    <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
+    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
+
     <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
@@ -794,7 +799,7 @@
                   android:noHistory="true"
                   android:showForAllUsers="true"
                   android:finishOnTaskLaunch="true"
-                  android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
+                  android:configChanges="screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden"
                   android:visibleToInstantApps="true">
         </activity>
 
@@ -805,7 +810,7 @@
                   android:showForAllUsers="true"
                   android:finishOnTaskLaunch="true"
                   android:launchMode="singleInstance"
-                  android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
+                  android:configChanges="screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden"
                   android:visibleToInstantApps="true">
         </activity>
 
diff --git a/packages/SystemUI/animation/res/values/ids.xml b/packages/SystemUI/animation/res/values/ids.xml
index ef60a24..4e9a4be 100644
--- a/packages/SystemUI/animation/res/values/ids.xml
+++ b/packages/SystemUI/animation/res/values/ids.xml
@@ -15,5 +15,14 @@
      limitations under the License.
 -->
 <resources>
+    <!-- DialogLaunchAnimator -->
     <item type="id" name="launch_animation_running"/>
+
+    <!-- ViewBoundsAnimator -->
+    <item type="id" name="tag_animator"/>
+    <item type="id" name="tag_layout_listener"/>
+    <item type="id" name="tag_override_bottom"/>
+    <item type="id" name="tag_override_left"/>
+    <item type="id" name="tag_override_right"/>
+    <item type="id" name="tag_override_top"/>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index 1835842..3f7e0f0 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -33,6 +33,7 @@
 import android.view.ViewGroupOverlay
 import android.widget.FrameLayout
 import com.android.internal.jank.InteractionJankMonitor
+import java.util.LinkedList
 import kotlin.math.min
 
 private const val TAG = "GhostedViewLaunchAnimatorController"
@@ -81,21 +82,51 @@
      * [backgroundView].
      */
     private var backgroundDrawable: WrappedDrawable? = null
-    private val backgroundInsets by lazy { getBackground()?.opticalInsets ?: Insets.NONE }
+    private val backgroundInsets by lazy { background?.opticalInsets ?: Insets.NONE }
     private var startBackgroundAlpha: Int = 0xFF
 
     private val ghostedViewLocation = IntArray(2)
     private val ghostedViewState = LaunchAnimator.State()
 
     /**
-     * Return the background of the [ghostedView]. This background will be used to draw the
-     * background of the background view that is expanding up to the final animation position. This
-     * is called at the start of the animation.
+     * The background of the [ghostedView]. This background will be used to draw the background of
+     * the background view that is expanding up to the final animation position.
      *
      * Note that during the animation, the alpha value value of this background will be set to 0,
      * then set back to its initial value at the end of the animation.
      */
-    protected open fun getBackground(): Drawable? = ghostedView.background
+    private val background: Drawable?
+
+    init {
+        /** Find the first view with a background in [view] and its children. */
+        fun findBackground(view: View): Drawable? {
+            if (view.background != null) {
+                return view.background
+            }
+
+            // Perform a BFS to find the largest View with background.
+            val views = LinkedList<View>().apply {
+                add(view)
+            }
+
+            while (views.isNotEmpty()) {
+                val v = views.removeFirst()
+                if (v.background != null) {
+                    return v.background
+                }
+
+                if (v is ViewGroup) {
+                    for (i in 0 until v.childCount) {
+                        views.add(v.getChildAt(i))
+                    }
+                }
+            }
+
+            return null
+        }
+
+        background = findBackground(ghostedView)
+    }
 
     /**
      * Set the corner radius of [background]. The background is the one that was returned by
@@ -113,7 +144,7 @@
 
     /** Return the current top corner radius of the background. */
     protected open fun getCurrentTopCornerRadius(): Float {
-        val drawable = getBackground() ?: return 0f
+        val drawable = background ?: return 0f
         val gradient = findGradientDrawable(drawable) ?: return 0f
 
         // TODO(b/184121838): Support more than symmetric top & bottom radius.
@@ -122,7 +153,7 @@
 
     /** Return the current bottom corner radius of the background. */
     protected open fun getCurrentBottomCornerRadius(): Float {
-        val drawable = getBackground() ?: return 0f
+        val drawable = background ?: return 0f
         val gradient = findGradientDrawable(drawable) ?: return 0f
 
         // TODO(b/184121838): Support more than symmetric top & bottom radius.
@@ -162,9 +193,8 @@
 
         // We wrap the ghosted view background and use it to draw the expandable background. Its
         // alpha will be set to 0 as soon as we start drawing the expanding background.
-        val drawable = getBackground()
-        startBackgroundAlpha = drawable?.alpha ?: 0xFF
-        backgroundDrawable = WrappedDrawable(drawable)
+        startBackgroundAlpha = background?.alpha ?: 0xFF
+        backgroundDrawable = WrappedDrawable(background)
         backgroundView?.background = backgroundDrawable
 
         // Create a ghost of the view that will be moving and fading out. This allows to fade out
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewBoundAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewBoundAnimator.kt
new file mode 100644
index 0000000..5593fdf
--- /dev/null
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewBoundAnimator.kt
@@ -0,0 +1,328 @@
+/*
+ * 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.animation
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ObjectAnimator
+import android.animation.PropertyValuesHolder
+import android.util.IntProperty
+import android.view.View
+import android.view.ViewGroup
+import android.view.animation.Interpolator
+
+/**
+ * A class that allows changes in bounds within a view hierarchy to animate seamlessly between the
+ * start and end state.
+ */
+class ViewBoundAnimator {
+    // TODO(b/221418522): make this private once it can't be passed as an arg anymore.
+    enum class Bound(val label: String, val overrideTag: Int) {
+        LEFT("left", R.id.tag_override_left) {
+            override fun setValue(view: View, value: Int) {
+                view.left = value
+            }
+
+            override fun getValue(view: View): Int {
+                return view.left
+            }
+        },
+        TOP("top", R.id.tag_override_top) {
+            override fun setValue(view: View, value: Int) {
+                view.top = value
+            }
+
+            override fun getValue(view: View): Int {
+                return view.top
+            }
+        },
+        RIGHT("right", R.id.tag_override_right) {
+            override fun setValue(view: View, value: Int) {
+                view.right = value
+            }
+
+            override fun getValue(view: View): Int {
+                return view.right
+            }
+        },
+        BOTTOM("bottom", R.id.tag_override_bottom) {
+            override fun setValue(view: View, value: Int) {
+                view.bottom = value
+            }
+
+            override fun getValue(view: View): Int {
+                return view.bottom
+            }
+        };
+
+        abstract fun setValue(view: View, value: Int)
+        abstract fun getValue(view: View): Int
+    }
+
+    companion object {
+        /** Default values for the animation. These can all be overridden at call time. */
+        private const val DEFAULT_DURATION = 500L
+        private val DEFAULT_INTERPOLATOR = Interpolators.EMPHASIZED
+        private val DEFAULT_BOUNDS = setOf(Bound.LEFT, Bound.TOP, Bound.RIGHT, Bound.BOTTOM)
+
+        /** The properties used to animate the view bounds. */
+        private val PROPERTIES = mapOf(
+            Bound.LEFT to createViewProperty(Bound.LEFT),
+            Bound.TOP to createViewProperty(Bound.TOP),
+            Bound.RIGHT to createViewProperty(Bound.RIGHT),
+            Bound.BOTTOM to createViewProperty(Bound.BOTTOM)
+        )
+
+        private fun createViewProperty(bound: Bound): IntProperty<View> {
+            return object : IntProperty<View>(bound.label) {
+                override fun setValue(view: View, value: Int) {
+                    setBound(view, bound, value)
+                }
+
+                override fun get(view: View): Int {
+                    return getBound(view, bound) ?: bound.getValue(view)
+                }
+            }
+        }
+
+        /**
+         * Instruct the animator to watch for changes to the layout of [rootView] and its children
+         * and animate them. The animation can be limited to a subset of [bounds]. It uses the
+         * given [interpolator] and [duration].
+         *
+         * If a new layout change happens while an animation is already in progress, the animation
+         * is updated to continue from the current values to the new end state.
+         *
+         * The animator continues to respond to layout changes until [stopAnimating] is called.
+         *
+         * Successive calls to this method override the previous settings ([interpolator] and
+         * [duration]). The changes take effect on the next animation.
+         *
+         * TODO(b/221418522): remove the ability to select which bounds to animate and always
+         * animate all of them.
+         */
+        @JvmOverloads
+        fun animate(
+            rootView: View,
+            bounds: Set<Bound> = DEFAULT_BOUNDS,
+            interpolator: Interpolator = DEFAULT_INTERPOLATOR,
+            duration: Long = DEFAULT_DURATION
+        ) {
+            animate(rootView, bounds, interpolator, duration, false /* ephemeral */)
+        }
+
+        /**
+         * Like [animate], but only takes effect on the next layout update, then unregisters itself
+         * once the first animation is complete.
+         *
+         * TODO(b/221418522): remove the ability to select which bounds to animate and always
+         * animate all of them.
+         */
+        @JvmOverloads
+        fun animateNextUpdate(
+            rootView: View,
+            bounds: Set<Bound> = DEFAULT_BOUNDS,
+            interpolator: Interpolator = DEFAULT_INTERPOLATOR,
+            duration: Long = DEFAULT_DURATION
+        ) {
+            animate(rootView, bounds, interpolator, duration, true /* ephemeral */)
+        }
+
+        private fun animate(
+            rootView: View,
+            bounds: Set<Bound>,
+            interpolator: Interpolator,
+            duration: Long,
+            ephemeral: Boolean
+        ) {
+            val listener = createListener(bounds, interpolator, duration, ephemeral)
+            recursivelyAddListener(rootView, listener)
+        }
+
+        /**
+         * Instruct the animator to stop watching for changes to the layout of [rootView] and its
+         * children.
+         *
+         * Any animations already in progress continue until their natural conclusion.
+         */
+        fun stopAnimating(rootView: View) {
+            val listener = rootView.getTag(R.id.tag_layout_listener)
+            if (listener != null && listener is View.OnLayoutChangeListener) {
+                rootView.setTag(R.id.tag_layout_listener, null /* tag */)
+                rootView.removeOnLayoutChangeListener(listener)
+            }
+
+            if (rootView is ViewGroup) {
+                for (i in 0 until rootView.childCount) {
+                    stopAnimating(rootView.getChildAt(i))
+                }
+            }
+        }
+
+        private fun createListener(
+            bounds: Set<Bound>,
+            interpolator: Interpolator,
+            duration: Long,
+            ephemeral: Boolean
+        ): View.OnLayoutChangeListener {
+            return object : View.OnLayoutChangeListener {
+                override fun onLayoutChange(
+                    view: View?,
+                    left: Int,
+                    top: Int,
+                    right: Int,
+                    bottom: Int,
+                    oldLeft: Int,
+                    oldTop: Int,
+                    oldRight: Int,
+                    oldBottom: Int
+                ) {
+                    if (view == null) return
+
+                    val startLeft = getBound(view, Bound.LEFT) ?: oldLeft
+                    val startTop = getBound(view, Bound.TOP) ?: oldTop
+                    val startRight = getBound(view, Bound.RIGHT) ?: oldRight
+                    val startBottom = getBound(view, Bound.BOTTOM) ?: oldBottom
+
+                    (view.getTag(R.id.tag_animator) as? ObjectAnimator)?.cancel()
+
+                    if (view.visibility == View.GONE || view.visibility == View.INVISIBLE) {
+                        setBound(view, Bound.LEFT, left)
+                        setBound(view, Bound.TOP, top)
+                        setBound(view, Bound.RIGHT, right)
+                        setBound(view, Bound.BOTTOM, bottom)
+                        return
+                    }
+
+                    val startValues = mapOf(
+                        Bound.LEFT to startLeft,
+                        Bound.TOP to startTop,
+                        Bound.RIGHT to startRight,
+                        Bound.BOTTOM to startBottom
+                    )
+                    val endValues = mapOf(
+                        Bound.LEFT to left,
+                        Bound.TOP to top,
+                        Bound.RIGHT to right,
+                        Bound.BOTTOM to bottom
+                    )
+
+                    val boundsToAnimate = bounds.toMutableSet()
+                    if (left == startLeft) boundsToAnimate.remove(Bound.LEFT)
+                    if (top == startTop) boundsToAnimate.remove(Bound.TOP)
+                    if (right == startRight) boundsToAnimate.remove(Bound.RIGHT)
+                    if (bottom == startBottom) boundsToAnimate.remove(Bound.BOTTOM)
+
+                    if (boundsToAnimate.isNotEmpty()) {
+                        startAnimation(
+                            view,
+                            boundsToAnimate,
+                            startValues,
+                            endValues,
+                            interpolator,
+                            duration,
+                            ephemeral
+                        )
+                    }
+                }
+            }
+        }
+
+        private fun recursivelyAddListener(view: View, listener: View.OnLayoutChangeListener) {
+            // Make sure that only one listener is active at a time.
+            val oldListener = view.getTag(R.id.tag_layout_listener)
+            if (oldListener != null && oldListener is View.OnLayoutChangeListener) {
+                view.removeOnLayoutChangeListener(oldListener)
+            }
+
+            view.addOnLayoutChangeListener(listener)
+            view.setTag(R.id.tag_layout_listener, listener)
+            if (view is ViewGroup) {
+                for (i in 0 until view.childCount) {
+                    recursivelyAddListener(view.getChildAt(i), listener)
+                }
+            }
+        }
+
+        private fun getBound(view: View, bound: Bound): Int? {
+            return view.getTag(bound.overrideTag) as? Int
+        }
+
+        private fun setBound(view: View, bound: Bound, value: Int) {
+            view.setTag(bound.overrideTag, value)
+            bound.setValue(view, value)
+        }
+
+        /**
+         * Initiates the animation of a single bound by creating the animator, registering it with
+         * the [view], and starting it. If [ephemeral], the layout change listener is unregistered
+         * at the end of the animation, so no more animations happen.
+         */
+        private fun startAnimation(
+            view: View,
+            bounds: Set<Bound>,
+            startValues: Map<Bound, Int>,
+            endValues: Map<Bound, Int>,
+            interpolator: Interpolator,
+            duration: Long,
+            ephemeral: Boolean
+        ) {
+            val propertyValuesHolders = buildList {
+                bounds.forEach { bound ->
+                    add(
+                        PropertyValuesHolder.ofInt(
+                            PROPERTIES[bound],
+                            startValues.getValue(bound),
+                            endValues.getValue(bound)
+                        )
+                    )
+                }
+            }.toTypedArray()
+
+            val animator = ObjectAnimator.ofPropertyValuesHolder(view, *propertyValuesHolders)
+            animator.interpolator = interpolator
+            animator.duration = duration
+            animator.addListener(object : AnimatorListenerAdapter() {
+                var cancelled = false
+
+                override fun onAnimationEnd(animation: Animator) {
+                    view.setTag(R.id.tag_animator, null /* tag */)
+                    bounds.forEach { view.setTag(it.overrideTag, null /* tag */) }
+
+                    // When an animation is cancelled, a new one might be taking over. We shouldn't
+                    // unregister the listener yet.
+                    if (ephemeral && !cancelled) {
+                        val listener = view.getTag(R.id.tag_layout_listener)
+                        if (listener != null && listener is View.OnLayoutChangeListener) {
+                            view.setTag(R.id.tag_layout_listener, null /* tag */)
+                            view.removeOnLayoutChangeListener(listener)
+                        }
+                    }
+                }
+
+                override fun onAnimationCancel(animation: Animator?) {
+                    cancelled = true
+                }
+            })
+
+            bounds.forEach { bound -> setBound(view, bound, startValues.getValue(bound)) }
+
+            view.setTag(R.id.tag_animator, animator)
+            animator.start()
+        }
+    }
+}
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index c97ebe8..e74b6c7 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -41,6 +41,14 @@
 -keep,allowoptimization,allowaccessmodification class com.android.systemui.dagger.Dagger** { !synthetic *; }
 -keep,allowoptimization,allowaccessmodification class com.android.systemui.tv.Dagger** { !synthetic *; }
 
+# Prevent optimization or access modification of any referenced code that may
+# conflict with code in the bootclasspath.
+# TODO(b/222468116): Resolve such collisions in the build system.
+-keepnames class android.**.nano.** { *; }
+-keepnames class com.android.**.nano.** { *; }
+-keepnames class com.android.internal.protolog.** { *; }
+-keepnames class android.hardware.common.** { *; }
+
 # Allows proguard to make private and protected methods and fields public as
 # part of optimization. This lets proguard inline trivial getter/setter methods.
 -allowaccessmodification
diff --git a/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
index b96c07e..0764273 100644
--- a/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
+++ b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
@@ -15,10 +15,11 @@
   ~ limitations under the License.
   -->
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:color="?attr/wallpaperTextColorSecondary">
     <item android:id="@android:id/background">
         <shape android:shape="rectangle">
-            <solid android:color="?android:attr/colorAccent"/>
+            <solid android:color="?androidprv:attr/colorAccentTertiary"/>
             <corners android:radius="24dp"/>
         </shape>
     </item>
diff --git a/packages/SystemUI/res/layout/communal_host_view.xml b/packages/SystemUI/res-keyguard/drawable/media_squiggly_progress.xml
similarity index 62%
rename from packages/SystemUI/res/layout/communal_host_view.xml
rename to packages/SystemUI/res-keyguard/drawable/media_squiggly_progress.xml
index cd9c260..9e61236 100644
--- a/packages/SystemUI/res/layout/communal_host_view.xml
+++ b/packages/SystemUI/res-keyguard/drawable/media_squiggly_progress.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2021 The Android Open Source Project
+  ~ 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.
@@ -14,10 +14,4 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-
-<!-- This is a view that shows general status information in Keyguard. -->
-<com.android.systemui.communal.CommunalHostView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/communal_host"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"/>
\ No newline at end of file
+<com.android.systemui.media.SquigglyProgress />
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 6375698..625ffd3 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -17,13 +17,14 @@
 */
 -->
 
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <!-- Keyguard PIN pad styles -->
     <style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView">
         <item name="android:textSize">@dimen/kg_status_line_font_size</item>
     </style>
     <style name="Keyguard.TextView.EmergencyButton" parent="Theme.SystemUI">
-        <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+        <item name="android:textColor">?androidprv:attr/textColorOnAccent</item>
         <item name="android:textSize">14dp</item>
         <item name="android:background">@drawable/kg_emergency_button_background</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
diff --git a/packages/SystemUI/res/color/kg_user_avatar_frame.xml b/packages/SystemUI/res/color/kg_user_avatar_frame.xml
index 174981e..a143194 100644
--- a/packages/SystemUI/res/color/kg_user_avatar_frame.xml
+++ b/packages/SystemUI/res/color/kg_user_avatar_frame.xml
@@ -18,6 +18,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:state_activated="true"
-        android:color="@color/kg_user_switcher_avatar_background" />
-    <item android:color="@color/kg_user_switcher_avatar_background" />
+        android:color="@color/user_avatar_color_bg" />
+    <item android:color="@color/user_avatar_color_bg" />
 </selector>
diff --git a/packages/SystemUI/res/drawable/user_switcher_icon_large.xml b/packages/SystemUI/res/drawable/user_switcher_icon_large.xml
index b78b221..1ed7553 100644
--- a/packages/SystemUI/res/drawable/user_switcher_icon_large.xml
+++ b/packages/SystemUI/res/drawable/user_switcher_icon_large.xml
@@ -36,7 +36,7 @@
   </item>
   <!-- Where the user drawable/bitmap will be placed -->
   <item
-      android:drawable="@drawable/kg_bg_avatar"
+      android:drawable="@drawable/user_avatar_bg"
       android:width="@dimen/bouncer_user_switcher_icon_size"
       android:height="@dimen/bouncer_user_switcher_icon_size"
       android:top="@dimen/user_switcher_icon_large_margin"
diff --git a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
index 8f6753a..da4088f 100644
--- a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
+++ b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
@@ -36,6 +36,7 @@
         android:tooltipText="@*android:string/share"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintTop_toTopOf="@+id/copy_button"
+        android:tint="?android:attr/textColorPrimary"
         android:src="@drawable/ic_screenshot_share" />
 
     <ScrollView
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index c58c001..2782300 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -26,7 +26,7 @@
         android:layout_width="match_parent"
         android:layout_gravity="bottom"
         android:src="@drawable/overlay_actions_background_protection"/>
-    <com.android.systemui.clipboardoverlay.DraggableConstraintLayout
+    <com.android.systemui.screenshot.DraggableConstraintLayout
         android:id="@+id/clipboard_ui"
         android:theme="@style/FloatingOverlay"
         android:layout_width="match_parent"
@@ -146,5 +146,5 @@
                 android:layout_margin="@dimen/overlay_dismiss_button_margin"
                 android:src="@drawable/overlay_cancel"/>
         </FrameLayout>
-    </com.android.systemui.clipboardoverlay.DraggableConstraintLayout>
+    </com.android.systemui.screenshot.DraggableConstraintLayout>
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml b/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml
index 91d81a2..cb63300 100644
--- a/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml
@@ -19,6 +19,7 @@
     android:id="@+id/date_view"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
+    android:paddingHorizontal="@dimen/dream_overlay_complication_shadow_padding"
     android:gravity="center_horizontal"
     android:textColor="@android:color/white"
     android:shadowColor="@color/keyguard_shadow_color"
diff --git a/packages/SystemUI/res/layout/dream_overlay_complication_weather.xml b/packages/SystemUI/res/layout/dream_overlay_complication_weather.xml
index 3900ea5..76fe58c 100644
--- a/packages/SystemUI/res/layout/dream_overlay_complication_weather.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_complication_weather.xml
@@ -19,6 +19,7 @@
     android:id="@+id/weather_view"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
+    android:paddingHorizontal="@dimen/dream_overlay_complication_shadow_padding"
     android:textColor="@android:color/white"
     android:shadowColor="@color/keyguard_shadow_color"
     android:shadowRadius="?attr/shadowRadius"
diff --git a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
index 1cbc3c2..d0f4903 100644
--- a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
@@ -42,17 +42,6 @@
         app:layout_constraintEnd_toEndOf="parent">
 
         <com.android.systemui.statusbar.AlphaOptimizedImageView
-            android:id="@+id/dream_overlay_assistant_guest_mode_enabled"
-            android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
-            android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
-            android:src="@drawable/ic_account_circle"
-            android:tint="@android:color/white"
-            android:visibility="gone"
-            android:contentDescription=
-                "@string/dream_overlay_status_bar_assistant_guest_mode_enabled" />
-
-        <com.android.systemui.statusbar.AlphaOptimizedImageView
             android:id="@+id/dream_overlay_alarm_set"
             android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
             android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index 51211a0..05343e7 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -129,7 +129,7 @@
             style="@style/Widget.Dialog.Button.BorderButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="@string/keyboard_key_media_stop"
+            android:text="@string/media_output_dialog_button_stop_casting"
             android:visibility="gone"/>
 
         <Space
diff --git a/packages/SystemUI/res/layout/media_output_list_item.xml b/packages/SystemUI/res/layout/media_output_list_item.xml
index 806804f..eeb37c7 100644
--- a/packages/SystemUI/res/layout/media_output_list_item.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item.xml
@@ -62,20 +62,22 @@
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical|start"
             android:layout_marginStart="56dp"
+            android:layout_marginEnd="56dp"
             android:ellipsize="end"
             android:maxLines="1"
             android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
             android:textSize="16sp"/>
 
-        <RelativeLayout
+        <LinearLayout
             android:id="@+id/two_line_layout"
+            android:orientation="vertical"
             android:layout_width="wrap_content"
             android:layout_gravity="center_vertical|start"
             android:layout_height="48dp"
+            android:layout_marginEnd="56dp"
             android:layout_marginStart="56dp">
             <TextView
                 android:id="@+id/two_line_title"
-                android:gravity="center_vertical"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:ellipsize="end"
@@ -85,18 +87,15 @@
                 android:textSize="16sp"/>
             <TextView
                 android:id="@+id/subtitle"
-                android:layout_gravity="center_vertical"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="4dp"
-                android:layout_alignParentBottom="true"
                 android:ellipsize="end"
                 android:maxLines="1"
                 android:textColor="@color/media_dialog_inactive_item_main_content"
                 android:textSize="14sp"
                 android:fontFamily="@*android:string/config_bodyFontFamily"
                 android:visibility="gone"/>
-        </RelativeLayout>
+        </LinearLayout>
 
         <ProgressBar
             android:id="@+id/volume_indeterminate_progress"
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 978998d..f030f31 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -44,6 +44,7 @@
         android:background="@drawable/qs_media_scrim"
         />
 
+    <!-- Guideline for output switcher -->
     <androidx.constraintlayout.widget.Guideline
         android:id="@+id/center_vertical_guideline"
         android:layout_width="wrap_content"
@@ -51,6 +52,14 @@
         android:orientation="vertical"
         app:layout_constraintGuide_percent="0.6" />
 
+    <!-- Guideline for action buttons (collapsed view only) -->
+    <androidx.constraintlayout.widget.Guideline
+        android:id="@+id/action_button_guideline"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:orientation="vertical"
+        app:layout_constraintGuide_end="@dimen/qs_media_session_collapsed_guideline" />
+
     <!-- App icon -->
     <com.android.internal.widget.CachingIconView
         android:id="@+id/icon"
@@ -118,15 +127,7 @@
         android:singleLine="true"
         android:textSize="16sp"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="20dp"
-        android:layout_marginStart="@dimen/qs_media_padding"
-        android:layout_marginEnd="@dimen/qs_media_padding"
-        app:layout_constrainedWidth="true"
-        app:layout_constraintTop_toBottomOf="@id/icon"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
-        app:layout_constraintHorizontal_bias="0" />
+        android:layout_height="wrap_content" />
 
     <!-- Artist name -->
     <TextView
@@ -136,15 +137,7 @@
         style="@style/MediaPlayer.Subtitle"
         android:textSize="14sp"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginEnd="@dimen/qs_media_padding"
-        app:layout_constrainedWidth="true"
-        android:layout_marginTop="1dp"
-        app:layout_constraintTop_toBottomOf="@id/header_title"
-        app:layout_constraintStart_toStartOf="@id/header_title"
-        app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
-        app:layout_constraintBottom_toBottomOf="@id/actionPlayPause"
-        app:layout_constraintHorizontal_bias="0" />
+        android:layout_height="wrap_content" />
 
     <ImageButton
         android:id="@+id/actionPlayPause"
@@ -153,9 +146,33 @@
         android:layout_height="48dp"
         android:layout_marginStart="@dimen/qs_media_padding"
         android:layout_marginEnd="@dimen/qs_media_padding"
-        android:layout_marginTop="0dp"
-        android:layout_marginBottom="0dp" />
+         />
 
+    <!-- See comment in media_session_collapsed.xml for how these barriers are used -->
+    <androidx.constraintlayout.widget.Barrier
+        android:id="@+id/media_action_barrier"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:orientation="vertical"
+        app:layout_constraintTop_toBottomOf="@id/header_title"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:barrierDirection="start"
+        app:constraint_referenced_ids="actionPrev,media_progress_bar,actionNext,action0,action1,action2,action3,action4"
+        />
+    <androidx.constraintlayout.widget.Barrier
+        android:id="@+id/media_action_barrier_end"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:orientation="vertical"
+        app:layout_constraintTop_toBottomOf="@id/media_seamless"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:barrierDirection="end"
+        app:constraint_referenced_ids="actionPrev,media_progress_bar,actionNext,action0,action1,action2,action3,action4"
+        app:layout_constraintStart_toStartOf="parent"
+        />
+
+    <!-- Button visibility will be controlled in code -->
     <ImageButton
         android:id="@+id/actionPrev"
         style="@style/MediaPlayer.SessionAction"
@@ -163,10 +180,9 @@
         android:layout_height="48dp"
         android:layout_marginStart="4dp"
         android:layout_marginEnd="0dp"
-        android:layout_marginBottom="0dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
         android:layout_marginTop="0dp"
-        app:layout_constraintHorizontal_bias="1"
-        app:layout_constraintHorizontal_chainStyle="packed" />
+        />
 
     <!-- Seek Bar -->
     <!-- As per Material Design on Bidirectionality, this is forced to LTR in code -->
@@ -174,12 +190,12 @@
         android:id="@+id/media_progress_bar"
         style="@style/MediaPlayer.ProgressBar"
         android:layout_width="0dp"
-        android:layout_height="wrap_content"
+        android:layout_height="48dp"
         android:paddingTop="@dimen/qs_media_session_enabled_seekbar_vertical_padding"
         android:paddingBottom="12dp"
         android:maxHeight="@dimen/qs_media_enabled_seekbar_height"
         android:splitTrack="false"
-        android:layout_marginBottom="0dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
         android:layout_marginTop="0dp"
         android:layout_marginStart="0dp"
         android:layout_marginEnd="0dp" />
@@ -191,29 +207,58 @@
         android:layout_height="48dp"
         android:layout_marginStart="0dp"
         android:layout_marginEnd="@dimen/qs_media_action_spacing"
-        android:layout_marginBottom="0dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
         android:layout_marginTop="0dp" />
 
     <ImageButton
-        android:id="@+id/actionStart"
+        android:id="@+id/action0"
         style="@style/MediaPlayer.SessionAction"
         android:layout_width="48dp"
         android:layout_height="48dp"
         android:layout_marginStart="@dimen/qs_media_action_spacing"
         android:layout_marginEnd="@dimen/qs_media_action_spacing"
-        android:layout_marginBottom="0dp"
-        android:layout_marginTop="0dp" />
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        android:layout_marginTop="0dp"/>
 
     <ImageButton
-        android:id="@+id/actionEnd"
+        android:id="@+id/action1"
         style="@style/MediaPlayer.SessionAction"
         android:layout_width="48dp"
         android:layout_height="48dp"
         android:layout_marginStart="@dimen/qs_media_action_spacing"
         android:layout_marginEnd="4dp"
-        android:layout_marginBottom="0dp"
-        android:layout_marginTop="0dp"
-        app:layout_constraintHorizontal_chainStyle="packed" />
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        android:layout_marginTop="0dp" />
+
+    <ImageButton
+        android:id="@+id/action2"
+        style="@style/MediaPlayer.SessionAction"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginStart="@dimen/qs_media_action_spacing"
+        android:layout_marginEnd="4dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        android:layout_marginTop="0dp" />
+
+    <ImageButton
+        android:id="@+id/action3"
+        style="@style/MediaPlayer.SessionAction"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginStart="@dimen/qs_media_action_spacing"
+        android:layout_marginEnd="4dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        android:layout_marginTop="0dp" />
+
+    <ImageButton
+        android:id="@+id/action4"
+        style="@style/MediaPlayer.SessionAction"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginStart="@dimen/qs_media_action_spacing"
+        android:layout_marginEnd="4dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        android:layout_marginTop="0dp" />
 
     <!-- Long press menu -->
     <TextView
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
index 8122776..ad2bc79 100644
--- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
@@ -22,7 +22,10 @@
     android:layout_height="match_parent"
     android:layout_width="wrap_content"
     android:layout_gravity="center_vertical|end"
-    android:focusable="true" >
+    android:focusable="true"
+    android:clipChildren="false"
+    android:clipToPadding="false"
+    >
 
         <LinearLayout
             android:id="@+id/icons_container"
@@ -34,5 +37,7 @@
             android:layout_gravity="center"
             android:minWidth="@dimen/ongoing_appops_chip_min_width"
             android:maxWidth="@dimen/ongoing_appops_chip_max_width"
+            android:clipChildren="false"
+            android:clipToPadding="false"
             />
 </com.android.systemui.privacy.OngoingPrivacyChip>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/screenshot_static.xml b/packages/SystemUI/res/layout/screenshot_static.xml
index 813bb60..8de8084 100644
--- a/packages/SystemUI/res/layout/screenshot_static.xml
+++ b/packages/SystemUI/res/layout/screenshot_static.xml
@@ -14,25 +14,25 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<androidx.constraintlayout.widget.ConstraintLayout
+<com.android.systemui.screenshot.DraggableConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
     <ImageView
-        android:id="@+id/screenshot_actions_container_background"
+        android:id="@+id/actions_container_background"
         android:visibility="gone"
         android:layout_height="0dp"
         android:layout_width="0dp"
         android:elevation="1dp"
         android:background="@drawable/action_chip_container_background"
         android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
-        app:layout_constraintBottom_toBottomOf="@+id/screenshot_actions_container"
+        app:layout_constraintBottom_toBottomOf="@+id/actions_container"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="@+id/screenshot_actions_container"
-        app:layout_constraintEnd_toEndOf="@+id/screenshot_actions_container"/>
+        app:layout_constraintTop_toTopOf="@+id/actions_container"
+        app:layout_constraintEnd_toEndOf="@+id/actions_container"/>
     <HorizontalScrollView
-        android:id="@+id/screenshot_actions_container"
+        android:id="@+id/actions_container"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_marginEnd="@dimen/overlay_action_container_margin_horizontal"
@@ -130,4 +130,4 @@
         app:layout_constraintStart_toStartOf="@id/screenshot_preview"
         app:layout_constraintTop_toTopOf="@id/screenshot_preview"
         android:elevation="@dimen/overlay_preview_elevation"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
+</com.android.systemui.screenshot.DraggableConstraintLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index e4706e2..ef030ba 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -26,9 +26,6 @@
     android:layout_height="match_parent"
     android:background="@android:color/transparent">
 
-    <include layout="@layout/communal_host_view"
-             android:visibility="gone"/>
-
     <ViewStub
         android:id="@+id/keyguard_qs_user_switch_stub"
         android:layout="@layout/keyguard_qs_user_switch"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_section_header.xml b/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
index e33f186..c4d8d55 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
@@ -21,8 +21,6 @@
     android:layout_height="@dimen/notification_section_header_height"
     android:paddingStart="4dp"
     android:paddingEnd="4dp"
-    android:focusable="true"
-    android:clickable="true"
     >
 
     <LinearLayout
@@ -46,6 +44,7 @@
                 android:id="@+id/header_label"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:focusable="true"
                 android:forceHasOverlappingRendering="false"
                 android:text="@string/notification_section_header_gentle"
             />
@@ -57,6 +56,7 @@
             android:layout_height="48dp"
             android:src="@drawable/status_bar_notification_section_header_clear_btn"
             android:contentDescription="@string/accessibility_notification_section_header_gentle_clear_all"
+            android:focusable="true"
             android:scaleType="center"
             android:tintMode="src_in"
             android:visibility="gone"
diff --git a/packages/SystemUI/res/layout/system_event_animation_window.xml b/packages/SystemUI/res/layout/system_event_animation_window.xml
index c92dec9..e6868b3 100644
--- a/packages/SystemUI/res/layout/system_event_animation_window.xml
+++ b/packages/SystemUI/res/layout/system_event_animation_window.xml
@@ -19,17 +19,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_gravity="center_vertical|end"
-    android:paddingTop="@dimen/status_bar_padding_top"
-    android:paddingEnd="8dp"
+    android:clipChildren="false"
+    android:clipToPadding="false"
     >
-
-    <ImageView
-        android:id="@+id/dot_view"
-        android:layout_width="10dp"
-        android:layout_height="10dp"
-        android:layout_gravity="center_vertical|end"
-        android:src="@drawable/system_animation_ongoing_dot"
-        android:visibility="invisible"
-        />
-
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 42955caf..c0fdf68 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -20,7 +20,12 @@
 <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">"Stelsel-UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Battery kan binnekort afloop"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> oor"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Kan nie deur USB laai nie"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Gebruik die laaier wat jy saam met jou toestel gekry het"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gesig is gestaaf"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bevestig"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tik op Bevestig om te voltooi"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Gestaaf"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gebruik PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gebruik patroon"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Maak toe"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"volkome stilte"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"net wekkers"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Moenie Steur Nie."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth aan."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Wekker gestel vir <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Nageregkas"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Sluimerskerm"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Moenie Steur Nie"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Geen saamgebinde toestelle beskikbaar nie"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterykrag"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Kennisgewings"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Gesprekke"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vee alle stil kennisgewings uit"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Kennisgewings onderbreek deur Moenie Steur Nie"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Begin nou"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Geen kennisgewings nie"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Hierdie toestel word deur jou ouer bestuur"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Laer gegradeer"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Word aan die bokant van gesprekskennisgewings en as \'n profielfoto op sluitskerm gewys"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Word aan die bokant van gesprekskennisgewings en as \'n profielfoto op sluitskerm gewys, verskyn as \'n borrel"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Word aan die bokant van gesprekskennisgewings en as \'n profielfoto op sluitskerm gewys, onderbreek Moenie Steur Nie"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Word aan die bokant van gesprekskennisgewings en as \'n profielfoto op sluitskerm gewys, verskyn as \'n borrel, onderbreek Moenie Steur Nie"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> steun nie gesprekskenmerke nie"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Hierdie kennisgewings kan nie gewysig word nie."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiek"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Moenie Steur Nie"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volumeknoppieskortpad"</string>
     <string name="battery" msgid="769686279459897127">"Battery"</string>
     <string name="headset" msgid="4485892374984466437">"Kopstuk"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is af"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is af"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Moenie Steur Nie is af"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\'n Outomatiese reël (<xliff:g id="ID_1">%s</xliff:g>) het Moenie Steur Nie aangeskakel."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\'n Program (<xliff:g id="ID_1">%s</xliff:g>) het Moenie Steur Nie aangeskakel."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\'n Outomatiese reël of program het Moenie Steur Nie aangeskakel."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Programme wat op die agtergrond loop"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tik vir besonderhede oor battery- en datagebruik"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Skakel mobiele data af?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(werk)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Oproep"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(deur <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ligging"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoon"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ontkoppel)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan nie wissel nie. Tik om weer te probeer."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bind nuwe toestel saam"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Maak die program oop om hierdie sessie uit te saai."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende program"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Bounommer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Bounommer is na knipbord gekopieer."</string>
     <string name="basic_status" msgid="2315371112182658176">"Maak gesprek oop"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Sien onlangse boodskappe, gemiste oproepe en statusopdaterings"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Gesprek"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Onderbreek deur Moenie Steur nie"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> het \'n boodskap gestuur: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> het \'n prent gestuur"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> het \'n statusopdatering: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktiewe programme</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiewe program</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nuwe inligting"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiewe programme"</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>
@@ -889,8 +910,14 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Wysig gekopieerde teks"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Wysig gekopieerde prent"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Stuur na toestel in die omtrek"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="add" msgid="81036585205287996">"Voeg by"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Bestuur gebruikers"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Sleep na verdeelde skerm word nie vir hierdie kennisgewing gesteun nie."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑fi onbeskikbaar"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteitmodus"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gestel"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistent-gasmodus is geaktiveer"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera en mikrofoon is af"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 03ae0e4..43ad005 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -20,7 +20,12 @@
 <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">"የስርዓት UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"ባትሪ በቅርቡ ሊያልቅ ይችላል"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ይቀራል"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"በዩኤስቢ በኩል ኃይል መሙላት አይቻልም"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"ከእርስዎ መሣሪያ ጋር የመጣውን ኃይል መሙያ ይጠቀሙ"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"መልክ ተረጋግጧል"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ተረጋግጧል"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ለማጠናቀቅ አረጋግጥን መታ ያድርጉ"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ዝጋ"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ሙሉ ለሙሉ ጸጥታ"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ማንቂያዎች ብቻ"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"አትረብሽ።"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ብሉቱዝ።"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ብሉቱዝ በርቷል።"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ማንቂያ ለ<xliff:g id="TIME">%s</xliff:g> ተዋቅሯል።"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"የማወራረጃ ምግቦች መያዣ"</string>
     <string name="start_dreams" msgid="9131802557946276718">"የማያ ገጽ ማቆያ"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ኤተርኔት"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"አትረብሽ"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ብሉቱዝ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ምንም የተጣመሩ መሣሪያዎች አይገኝም"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ባትሪ"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"ማሳወቂያዎች"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ውይይቶች"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ሁሉንም ጸጥ ያሉ ማሳወቂያዎችን ያጽዱ"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ማሳወቂያዎች በአትረብሽ ባሉበት ቆመዋል"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ሁኔታ:&lt;/b&gt; ዝቅተኛ ደረጃ ተሰጥቶታል"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ እንደ አረፋ ሆኖ ይታያል"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ አትረብሽን ያቋርጣል"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ እንደ አረፋ ሆኖ ይታያል፣ አትረብሽን ያቋርጣል"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"ኤስኤምኤስ"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ሙዚቃ"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"የቀን መቁጠሪያ"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"አትረብሽ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"የድምፅ አዝራሮች አቋራጭ"</string>
     <string name="battery" msgid="769686279459897127">"ባትሪ"</string>
     <string name="headset" msgid="4485892374984466437">"ጆሮ ማዳመጫ"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>፣ <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ጠፍቷል"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ብሉቱዝ ጠፍቷል"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"አትረብሽ ጠፍቷል"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"አትረብሽ በአንድ ራስ-ሰር ደንብ (<xliff:g id="ID_1">%s</xliff:g>) በርቷል።"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"አትረብሽ በአንድ መተግበሪያ (<xliff:g id="ID_1">%s</xliff:g>) በርቷል።"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"አትረብሽ በአንድ ራስ-ሰር ደንብ ወይም መተግበሪያ በርቷል።"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"በጀርባ ውስጥ የሚያሄዱ መተግበሪያዎች"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"በባትሪ እና ውሂብ አጠቃቀም ላይ ዝርዝሮችን ለማግኘት መታ ያድርጉ"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"የተንቀሳቃሽ ስልክ ውሂብ ይጥፋ?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ስራ)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"የስልክ ጥሪ"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(በ<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> በኩል)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"ካሜራ"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"አካባቢ"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"ማይክሮፎን"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ተቋርጧል)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"መቀየር አይቻልም። እንደገና ለመሞከር መታ ያድርጉ።"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"አዲስ መሣሪያ ያጣምሩ"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ይህን ክፍለ ጊዜ cast ለማድረግ፣ እባክዎ መተግበሪያውን ይክፈቱ።"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"የማይታወቅ መተግበሪያ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"የግንብ ቁጥር"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"የገንባ ቁጥር ወደ ቅንጥብ ሰሌዳ ተቀድቷል።"</string>
     <string name="basic_status" msgid="2315371112182658176">"ውይይት ይክፈቱ"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"የቅርብ ጊዜ መልዕክቶችን፣ ያመለጡ ጥሪዎች እና፣ የሁኔታ ዝመናዎችን ይመልከቱ"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"ውይይት"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"በአትረብሽ ባለበት ቆሟል"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> መልዕክት ልከዋል፦ <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ምስል ልኳል"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> የሁኔታ ዝማኔ አለው፦ <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"አዲስ መረጃ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ገቢር መተግበሪያዎች"</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>
@@ -889,8 +910,14 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"የተቀዳ ጽሁፍ አርትዕ ያድርጉ"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"የተቀዳ ምስል አርትዕ ያድርጉ"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"በአቅራቢያ ወዳለ መሳሪያ ይላኩ"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="add" msgid="81036585205287996">"አክል"</string>
+    <string name="manage_users" msgid="1823875311934643849">"ተጠቃሚዎችን ያስተዳድሩ"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"ይህ ማሳወቂያ ወደ Splitscreen መጎተትን አይደግፍም።"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi አይገኝም"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"የቅድሚያ ሁነታ"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ማንቂያ ተቀናብሯል"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"የረዳት እንግዳ ሁነታ ነቅቷል"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ካሜራ እና ማይክሮፎን ጠፍተዋል"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 38dcb89..5ec5e9b 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"قد ينفد شحن البطارية قريبًا"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"متبقي <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"‏يتعذّر الشحن باستخدام USB."</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"استخدم الشاحن المرفق بجهازك."</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"تمّت مصادقة الوجه."</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تمّ التأكيد."</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"يمكنك النقر على \"تأكيد\" لإكمال المهمة."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"إغلاق"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"كتم الصوت تمامًا"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"المنبِّهات فقط"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"عدم الإزعاج"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"البلوتوث."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"تفعيل البلوتوث."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"تم ضبط المنبّه على <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -209,6 +217,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"حالة الحلويات"</string>
     <string name="start_dreams" msgid="9131802557946276718">"شاشة الاستراحة"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"عدم الإزعاج"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"بلوتوث"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"لا يتوفر أي أجهزة مقترنة"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"مستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -360,6 +369,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"الإشعارات"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"المحادثات"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"محو جميع الإشعارات الصامتة"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"تم إيقاف الإشعارات مؤقتًا وفقًا لإعداد \"عدم الإزعاج\""</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>
@@ -503,6 +513,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"‏&lt;b&gt;الحالة:&lt;/b&gt; تم خفض الترتيب"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل."</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل وتظهر على شكل فقاعة."</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل، وتقاطع ميزة \"عدم الإزعاج\"."</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل وتظهر على شكل فقاعة لمقاطعة ميزة \"عدم الإزعاج\"."</string>
     <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>
@@ -586,6 +598,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"‏الرسائل القصيرة SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"الموسيقى"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"التقويم"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"عدم الإزعاج"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"اختصار أزرار مستوى الصوت"</string>
     <string name="battery" msgid="769686279459897127">"البطارية"</string>
     <string name="headset" msgid="4485892374984466437">"سماعة الرأس"</string>
@@ -704,6 +717,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>، <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"‏تم إيقاف شبكة Wi-Fi"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"تم إيقاف البلوتوث."</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"تم إيقاف وضع \"عدم الإزعاج\""</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة تطبيق (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"تم تفعيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية أو تطبيق."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"التطبيقات التي تعمل في الخلفية"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"انقر للحصول على تفاصيل حول البطارية واستخدام البيانات"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"هل تريد إيقاف بيانات الجوّال؟"</string>
@@ -728,6 +745,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(العمل)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"المكالمات الهاتفية"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(من خلال <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"الكاميرا"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"الموقع"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"الميكروفون"</string>
@@ -830,6 +849,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(غير متّصل)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"لا يمكن التبديل. انقر لإعادة المحاولة."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"إقران جهاز جديد"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"لبث هذه الجلسة، يُرجى فتح التطبيق"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"تطبيق غير معروف"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string>
     <string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string>
@@ -863,6 +884,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+<xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"عرض أحدث الرسائل والمكالمات الفائتة والتغييرات في الحالة"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"محادثة"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"تم إيقاف الإشعار مؤقتًا من خلال ميزة \"عدم الإزعاج\""</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"تم إرسال رسالة من <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"تم إرسال صورة من <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"تم تعديل حالة <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -905,8 +927,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"معلومات جديدة"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"# تطبيق نشط"</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>
@@ -914,14 +935,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"تم النسخ."</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"من <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"إغلاق واجهة مستخدم النسخ"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"تعديل النص المنسوخ"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"تعديل الصورة المنسوخة"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"الإرسال إلى جهاز مجاور"</string>
+    <string name="add" msgid="81036585205287996">"إضافة"</string>
+    <string name="manage_users" msgid="1823875311934643849">"إدارة المستخدمين"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"لا يتيح هذا الإشعار السحب لتقسيم الشاشة."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏شبكة Wi‑Fi غير متاحة"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"وضع الأولوية"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"تم ضبط المنبه."</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"‏تم تفعيل وضع الضيف لاستخدام \"مساعد Google\"."</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"الكاميرا والميكروفون غير مفعّلين."</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 8d8a0fb..00f7790 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"বেটাৰী অতি সোনকালে শেষ হ\'ব পাৰে"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> বাকী আছে"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"ইউএছবি জৰিয়তে চ্চাৰ্জ কৰিব নোৱাৰি"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"আপোনাৰ ডিভাইচৰ লগত পোৱা চ্চাৰ্জাৰটো ব্যৱহাৰ কৰক।"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"নিশ্চিত কৰিলে"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"সম্পূৰ্ণ কৰিবলৈ নিশ্চিত কৰক-ত টিপক"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"বন্ধ কৰক"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"সম্পূৰ্ণ নিৰৱতা"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"কেৱল এলাৰ্মবোৰৰ বাবে"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"অসুবিধা নিদিব"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ব্লুটুথ।"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ব্লুটুথ অন হৈ আছে।"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g>ৰ বাবে এলাৰ্ম ছেট কৰা হৈছে।"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"মিষ্টান্ন ভাণ্ডাৰ"</string>
     <string name="start_dreams" msgid="9131802557946276718">"স্ক্ৰীন ছেভাৰ"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ইথাৰনেট"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"অসুবিধা নিদিব"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ব্লুটুথ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"কোনো যোৰা লগোৱা ডিভাইচ উপলব্ধ নহয়।"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"বেটাৰী <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"জাননীসমূহ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"বাৰ্তালাপ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"আটাইবোৰ নীৰৱ জাননী মচক"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"অসুবিধা নিদিব-ই জাননী পজ কৰিছে"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;স্থিতি:&lt;/b&gt; স্থান তললৈ কৰা হৈছে"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"বাৰ্তালাপৰ জাননীৰ শীৰ্ষত আৰু প্ৰ’ফাইল চিত্ৰ হিচাপে লক স্ক্ৰীনত দেখুৱায়"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"বাৰ্তালাপৰ জাননীৰ শীৰ্ষত আৰু প্ৰ’ফাইল চিত্ৰ হিচাপে লক স্ক্ৰীনত দেখুৱায়, এটা বাবল হিচাপে দেখা পোৱা যায়"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"বাৰ্তালাপৰ জাননীৰ শীৰ্ষত আৰু প্ৰ’ফাইল চিত্ৰ হিচাপে লক স্ক্ৰীনত দেখুৱায়, অসুবিধা নিদিব ম’ডত ব্যাঘাত জন্মায়"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"বাৰ্তালাপৰ জাননীৰ শীৰ্ষত আৰু প্ৰ’ফাইল চিত্ৰ হিচাপে লক স্ক্ৰীনত দেখুৱায়, এটা বাবল হিচাপে দেখা পোৱা যায়, অসুবিধা নিদিব ম’ডত ব্যাঘাত জন্মায়"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"এছএমএছ"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"সংগীত"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"অসুবিধা নিদিব"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ভলিউম বুটামসমূহৰ শ্বৰ্টকাট"</string>
     <string name="battery" msgid="769686279459897127">"বেটাৰী"</string>
     <string name="headset" msgid="4485892374984466437">"হেডছেট"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"ৱাই-ফাই অফ অৱস্থাত আছে"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ব্লুটুথ অফ অৱস্থাত আছে"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"অসুবিধা নিদিব অফ অৱস্থাত আছে"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"অসুবিধা নিদিব-ক এটা স্বয়ংক্ৰিয় নিয়ম (<xliff:g id="ID_1">%s</xliff:g>)এ অন কৰিলে।"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"অসুবিধা নিদিব-ক কোনো এপ্ (<xliff:g id="ID_1">%s</xliff:g>)এ অন কৰিলে।"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"অসুবিধা নিদিব-ক এটা স্বয়ংক্ৰিয় নিয়ম বা এপে অন কৰিলে।"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"নেপথ্যত চলি থকা এপসমূহ"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"বেটাৰী আৰু ডেটাৰ ব্যৱহাৰৰ বিষয়ে সবিশেষ জানিবলৈ টিপক"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"ম’বাইল ডেটা অফ কৰিবনে?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(কৰ্মস্থান)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ফ’ন কল"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>ৰ জৰিয়তে)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"Camera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"অৱস্থান"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"মাইক্ৰ\'ফ\'ন"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(সংযোগ বিচ্ছিন্ন কৰা হৈছে)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"সলনি কৰিব নোৱাৰি। আকৌ চেষ্টা কৰিবলৈ টিপক।"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইচ পেয়াৰ কৰক"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই ছেশ্বনটো কাষ্ট কৰিবলৈ, অনুগ্ৰহ কৰি এপ্‌টো খোলক"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজ্ঞাত এপ্"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ডৰ নম্বৰ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ক্লিপব’ৰ্ডলৈ বিল্ডৰ নম্বৰ প্ৰতিলিপি কৰা হ’ল।"</string>
     <string name="basic_status" msgid="2315371112182658176">"বাৰ্তালাপ খোলক"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"শেহতীয়া বাৰ্তা, মিছড্‌ কল আৰু স্থিতিৰ আপডে’ট চাওক"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"বাৰ্তালাপ"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"অসুবিধা নিদিব সুবিধাটোৱে পজ কৰিছে"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>এ এটা বাৰ্তা পঠিয়াইছে: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>এ এখন প্ৰতিচ্ছবি পঠিয়াইছে"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>ৰ এটা স্থিতিৰ আপডে’ট আছে: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"নতুন তথ্য"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"সক্ৰিয় এপ্‌"</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>
@@ -889,8 +910,14 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"প্ৰতিলিপি কৰা পাঠ সম্পাদনা কৰক"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"প্ৰতিলিপি কৰা প্ৰতিচ্ছবি সম্পাদনা কৰক"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"নিকটৱৰ্তী ডিভাইচলৈ পঠাওক"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="add" msgid="81036585205287996">"যোগ দিয়ক"</string>
+    <string name="manage_users" msgid="1823875311934643849">"ব্যৱহাৰকাৰী পৰিচালনা কৰক"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"এই জাননীটোৱে টানি আনি এৰাৰ পৰা বিভাজিত স্ক্ৰীন সমৰ্থন নকৰে।"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ৱাই-ফাই উপলব্ধ নহয়"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"অগ্ৰাধিকাৰ ম’ড"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"এলাৰ্ম ছেট কৰা হ’ল"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistantৰ অতিথি ম’ড সক্ষম কৰা হৈছে"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"কেমেৰা আৰু মাইক অফ হৈ আছে"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 1fc28a8..a1956b3 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -20,7 +20,12 @@
 <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">"Sistemin İstifadə İnterfeysi"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Batareya tezliklə bitə bilər"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> qalır"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB vasitəsilə enerji yığa bilməz"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Cihazla verilən adapterdən istifadə edin"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Üz doğrulandı"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Təsdiqləndi"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tamamlamaq üçün \"Təsdiq edin\" seçiminə toxunun"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Doğrulandı"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN istifadə edin"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Model istifadə edin"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Qapadın"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"tam sakitlik"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"bildirişlər"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Narahat Etməyin."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth aktiv."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm <xliff:g id="TIME">%s</xliff:g> üçün qurulub."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Desert Qabı"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Ekran qoruyucu"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Narahat etməyin"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Heç bir cütlənmiş cihaz əlçatan deyil"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batareya"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirişlər"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Söhbətlər"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Səssiz bildirişlərin hamısını silin"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bildirişlər \"Narahat Etməyin\" rejimi tərəfindən dayandırıldı"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"İndi başlayın"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Heç bir bildiriş yoxdur"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz valideyniniz tərəfindən idarə olunur"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Aşağı sıraya keçirilib"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Söhbət bildirişlərinin yuxarısında və kilid ekranında profil şəkli kimi göstərilir"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Söhbət bildirişlərinin yuxarısında və kilid ekranında profil şəkli kimi göstərilir, baloncuq kimi görünür"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Söhbət bildirişlərinin yuxarısında və kilid ekranında profil şəkli kimi göstərilir, Narahat Etməyin rejimini kəsir"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Söhbət bildirişlərinin yuxarısında və kilid ekranında profil şəkli kimi göstərilir, baloncuq kimi görünür, Narahat Etməyin rejimini kəsir"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> söhbət funksiyalarını dəstəkləmir"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirişlər dəyişdirilə bilməz."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiqi"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Təqvim"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Narahat Etməyin"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Səs düymələri qısayolu"</string>
     <string name="battery" msgid="769686279459897127">"Batareya"</string>
     <string name="headset" msgid="4485892374984466437">"Qulaqlıq"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi deaktivdir"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth deaktivdir"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"\"Narahat Etməyin\" deaktivdir"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"Narahat etməyin\" rejimi (<xliff:g id="ID_1">%s</xliff:g>) avtomatik qaydası tərəfindən aktiv edildi."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"Narahat etməyin\" rejimi (<xliff:g id="ID_1">%s</xliff:g>) tətbiqi tərəfindən aktiv edildi."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"Narahat etməyin\" rejimi avtomatik qayda və ya tətbiq tərəfindən aktiv edildi."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Arxa fonda işləyən tətbiqlər"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Batareya və data istifadəsi haqqında ətraflı məlumat üçün klikləyin"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Mobil data söndürülsün?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(iş)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefon zəngi"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> vasitəsilə)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"məkan"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(bağlantı kəsildi)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Dəyişmək olmur. Yenidən cəhd etmək üçün toxunun."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Cihaz əlavə edin"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu sessiyanı yayımlamaq üçün tətbiqi açın."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Naməlum tətbiq"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Montaj nömrəsi"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versiya nömrəsi mübadilə buferinə kopyalandı."</string>
     <string name="basic_status" msgid="2315371112182658176">"Açıq söhbət"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Son mesajlar, buraxılmış zənglər və status güncəlləmələrinə baxın"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Söhbət"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"\"Narahat Etməyin\" rejimini tərəfindən durdurulub"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> mesaj göndərdi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> şəkil göndərdi"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> status güncəlləməsi edib: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktiv tətbiq</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiv tətbiq</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Yeni məlumat"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiv tətbiqlər"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Dayandırın"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Dayandırılıb"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopyalandı"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Mənbə: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI kopyalanmasını qapadın"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Kopyalanmış mətni redaktə edin"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Kopyalanmış şəkli redaktə edin"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Yaxınlıqdakı cihaza göndərin"</string>
+    <string name="add" msgid="81036585205287996">"Əlavə edin"</string>
+    <string name="manage_users" msgid="1823875311934643849">"İstifadəçiləri idarə edin"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildiriş Ayrılmış ekrana sürüşdürməyi dəstəkləmir."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi əlçatan deyil"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritet rejimi"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Siqnal ayarlanıb"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistent qonaq rejimi aktivdir"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera və mikrofon deaktivdir"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 555b477..2019e9d 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI sistema"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Baterija će se možda uskoro isprazniti"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Još <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Punjenje preko USB-a nije uspelo"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Koristite punjač koji ste dobili uz uređaj"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je potvrđeno"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da biste završili"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Identitet je potvrđen"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite šablon"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvori"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"potpuna tišina"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne uznemiravaj."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth je uključen."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm je podešen za <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Vitrina sa poslasticama"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Čuvar ekrana"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Eternet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne uznemiravaj"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nije dostupan nijedan upareni uređaj"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -351,6 +360,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Obaveštenja"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzacije"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obrišite sva nečujna obaveštenja"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obaveštenja su pauzirana režimom Ne uznemiravaj"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Započni"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nema obaveštenja"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja roditelj"</string>
@@ -494,6 +504,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Rangirano niže"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, pojavljuje se kao oblačić"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, prekida režim Ne uznemiravaj"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, pojavljuje se kao oblačić, prekida režim Ne uznemiravaj"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije konverzacije"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ova obaveštenja ne mogu da se menjaju."</string>
@@ -571,6 +583,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne uznemiravaj"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Prečica za dugmad za jačinu zvuka"</string>
     <string name="battery" msgid="769686279459897127">"Baterija"</string>
     <string name="headset" msgid="4485892374984466437">"Naglavne slušalice"</string>
@@ -689,6 +702,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"WiFi je isključen"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Režim Ne uznemiravaj je isključen"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>) je uključilo režim Ne uznemiravaj."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je uključila režim Ne uznemiravaj."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automatsko pravilo ili aplikacija su uključili režim Ne uznemiravaj."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije pokrenute u pozadini"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Želite da isključite mobilne podatke?"</string>
@@ -713,6 +730,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(posao)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski poziv"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(preko: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -812,6 +831,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Prebacivanje nije uspelo. Probajte ponovo."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Upari novi uređaj"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste prebacivali ovu sesiju, otvorite aplikaciju."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string>
@@ -845,6 +866,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Pogledajte nedavne poruke, propuštene pozive i ažuriranja statusa"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Konverzacija"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Pauzirano režimom Ne uznemiravaj"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la poruku: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> šalje sliku"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ima ažuriranje statusa: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
       <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aktivne aplikacije</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktivnih aplikacija</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</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>
@@ -893,14 +914,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopirano je"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Iz: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Odbaci kopiranje korisničkog interfejsa"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Izmenite kopirani tekst"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Izmenite kopiranu sliku"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošalji na uređaj u blizini"</string>
+    <string name="add" msgid="81036585205287996">"Dodaj"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Upravljajte korisnicima"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Ovo obaveštenje ne podržava prevlačenje na podeljeni ekran."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi nije dostupan"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni režim"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je podešen"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Omogućen je režim gosta u Pomoćniku"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 7446007..c10a36d 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"Акумулятар хутка разрадзіцца"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Засталося <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Не ўдалося выканаць зарадку праз USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Выкарыстоўвайце зараднае прыстасаванне з камплекта прылады"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Твар распазнаны"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Пацверджана"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Націсніце \"Пацвердзіць\", каб завяршыць"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Закрыць"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"поўная цішыня"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"толькі будзільнікі"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не турбаваць."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth уключаны."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Наладжаны будзiльнiк: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Вітрына з дэсертамі"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Экранная застаўка"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не турбаваць"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Няма даступных спалучаных прылад"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Узровень зараду: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Апавяшчэнні"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Размовы"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Выдаліць усе апавяшчэнні без гуку"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Паказ апавяшчэнняў прыпынены ў рэжыме \"Не турбаваць\""</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>
@@ -497,6 +507,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Стан:&lt;/b&gt; Ацэнена як няважнае"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"З\'яўляецца ўверсе раздзела размоў і паказвае на экране блакіроўкі відарыс профілю"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"З\'яўляецца ўверсе раздзела размоў як усплывальнае апавяшчэнне, якое паказвае на экране блакіроўкі відарыс профілю"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"З\'яўляецца ўверсе раздзела размоў, перарывае рэжым \"Не турбаваць\" і паказвае на экране блакіроўкі відарыс профілю"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З\'яўляецца ўверсе раздзела размоў як усплывальнае апавяшчэнне, якое перарывае рэжым \"Не турбаваць\" і паказвае на экране блакіроўкі відарыс профілю"</string>
     <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>
@@ -576,6 +588,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS-паведамленні"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музыка"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Каляндар"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не турбаваць"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Доступ праз кнопкі рэгулявання гучнасці"</string>
     <string name="battery" msgid="769686279459897127">"Акумулятар"</string>
     <string name="headset" msgid="4485892374984466437">"Гарнітура"</string>
@@ -694,6 +707,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi выключаны"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth выключаны"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Рэжым \"Не турбаваць\" выключаны"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Рэжым \"Не турбаваць\" быў уключаны праграмай (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам ці праграмай."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Праграмы, якія працуюць у фонавым рэжыме"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Дакраніцеся, каб даведацца пра выкарыстанне трафіка і акумулятара"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Выключыць мабільную перадачу даных?"</string>
@@ -718,6 +735,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(працоўная)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Тэлефонны выклік"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(праз праграму \"<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>\")"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"геалакацыя"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"мікрафон"</string>
@@ -818,6 +837,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(адключана)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не ўдалося пераключыцца. Дакраніцеся, каб паўтарыць спробу."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спалучыць з новай прыладай"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Для трансляцыі гэтага сеанса адкрыйце праграму."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невядомая праграма"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Нумар зборкі"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Нумар зборкі скапіраваны ў буфер абмену."</string>
     <string name="basic_status" msgid="2315371112182658176">"Адкрытая размова"</string>
@@ -851,6 +872,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Глядзець нядаўнія паведамленні, прапушчаныя выклікі і абнаўленні стану"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Размова"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Прыпынена функцыяй \"Не турбаваць\""</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> прыслаў паведамленне: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> адправіў відарыс"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> абнавіў стан: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Новая інфармацыя"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Актыўныя праграмы"</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>
@@ -900,14 +921,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Скапіравана"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"З праграмы \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Закрыць інтэрфейс капіравання"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Змяніць скапіраваны тэкст"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Змяніць скапіраваны відарыс"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Адправіць на прыладу паблізу"</string>
+    <string name="add" msgid="81036585205287996">"Дадаць"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Кіраванне карыстальнікамі"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Гэта апавяшчэнне нельга перацягнуць на падзелены экран."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Сетка Wi‑Fi недаступная"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Прыярытэтны рэжым"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будзільнік зададзены"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Гасцявы рэжым для Памочніка ўключаны"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера і мікрафон выключаны"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index f7a1ad6..a107504 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"Батерията може скоро да се изтощи"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Остава/т <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Зареждането през USB не е възможно"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Използвайте оригиналното зарядно устройство"</string>
@@ -111,7 +116,7 @@
     <string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон"</string>
     <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Гласова помощ"</string>
     <string name="accessibility_wallet_button" msgid="1458258783460555507">"Портфейл"</string>
-    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Инструмент за сканиране на QR кодове"</string>
+    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Скенер за QR кодове"</string>
     <string name="accessibility_unlock_button" msgid="122785427241471085">"Отключване"</string>
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Устройството е заключено"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Извършва се сканиране на лице"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицето е удостоверено"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потвърдено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Докоснете „Потвърждаване“ за завършване"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Затваряне"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"пълна тишина"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"само будилници"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не безпокойте."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Функцията за Bluetooth е включена."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Будилникът е навит за <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Витрина с десерти"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Скрийнсейвър"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не безпокойте"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Няма налични сдвоени устройства"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Известия"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Разговори"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Изчистване на всички беззвучни известия"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Известията са поставени на пауза от режима „Не безпокойте“"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Състояние:&lt;/b&gt; Класирано по-ниско"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Показва се в горната част на известията за разговори и като снимка на потребителския профил на заключения екран"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Показва се в горната част на известията за разговори и като снимка на потребителския профил на заключения екран, изглежда като балонче"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Показва се в горната част на известията за разговори и като снимка на потребителския профил на заключения екран, прекъсва режима „Не безпокойте“"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Показва се в горната част на известията за разговори и като снимка на потребителския профил на заключения екран, изглежда като балонче, прекъсва режима „Не безпокойте“"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не безпокойте"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Пряк път към бутоните за силата на звука"</string>
     <string name="battery" msgid="769686279459897127">"Батерия"</string>
     <string name="headset" msgid="4485892374984466437">"Слушалки"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Функцията за Wi‑Fi е изключена"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Функцията за Bluetooth е изключена"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Режимът „Не безпокойте“ е изключен"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Режимът „Не безпокойте“ бе включен от автоматично правило (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Режимът „Не безпокойте“ бе включен от приложение (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Режимът „Не безпокойте“ бе включен от автоматично правило или от приложение."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Приложения, работещи на заден план"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Докоснете за информация относно използването на батерията и преноса на данни"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Да се изключат ли мобилните данни?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(служебно)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонно обаждане"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(чрез <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"камерата"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"местополож."</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофона"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(връзката е прекратена)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не може да се превключи. Докоснете за нов опит."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Сдвояване на ново устройство"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да предавате тази сесия, моля, отворете приложението."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестно приложение"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string>
     <string name="basic_status" msgid="2315371112182658176">"Отворен разговор"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Над <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Преглеждайте скорошни съобщения, пропуснати обаждания и информация за състоянието"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Разговор"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Поставено на пауза от режима „Не безпокойте“"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> изпрати съобщение: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> изпрати изображение"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има актуализация на състоянието: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нова информация"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активни приложения"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"От <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Отхвърляне на ПИ за копиране"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Редактиране на копирания текст"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Редактиране на копираното изображение"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Изпращане до устройство в близост"</string>
+    <string name="add" msgid="81036585205287996">"Добавяне"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Управление на потребителите"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Това известие не поддържа плъзгане за разделяне на екрана."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi не е налице"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетен режим"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будилникът е зададен"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Режимът на гост за Асистент е активиран"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонът са изключени"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 36a5bc4..b5040e9 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -20,7 +20,12 @@
 <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">"সিস্টেম UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"চার্জ শীঘ্রই শেষ হয়ে যেতে পারে"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> অবশিষ্ট আছে"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"ইউএসবি দিয়ে চার্জ করা যাবে না"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"ডিভাইসের সাথে যে চার্জারটি পেয়েছেন, সেটি ব্যবহার করুন"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ফেস যাচাই করা হয়েছে"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"কনফার্ম করা হয়েছে"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"সম্পূর্ণ করতে \'কনফার্ম করুন\' বোতামে ট্যাপ করুন"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"বন্ধ করুন"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"সম্পূর্ণ নীরব"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"শুধুমাত্র অ্যালার্ম"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"বিরক্ত করবে না।"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ব্লুটুথ"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ব্লুটুথ চালু আছে।"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> এ অ্যালার্ম সেট করা হয়েছে৷"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"ডেজার্ট কেস"</string>
     <string name="start_dreams" msgid="9131802557946276718">"স্ক্রিন সেভার"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ইথারনেট"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"বিরক্ত করবে না"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ব্লুটুথ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"চেনা কোনও ডিভাইস নেই"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"বিজ্ঞপ্তি"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"কথোপকথন"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"সব নীরব বিজ্ঞপ্তি মুছুন"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'বিরক্ত করবে না\' দিয়ে বিজ্ঞপ্তি পজ করা হয়েছে"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;স্ট্যাটাস:&lt;/b&gt; র‍্যাঙ্ক কমে গেছে"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"কথোপকথনের বিজ্ঞপ্তির উপরের দিকে এবং প্রোফাইল ছবি হিসেবে লক স্ক্রিনে দেখানো হয়"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"কথোপকথনের বিজ্ঞপ্তির উপরের দিকে এবং প্রোফাইল ছবি হিসেবে লক স্ক্রিনে দেখানো হয়, বাবল হিসেবেও এটি দেখা যায়"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"কথোপকথনের বিজ্ঞপ্তির উপরের দিকে এবং প্রোফাইল ছবি হিসেবে লক স্ক্রিনে দেখানো হয় এবং এর ফলে \'বিরক্ত করবে না\' মোডে কাজ করতে অসুবিধা হয়"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"কথোপকথনের বিজ্ঞপ্তির উপরের দিকে এবং প্রোফাইল ছবি হিসেবে লক স্ক্রিনে দেখানো হয়, বাবল হিসেবেও এটি দেখা যায় এবং এর ফলে \'বিরক্ত করবে না\' মোডে কাজ করতে অসুবিধা হয়"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"সংগীত"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"বিরক্ত করবে না"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ভলিউম বোতামের শর্টকাট"</string>
     <string name="battery" msgid="769686279459897127">"ব্যাটারি"</string>
     <string name="headset" msgid="4485892374984466437">"হেডসেট"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"ওয়াই ফাই বন্ধ আছে"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ব্লুটুথ বন্ধ আছে"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"বিরক্ত করবে না বিকল্পটি বন্ধ আছে"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"বিরক্ত করবে না বিকল্পটি একটি স্বয়ংক্রিয় নিয়ম <xliff:g id="ID_1">%s</xliff:g> এর দ্বারা চালু করা হয়েছে।"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"বিরক্ত করবে না বিকল্পটি একটি অ্যাপ <xliff:g id="ID_1">%s</xliff:g> এর দ্বারা চালু করা হয়েছে।"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"বিরক্ত করবে না বিকল্পটি একটি স্বয়ংক্রিয় নিয়ম বা অ্যাপের দ্বারা চালু করা হয়েছে।"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"পটভূমিতে অ্যাপ চালু আছে"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"ব্যাটারি এবং ডেটার ব্যবহারের বিশদ বিবরণের জন্য ট্যাপ করুন"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"মোবাইল ডেটা বন্ধ করবেন?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(অফিস)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ফোন কল"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>-এর সাহায্যে)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"ক্যামেরা"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"লোকেশন"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"মাইক্রোফোন"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ডিসকানেক্ট হয়ে গেছে)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"পাল্টানো যাচ্ছে না। আবার চেষ্টা করতে ট্যাপ করুন।"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইস পেয়ার করুন"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই সেশন কাস্ট করার জন্য, অ্যাপ খুলুন।"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজানা অ্যাপ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ড নম্বর"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"বিল্ড নম্বর ক্লিপবোর্ডে কপি করা হয়েছে।"</string>
     <string name="basic_status" msgid="2315371112182658176">"খোলা কথোপকথন"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"সাম্প্রতিক মেসেজ, মিসড কল এবং স্ট্যাটাস সংক্রান্ত আপডেট দেখুন"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"কথোপকথন"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"\'বিরক্ত করবে না\' মোডের মাধ্যমে পজ করা আছে"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> একটি মেসেজ পাঠিয়েছেন: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> একটি ছবি পাঠিয়েছেন"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> একটি স্ট্যাটাস আপডেট করেছেন: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"নতুন তথ্য"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"অ্যাক্টিভ অ্যাপ"</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>
@@ -889,8 +910,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"কপি করা টেক্সট এডিট করুন"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"কপি করা ছবি এডিট করুন"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"আশেপাশের ডিভাইসে পাঠান"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"যোগ করুন"</string>
+    <string name="manage_users" msgid="1823875311934643849">"ব্যবহারকারীদের ম্যানেজ করুন"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"স্প্লিটস্ক্রিন মোডে এই বিজ্ঞপ্তি টেনে আনা যাবে না।"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ওয়াই-ফাই উপলভ্য নেই"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"প্রায়োরিটি মোড"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"অ্যালার্ম সেট করা হয়েছে"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant-এর \'অতিথি মোড\' চালু করা হয়েছে"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ক্যামেরা ও মাইক্রোফোন বন্ধ আছে"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#টি বিজ্ঞপ্তি}one{#টি বিজ্ঞপ্তি}other{#টি বিজ্ঞপ্তি}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 1545c43..b0691fe 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -20,7 +20,12 @@
 <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">"Sistemski UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Baterija će se uskoro isprazniti"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Preostalo <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Punjenje putem USB-a nije moguće"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Koristite punjač koji ste dobili uz uređaj"</string>
@@ -111,7 +116,7 @@
     <string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
     <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovna pomoć"</string>
     <string name="accessibility_wallet_button" msgid="1458258783460555507">"Novčanik"</string>
-    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Skener QR kôda"</string>
+    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Skener QR koda"</string>
     <string name="accessibility_unlock_button" msgid="122785427241471085">"Otključaj"</string>
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je provjereno"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da završite"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificirano"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristi PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristi uzorak"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvori"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"potpuna tišina"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne ometaj."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth uključen."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm je podešen na <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Slika sa desertima"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Čuvar ekrana"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne ometaj"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nema dostupnih uparenih uređaja"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string>
@@ -351,6 +360,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Obavještenja"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Razgovori"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obriši sva nečujna obavještenja"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obavještenja su pauzirana načinom rada Ne ometaj"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nema obavještenja"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
@@ -494,6 +504,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; je rangiran niže"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Prikazuje se na vrhu obavještenja u razgovorima i kao slika profila na zaključanom ekranu"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Prikazuje se na vrhu obavještenja u razgovorima i kao slika profila na zaključanom ekranu, izgleda kao oblačić"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikazuje se na vrhu obavještenja u razgovorima i kao slika profila na zaključanom ekranu, prekida funkciju Ne ometaj"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se na vrhu obavještenja u razgovorima i kao slika profila na zaključanom ekranu, izgleda kao oblačić, prekida funkciju Ne ometaj"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije razgovora"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ta obavještenja se ne mogu izmijeniti."</string>
@@ -571,6 +583,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne ometaj"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Prečica za dugmad za Jačinu zvuka"</string>
     <string name="battery" msgid="769686279459897127">"Baterija"</string>
     <string name="headset" msgid="4485892374984466437">"Slušalice s mikrofonom"</string>
@@ -689,10 +702,14 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"WiFi veza je isključena"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Način rada Ne ometaj je isključen"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Opciju Ne ometaju uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Način rada Ne ometaj uključila je aplikacija <xliff:g id="ID_1">%s</xliff:g>."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način rada Ne ometaj uključilo je automatsko pravilo ili aplikacija."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije koje rade u pozadini"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Isključiti prijenos podataka na mobilnoj mreži?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nećete imati pristup podacima ni internetu putem mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo putem WiFi mreže."</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nećete imati pristup podacima ni internetu putem mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo putem WiFi-ja."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"vaš operater"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Postavke ne mogu potvrditi vaš odgovor jer aplikacija zaklanja zahtjev za odobrenje."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"Dozvoliti aplikaciji <xliff:g id="APP_0">%1$s</xliff:g> da prikazuje isječke aplikacije <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
@@ -713,6 +730,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(posao)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski poziv"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(putem aplikacije <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -812,6 +831,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nije moguće prebaciti. Dodirnite da pokušate ponovo."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da emitirate ovu sesiju, otvorite aplikaciju."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u međumemoriju."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
@@ -845,6 +866,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Pregledajte nedavne poruke, propuštene pozive i ažuriranja statusa"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Razgovor"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Pauzirala je funkcija Ne ometaj"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la poruku: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la sliku"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> je ažurirao/la status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
       <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aktivne aplikacije</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktivnih aplikacija</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</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>
@@ -896,8 +917,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Uredi kopirani tekst"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Uredi kopiranu sliku"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošalji na uređaj u blizini"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"Dodaj"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Upravljajte korisnicima"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Ovo obavještenje ne podržava prevlačenje na podijeljeni ekran."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi je nedostupan"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Način rada Prioriteti"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Način rada za gosta Asistenta je omogućen"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavijest}one{# obavijest}few{# obavijesti}other{# obavijesti}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 621f5f9..da4cba7 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -20,7 +20,12 @@
 <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">"IU del sistema"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"És possible que la bateria s\'esgoti aviat"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g>."</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"No es pot carregar per USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Fes servir el carregador original del dispositiu"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Cara autenticada"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Tanca"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silenci total"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"només alarmes"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"No molestis."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activat."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"S\'ha configurat l\'alarma (<xliff:g id="TIME">%s</xliff:g>)."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Capsa de postres"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Estalvi de pantalla"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"No molestis"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No hi ha dispositius vinculats  disponibles"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificacions"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Converses"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Esborra totes les notificacions silencioses"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificacions pausades pel mode No molestis"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No hi ha cap notificació"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Els teus pares gestionen aquest dispositiu"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Estat&lt;/b&gt;: s\'ha classificat amb un nivell inferior"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Es mostra a la part superior de les notificacions de les converses i com a foto de perfil a la pantalla de bloqueig"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Es mostra a la part superior de les notificacions de les converses i com a foto de perfil a la pantalla de bloqueig, apareix com una bombolla"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Es mostra a la part superior de les notificacions de les converses i com a foto de perfil a la pantalla de bloqueig, interromp el mode No molestis"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Es mostra a la part superior de les notificacions de les converses i com a foto de perfil a la pantalla de bloqueig, apareix com una bombolla, interromp el mode No molestis"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"No molestis"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Drecera per als botons de volum"</string>
     <string name="battery" msgid="769686279459897127">"Bateria"</string>
     <string name="headset" msgid="4485892374984466437">"Auriculars"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"La Wi-Fi està desactivada"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"El Bluetooth està desactivat"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"El mode No molestis està desactivat"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Una regla automàtica (<xliff:g id="ID_1">%s</xliff:g>) ha activat el mode No molestis."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Una aplicació (<xliff:g id="ID_1">%s</xliff:g>) ha activat el mode No molestis."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Una regla automàtica o una aplicació han activat el mode No molestis."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplicacions que s\'estan executant en segon pla"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Toca per obtenir informació sobre l\'ús de dades i de bateria"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Vols desactivar les dades mòbils?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(feina)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Trucada"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(a través de: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"càmera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ubicació"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"micròfon"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconnectat)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No es pot canviar. Torna-ho a provar."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincula un dispositiu nou"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per emetre aquesta sessió, obre l\'aplicació."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicació desconeguda"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa oberta"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Consulta els missatges recents, les trucades perdudes i les actualitzacions d\'estat"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Posat en pausa pel mode No molestis"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ha enviat un missatge: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha enviat una imatge"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> té una actualització d\'estat: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplicacions actives</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicació activa</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informació nova"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicacions actives"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Atura"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Aturada"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"S\'ha copiat"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"De: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignora la IU de còpia"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edita el text que has copiat"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edita la imatge que has copiat"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Envia a un dispositiu proper"</string>
+    <string name="add" msgid="81036585205287996">"Afegeix"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Gestiona els usuaris"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Aquesta notificació no es pot arrossegar a la pantalla dividida."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi no disponible"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode Prioritat"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Mode de convidat de l\'Assistent activat"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Càmera i micròfon desactivats"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index ba97688..e93fc29 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI systému"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Baterie se brzy vybije"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Zbývá <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Nabíjení přes USB nefunguje"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Používejte originální nabíječku, která byla dodána spolu se zařízením."</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Obličej byl ověřen"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrzeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ověření dokončíte klepnutím na Potvrdit"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ověřeno"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Použít kód PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Použít gesto"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zavřít"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"úplné ticho"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"pouze budíky"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Nerušit."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Rozhraní Bluetooth je zapnuto."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Budík je nastaven na <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Pult se sladkostmi"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Spořič obrazovky"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Nerušit"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nejsou dostupná žádná spárovaná zařízení"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Oznámení"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzace"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vymazat všechna tichá oznámení"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Oznámení jsou pozastavena režimem Nerušit"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Spustit"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Žádná oznámení"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zařízení spravuje rodič"</string>
@@ -497,6 +507,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stav:&lt;/b&gt; zařazeno níže"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Zobrazuje se v horní části sekce konverzací a na obrazovce uzamčení se objevuje jako profilová fotka"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Zobrazuje se v horní části sekce konverzací a na obrazovce uzamčení se objevuje jako profilová fotka, má podobu bubliny"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Zobrazuje se v horní části sekce konverzací a na obrazovce uzamčení se objevuje jako profilová fotka, deaktivuje režim Nerušit"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Zobrazuje se v horní části sekce konverzací a na obrazovce uzamčení se objevuje jako profilová fotka, má podobu bubliny a deaktivuje režim Nerušit"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorita"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> funkce konverzace nepodporuje"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Tato oznámení nelze upravit."</string>
@@ -576,6 +588,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Hudba"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendář"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Nerušit"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Zkratka tlačítek hlasitosti"</string>
     <string name="battery" msgid="769686279459897127">"Baterie"</string>
     <string name="headset" msgid="4485892374984466437">"Sluchátka"</string>
@@ -694,6 +707,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi je vypnuta"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je vypnuto"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Režim Nerušit je vypnut"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režim Nerušit byl zapnut automatickým pravidlem (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režim Nerušit byl zapnut aplikací (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režim Nerušit byl zapnut automatickým pravidlem nebo aplikací."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikace běžící na pozadí"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Klepnutím zobrazíte podrobnosti o využití baterie a dat"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Vypnout mobilní data?"</string>
@@ -718,6 +735,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(práce)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonní hovor"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(prostřednictvím aplikace <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparát"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"poloha"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -818,6 +837,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odpojeno)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nelze přepnout. Klepnutím opakujte akci."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovat nové zařízení"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pokud chcete odesílat relaci, otevřete aplikaci."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznámá aplikace"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otevřít konverzaci"</string>
@@ -851,6 +872,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Zobrazit poslední zprávy, zmeškané hovory a aktualizace stavu"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Konverzace"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Pozastaveno funkcí Nerušit"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> posílá zprávu: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> posílá obrázek"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> má aktualizaci stavu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktivních aplikací</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktivních aplikací</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nové informace"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivní aplikace"</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>
@@ -900,14 +921,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Zkopírováno"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Z aplikace <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Zavřít uživatelské rozhraní kopírování"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Upravit zkopírovaný text"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Upravit zkopírovaný obrázek"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Odeslat do zařízení v okolí"</string>
+    <string name="add" msgid="81036585205287996">"Přidat"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Správa uživatelů"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Toto oznámení nepodporuje přetažení na rozdělenou obrazovku."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Síť Wi‑Fi není k dispozici"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritní režim"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Je nastaven budík"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"U Asistenta je aktivován režim hosta"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparát a mikrofon jsou vypnuté"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# oznámení}few{# oznámení}many{# oznámení}other{# oznámení}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index bbcb9bc..bf460fe 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -20,7 +20,12 @@
 <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">"System-UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Enheden løber muligvis snart tør for batteri"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> tilbage"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Enheden kan ikke oplades via USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Brug den oplader, der fulgte med din enhed"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansigtet er godkendt"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekræftet"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tryk på Bekræft for at udføre"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Godkendt"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Brug pinkode"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Brug mønster"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Luk"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"total stilhed"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"kun alarmer"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Forstyr ikke."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth er slået til."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarmen er indstillet til <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessertcase"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Pauseskærm"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Forstyr ikke"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Der er ingen tilgængelige parrede enheder"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifikationer"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ryd alle lydløse notifikationer"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifikationer er sat på pause af Forstyr ikke"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start nu"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ingen notifikationer"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enhed administreres af din forælder"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Placeret lavere"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Vises øverst i samtalenotifikationer og som et profilbillede på låseskærmen"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Vises øverst i samtalenotifikationer og som et profilbillede på låseskærmen. Vises som en boble"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Vises øverst i samtalenotifikationer og som et profilbillede på låseskærmen. Afbryder Forstyr ikke"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Vises øverst i samtalenotifikationer og som et profilbillede på låseskærmen. Vises som en boble, der afbryder Forstyr ikke"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> understøtter ikke samtalefunktioner"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse notifikationer kan ikke redigeres."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sms"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Forstyr ikke"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Genvej til lydstyrkeknapper"</string>
     <string name="battery" msgid="769686279459897127">"Batteri"</string>
     <string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi er slået fra"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth er slået fra"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Forstyr ikke er slået fra"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Tilstanden Forstyr ikke blev aktiveret af en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Tilstanden Forstyr ikke blev aktiveret af en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Tilstanden Forstyr ikke blev aktiveret af en automatisk regel eller en app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps, der kører i baggrunden"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tryk for at se info om batteri- og dataforbrug"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Vil du deaktivere mobildata?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(arbejde)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonopkald"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(via <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kameraet"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"lokation"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonen"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(afbrudt)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Det var ikke muligt at skifte. Tryk for at prøve igen."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Par ny enhed"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Åbn appen for at caste denne session."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukendt app"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummeret blev kopieret til udklipsholderen."</string>
     <string name="basic_status" msgid="2315371112182658176">"Åben samtale"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Se dine seneste beskeder, mistede opkald og statusopdateringer"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Samtale"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Sat på pause af Forstyr ikke"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> har sendt en besked: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> har sendt et billede"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> har opdateret sin status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aktiv app</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktive apps</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nye oplysninger"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive apps"</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">"Stoppet"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopieret"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Fra <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Luk brugerfladen for kopi"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Rediger kopieret tekst"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Rediger kopieret billede"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send til enhed i nærheden"</string>
+    <string name="add" msgid="81036585205287996">"Tilføj"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Administrer brugere"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Denne notifikation kan ikke trækkes til en opdelt skærm."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Ingen tilgængelig Wi-Fi-forbindelse"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tilstanden Prioritet"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er indstillet"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Gæstetilstand i Assistent er aktiveret"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er slået fra"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 2b9f725..6197b3f 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -20,7 +20,12 @@
 <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">"System-UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Der Akku ist fast leer"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> verbleibend"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Aufladen über USB nicht möglich"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Verwende das mit dem Gerät gelieferte Ladegerät"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gesicht authentifiziert"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Schließen"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"lautlos"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"nur Weckrufe"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Bitte nicht stören."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth aktiviert"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Wecker gestellt für <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessertbehälter"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Bildschirmschoner"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Bitte nicht stören"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Keine gekoppelten Geräte verfügbar"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Benachrichtigungen"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Unterhaltungen"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Alle lautlosen Benachrichtigungen löschen"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Benachrichtigungen durch „Bitte nicht stören“ pausiert"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Jetzt starten"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Keine Benachrichtigungen"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dieses Gerät wird von deinen Eltern verwaltet"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status&lt;/b&gt;: niedriger eingestuft"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Wird oben im Bereich „Unterhaltungen“ sowie als Profilbild auf dem Sperrbildschirm angezeigt"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Wird oben im Bereich „Unterhaltungen“ sowie als Profilbild auf dem Sperrbildschirm angezeigt, erscheint als Bubble"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Wird oben im Bereich „Unterhaltungen“ sowie als Profilbild auf dem Sperrbildschirm angezeigt, unterbricht „Bitte nicht stören“"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wird oben im Bereich „Unterhaltungen“ sowie als Profilbild auf dem Sperrbildschirm angezeigt, erscheint als Bubble, unterbricht „Bitte nicht stören“"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Bitte nicht stören"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Tastenkombination für Lautstärketasten"</string>
     <string name="battery" msgid="769686279459897127">"Akku"</string>
     <string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"WLAN ist deaktiviert"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ist deaktiviert"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"„Bitte nicht stören“ ist deaktiviert"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"„Bitte nicht stören“ wurde von einer automatischen Regel aktiviert (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"„Bitte nicht stören“ wurde von einer App aktiviert (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"„Bitte nicht stören“ wurde von einer automatischen Regel oder einer App aktiviert."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps, die im Hintergrund ausgeführt werden"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Für Details zur Akku- und Datennutzung tippen"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Mobile Daten deaktivieren?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(geschäftlich)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonanruf"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(über <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"Kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"Standort"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"Mikrofon"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nicht verbunden)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Wechseln nicht möglich. Tippe, um es noch einmal zu versuchen."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Neues Gerät koppeln"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öffne zum Streamen dieser Sitzung die App."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unbekannte App"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-Nummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build-Nummer in Zwischenablage kopiert."</string>
     <string name="basic_status" msgid="2315371112182658176">"Offene Unterhaltung"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Letzte Nachrichten, verpasste Anrufe und Statusaktualisierungen ansehen"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Unterhaltung"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Durch „Bitte nicht stören“ pausiert"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> hat eine Nachricht gesendet: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> hat ein Bild gesendet"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> hat den Status aktualisiert: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktive Apps</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktive App</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Neue Informationen"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive Apps"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopiert"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Von <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Kopieren-Benutzeroberfläche schließen"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Kopierten Text bearbeiten"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Kopiertes Bild bearbeiten"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"An Gerät in der Nähe senden"</string>
+    <string name="add" msgid="81036585205287996">"Hinzufügen"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Nutzer verwalten"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Diese Benachrichtigung lässt sich nicht auf einen geteilten Bildschirm ziehen."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WLAN nicht verfügbar"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritätsmodus"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wecker gestellt"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant-Gastmodus aktiviert"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera und Mikrofon ausgeschaltet"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 6096749..dc0d98b 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI συστήματ."</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Η μπαταρία μπορεί να εξαντληθεί σύντομα"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Απομένουν <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Δεν είναι δυνατή η φόρτιση μέσω USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Χρησιμοποιήστε τον φορτιστή που συνοδεύει τη συσκευή σας"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Έγινε έλεγχος ταυτότητας προσώπου"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Επιβεβαιώθηκε"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Πατήστε Επιβεβαίωση για ολοκλήρωση"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Κλείσιμο"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"πλήρης σίγαση"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"μόνο ξυπνητήρια"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Μην ενοχλείτε."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Ενεργό Bluetooth."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Το ξυπνητήρι έχει οριστεί στις <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Επιδόρπιο"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Προφύλαξη οθόνης"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Μην ενοχλείτε"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Δεν υπάρχουν διαθέσιμες συσκευές σε σύζευξη"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Ειδοποιήσεις"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Συζητήσεις"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Διαγραφή όλων των ειδοποιήσεων σε σίγαση"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία \"Μην ενοχλείτε\""</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Κατάσταση:&lt;/b&gt; Κατατάχθηκε χαμηλότερα"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Εμφανίζεται στην κορυφή των ειδοποιήσεων συζήτησης και ως φωτογραφία προφίλ στην οθόνη κλειδώματος"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Εμφανίζεται στην κορυφή των ειδοποιήσεων συζήτησης και ως φωτογραφία προφίλ στην οθόνη κλειδώματος, εμφανίζεται ως συννεφάκι"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Εμφανίζεται στην κορυφή των ειδοποιήσεων συζήτησης και ως φωτογραφία προφίλ στην οθόνη κλειδώματος, διακόπτει τη λειτουργία Μην ενοχλείτε"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Εμφανίζεται στην κορυφή των ειδοποιήσεων συζήτησης και ως φωτογραφία προφίλ στην οθόνη κλειδώματος, εμφανίζεται ως συννεφάκι, διακόπτει τη λειτουργία Μην ενοχλείτε"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Μουσική"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Ημερολόγιο"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Μην ενοχλείτε"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Συντόμευση κουμπιών έντασης ήχου"</string>
     <string name="battery" msgid="769686279459897127">"Μπαταρία"</string>
     <string name="headset" msgid="4485892374984466437">"Ακουστικά"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Το Wi-Fi είναι ανενεργό"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Το Bluetooth είναι ανενεργό"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Η λειτουργία \"Μην ενοχλείτε\" είναι ανενεργή"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από έναν αυτόματο κανόνα (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από μια εφαρμογή (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Η λειτουργία \"Μην ενοχλείτε\" ενεργοποιήθηκε από έναν αυτόματο κανόνα ή μια εφαρμογή."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Εφαρμογές που εκτελούνται στο παρασκήνιο"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Πατήστε για λεπτομέρειες σχετικά με τη χρήση μπαταρίας και δεδομένων"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Απενεργοποίηση δεδομένων κινητής τηλεφωνίας;"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(εργασία)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Τηλεφωνική κλήση"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(μέσω <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"κάμερα"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"τοποθεσία"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"μικρόφωνο"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(αποσυνδέθηκε)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Δεν είναι δυνατή η εναλλαγή. Πατήστε για επανάληψη."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Σύζευξη νέας συσκευής"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Για μετάδοση της περιόδου σύνδεσης, ανοίξτε την εφαρμογή."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Άγνωστη εφαρμογή"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string>
     <string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Δείτε πρόσφατα μηνύματα, αναπάντητες κλήσεις και ενημερώσεις κατάστασης"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Συνομιλία"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Σε παύση από τη λειτουργία Μην ενοχλείτε"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"Ο χρήστης <xliff:g id="NAME">%1$s</xliff:g> έστειλε ένα μήνυμα: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"Ο χρήστης <xliff:g id="NAME">%1$s</xliff:g> έστειλε μια εικόνα"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"Ο χρήστης <xliff:g id="NAME">%1$s</xliff:g> έχει μια ενημέρωση κατάστασης: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Νέες πληροφορίες"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ενεργές εφαρμογές"</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>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Αντιγράφηκε"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Από <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Παράβλεψη διεπαφής χρήστη αντιγραφής"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Επεξεργασία αντιγραμμένου κειμένου"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Επεξεργασία αντιγραμμένης εικόνας"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Αποστολή σε κοντινή συσκευή"</string>
+    <string name="add" msgid="81036585205287996">"Προσθήκη"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Διαχείριση χρηστών"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Αυτή η ειδοποίηση δεν υποστηρίζει τη μεταφορά με σύρσιμο για χρήση του διαχωρισμού οθόνης."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Το Wi‑Fi δεν είναι διαθέσιμο"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Λειτουργία προτεραιότητας"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Το ξυπνητήρι ρυθμίστηκε"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Η λειτουργία επισκέπτη του Βοηθού ενεργοποιήθηκε"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Η κάμερα και το μικρόφωνο έχουν απενεργοποιηθεί"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ειδοποίηση}other{# ειδοποιήσεις}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index f6dc314..fcbe0a6 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -20,7 +20,9 @@
 <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">"System UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Battery may run out soon"</string>
+    <string name="battery_low_title" msgid="5319680173344341779">"Turn on Battery Saver?"</string>
+    <string name="battery_low_description" msgid="3282977755476423966">"You have <xliff:g id="PERCENTAGE">%s</xliff:g> battery left. Battery Saver turns on Dark theme, restricts background activity and delays notifications."</string>
+    <string name="battery_low_intro" msgid="5148725009653088790">"Battery Saver turns on Dark theme, restricts background activity and delays notifications."</string>
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> remaining"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Can\'t charge via USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Use the charger that came with your device"</string>
@@ -128,6 +130,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -181,6 +185,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"total silence"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alarms only"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Do Not Disturb."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth on."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm set for <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +210,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string>
@@ -348,6 +354,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
@@ -491,6 +498,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; ranked lower"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Shows at the top of conversation notifications and as a profile picture on lock screen"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Shows at the top of conversation notifications and as a profile picture on lock screen, interrupts Do Not Disturb"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
@@ -566,6 +575,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
     <string name="battery" msgid="769686279459897127">"Battery"</string>
     <string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +694,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps running in background"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tap for details on battery and data usage"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Turn off mobile data?"</string>
@@ -708,6 +722,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(work)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(through <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
@@ -806,6 +822,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -839,6 +857,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"See recent messages, missed calls and status updates"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Paused by Do Not Disturb"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sent a message: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +896,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> active apps</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> active app</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</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>
@@ -889,8 +907,18 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string>
-    <!-- no translation found for add (81036585205287996) -->
+    <string name="add" msgid="81036585205287996">"Add"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Manage users"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string>
+    <!-- no translation found for dream_overlay_status_bar_wifi_off (4497069245055003582) -->
     <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <!-- no translation found for dream_overlay_status_bar_priority_mode (5428462123314728739) -->
     <skip />
+    <!-- no translation found for dream_overlay_status_bar_alarm_set (566707328356590886) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_assistant_guest_mode_enabled (3715897096012469615) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_camera_mic_off (3199425257833773569) -->
+    <skip />
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 0b4e009..2e6514a 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -20,7 +20,9 @@
 <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">"System UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Battery may run out soon"</string>
+    <string name="battery_low_title" msgid="5319680173344341779">"Turn on Battery Saver?"</string>
+    <string name="battery_low_description" msgid="3282977755476423966">"You have <xliff:g id="PERCENTAGE">%s</xliff:g> battery left. Battery Saver turns on Dark theme, restricts background activity and delays notifications."</string>
+    <string name="battery_low_intro" msgid="5148725009653088790">"Battery Saver turns on Dark theme, restricts background activity and delays notifications."</string>
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> remaining"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Can\'t charge via USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Use the charger that came with your device"</string>
@@ -128,6 +130,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -181,6 +185,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"total silence"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alarms only"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Do Not Disturb."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth on."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm set for <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +210,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string>
@@ -348,6 +354,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
@@ -491,6 +498,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; ranked lower"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Shows at the top of conversation notifications and as a profile picture on lock screen"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Shows at the top of conversation notifications and as a profile picture on lock screen, interrupts Do Not Disturb"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
@@ -566,6 +575,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
     <string name="battery" msgid="769686279459897127">"Battery"</string>
     <string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +694,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps running in background"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tap for details on battery and data usage"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Turn off mobile data?"</string>
@@ -708,6 +722,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(work)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(through <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
@@ -806,6 +822,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -839,6 +857,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"See recent messages, missed calls and status updates"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Paused by Do Not Disturb"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sent a message: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +896,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> active apps</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> active app</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</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>
@@ -889,8 +907,18 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string>
-    <!-- no translation found for add (81036585205287996) -->
+    <string name="add" msgid="81036585205287996">"Add"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Manage users"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string>
+    <!-- no translation found for dream_overlay_status_bar_wifi_off (4497069245055003582) -->
     <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <!-- no translation found for dream_overlay_status_bar_priority_mode (5428462123314728739) -->
     <skip />
+    <!-- no translation found for dream_overlay_status_bar_alarm_set (566707328356590886) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_assistant_guest_mode_enabled (3715897096012469615) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_camera_mic_off (3199425257833773569) -->
+    <skip />
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index f6dc314..fcbe0a6 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -20,7 +20,9 @@
 <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">"System UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Battery may run out soon"</string>
+    <string name="battery_low_title" msgid="5319680173344341779">"Turn on Battery Saver?"</string>
+    <string name="battery_low_description" msgid="3282977755476423966">"You have <xliff:g id="PERCENTAGE">%s</xliff:g> battery left. Battery Saver turns on Dark theme, restricts background activity and delays notifications."</string>
+    <string name="battery_low_intro" msgid="5148725009653088790">"Battery Saver turns on Dark theme, restricts background activity and delays notifications."</string>
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> remaining"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Can\'t charge via USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Use the charger that came with your device"</string>
@@ -128,6 +130,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -181,6 +185,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"total silence"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alarms only"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Do Not Disturb."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth on."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm set for <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +210,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string>
@@ -348,6 +354,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
@@ -491,6 +498,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; ranked lower"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Shows at the top of conversation notifications and as a profile picture on lock screen"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Shows at the top of conversation notifications and as a profile picture on lock screen, interrupts Do Not Disturb"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
@@ -566,6 +575,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
     <string name="battery" msgid="769686279459897127">"Battery"</string>
     <string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +694,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps running in background"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tap for details on battery and data usage"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Turn off mobile data?"</string>
@@ -708,6 +722,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(work)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(through <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
@@ -806,6 +822,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -839,6 +857,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"See recent messages, missed calls and status updates"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Paused by Do Not Disturb"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sent a message: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +896,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> active apps</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> active app</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</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>
@@ -889,8 +907,18 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string>
-    <!-- no translation found for add (81036585205287996) -->
+    <string name="add" msgid="81036585205287996">"Add"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Manage users"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string>
+    <!-- no translation found for dream_overlay_status_bar_wifi_off (4497069245055003582) -->
     <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <!-- no translation found for dream_overlay_status_bar_priority_mode (5428462123314728739) -->
     <skip />
+    <!-- no translation found for dream_overlay_status_bar_alarm_set (566707328356590886) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_assistant_guest_mode_enabled (3715897096012469615) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_camera_mic_off (3199425257833773569) -->
+    <skip />
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index f6dc314..fcbe0a6 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -20,7 +20,9 @@
 <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">"System UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Battery may run out soon"</string>
+    <string name="battery_low_title" msgid="5319680173344341779">"Turn on Battery Saver?"</string>
+    <string name="battery_low_description" msgid="3282977755476423966">"You have <xliff:g id="PERCENTAGE">%s</xliff:g> battery left. Battery Saver turns on Dark theme, restricts background activity and delays notifications."</string>
+    <string name="battery_low_intro" msgid="5148725009653088790">"Battery Saver turns on Dark theme, restricts background activity and delays notifications."</string>
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> remaining"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Can\'t charge via USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Use the charger that came with your device"</string>
@@ -128,6 +130,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -181,6 +185,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"total silence"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alarms only"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Do Not Disturb."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth on."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm set for <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +210,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Do Not Disturb"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No paired devices available"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string>
@@ -348,6 +354,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
@@ -491,6 +498,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; ranked lower"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Shows at the top of conversation notifications and as a profile picture on lock screen"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Shows at the top of conversation notifications and as a profile picture on lock screen, interrupts Do Not Disturb"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
@@ -566,6 +575,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
     <string name="battery" msgid="769686279459897127">"Battery"</string>
     <string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +694,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is off"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is off"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Do Not Disturb is off"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Do Not Disturb was turned on by an automatic rule or app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps running in background"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tap for details on battery and data usage"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Turn off mobile data?"</string>
@@ -708,6 +722,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(work)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Phone call"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(through <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
@@ -806,6 +822,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -839,6 +857,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"See recent messages, missed calls and status updates"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Paused by Do Not Disturb"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sent a message: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> has a status update: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +896,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> active apps</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> active app</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</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>
@@ -889,8 +907,18 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string>
-    <!-- no translation found for add (81036585205287996) -->
+    <string name="add" msgid="81036585205287996">"Add"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Manage users"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string>
+    <!-- no translation found for dream_overlay_status_bar_wifi_off (4497069245055003582) -->
     <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <!-- no translation found for dream_overlay_status_bar_priority_mode (5428462123314728739) -->
     <skip />
+    <!-- no translation found for dream_overlay_status_bar_alarm_set (566707328356590886) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_assistant_guest_mode_enabled (3715897096012469615) -->
+    <skip />
+    <!-- no translation found for dream_overlay_status_bar_camera_mic_off (3199425257833773569) -->
+    <skip />
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 18d87f3..f05e75b 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -20,7 +20,9 @@
 <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">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‎System UI‎‏‎‎‏‎"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‎Battery may run out soon‎‏‎‎‏‎"</string>
+    <string name="battery_low_title" msgid="5319680173344341779">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎Turn on Battery Saver?‎‏‎‎‏‎"</string>
+    <string name="battery_low_description" msgid="3282977755476423966">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‎‎You have ‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%s</xliff:g>‎‏‎‎‏‏‏‎ battery left. Battery Saver turns on Dark theme, restricts background activity, and delays notifications.‎‏‎‎‏‎"</string>
+    <string name="battery_low_intro" msgid="5148725009653088790">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎Battery Saver turns on Dark theme, restricts background activity, and delays notifications.‎‏‎‎‏‎"</string>
     <string name="battery_low_percent_format" msgid="4276661262843170964">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%s</xliff:g>‎‏‎‎‏‏‏‎ remaining‎‏‎‎‏‎"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎Can\'t charge via USB‎‏‎‎‏‎"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎Use the charger that came with your device‎‏‎‎‏‎"</string>
@@ -128,6 +130,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎Face authenticated‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎Confirmed‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎Tap Confirm to complete‎‏‎‎‏‎"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎Authenticated‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‏‎Use PIN‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎Use pattern‎‏‎‎‏‎"</string>
@@ -181,6 +185,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎Close‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎total silence‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎alarms only‎‏‎‎‏‎"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‎Do Not Disturb.‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎Bluetooth.‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‏‎Bluetooth on.‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‏‎‎Alarm set for ‎‏‎‎‏‏‎<xliff:g id="TIME">%s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
@@ -205,6 +210,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎Dessert Case‎‏‎‎‏‎"</string>
     <string name="start_dreams" msgid="9131802557946276718">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‏‏‏‎‎Screen saver‎‏‎‎‏‎"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎Ethernet‎‏‎‎‏‎"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‎Do Not Disturb‎‏‎‎‏‎"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‎Bluetooth‎‏‎‎‏‎"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‎‎‏‎‎No paired devices available‎‏‎‎‏‎"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>‎‏‎‎‏‏‏‎ battery‎‏‎‎‏‎"</string>
@@ -348,6 +354,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎Notifications‎‏‎‎‏‎"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎Conversations‎‏‎‎‏‎"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎Clear all silent notifications‎‏‎‎‏‎"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎Notifications paused by Do Not Disturb‎‏‎‎‏‎"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‎Start now‎‏‎‎‏‎"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‏‎‎‎No notifications‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎This device is managed by your parent‎‏‎‎‏‎"</string>
@@ -491,6 +498,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‏‎‏‎‎‎&lt;b&gt;Status:&lt;/b&gt; Ranked Lower‎‏‎‎‏‎"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎Shows at the top of conversation notifications and as a profile picture on lock screen‎‏‎‎‏‎"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‎‎Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble‎‏‎‎‏‎"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‏‎Shows at the top of conversation notifications and as a profile picture on lock screen, interrupts Do Not Disturb‎‏‎‎‏‎"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb‎‏‎‎‏‎"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎Priority‎‏‎‎‏‎"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ doesn’t support conversation features‎‏‎‎‏‎"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎These notifications can\'t be modified.‎‏‎‎‏‎"</string>
@@ -566,6 +575,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‎SMS‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‎Music‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎‏‎Calendar‎‏‎‎‏‎"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‎Do Not Disturb‎‏‎‎‏‎"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎Volume buttons shortcut‎‏‎‎‏‎"</string>
     <string name="battery" msgid="769686279459897127">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎Battery‎‏‎‎‏‎"</string>
     <string name="headset" msgid="4485892374984466437">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‎‎‏‎‏‎Headset‎‏‎‎‏‎"</string>
@@ -684,6 +694,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="CARRIER_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‏‎Wi-Fi is off‎‏‎‎‏‎"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‎Bluetooth is off‎‏‎‎‏‎"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎Do Not Disturb is off‎‏‎‎‏‎"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎Do Not Disturb was turned on by an automatic rule (‎‏‎‎‏‏‎<xliff:g id="ID_1">%s</xliff:g>‎‏‎‎‏‏‏‎).‎‏‎‎‏‎"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎Do Not Disturb was turned on by an app (‎‏‎‎‏‏‎<xliff:g id="ID_1">%s</xliff:g>‎‏‎‎‏‏‏‎).‎‏‎‎‏‎"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎Do Not Disturb was turned on by an automatic rule or app.‎‏‎‎‏‎"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎Apps running in background‎‏‎‎‏‎"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎Tap for details on battery and data usage‎‏‎‎‏‎"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎Turn off mobile data?‎‏‎‎‏‎"</string>
@@ -708,6 +722,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎(work)‎‏‎‎‏‎"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎Phone call‎‏‎‎‏‎"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎(through ‎‏‎‎‏‏‎<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>‎‏‎‎‏‏‏‎)‎‏‎‎‏‎"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎(‎‏‎‎‏‏‎<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>‎‏‎‎‏‏‏‎)‎‏‎‎‏‎"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‎‎‏‎(‎‏‎‎‏‏‎<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ • ‎‏‎‎‏‏‎<xliff:g id="PROXY_LABEL">%2$s</xliff:g>‎‏‎‎‏‏‏‎)‎‏‎‎‏‎"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎camera‎‏‎‎‏‎"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎location‎‏‎‎‏‎"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‎microphone‎‏‎‎‏‎"</string>
@@ -806,6 +822,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎(disconnected)‎‏‎‎‏‎"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎Can\'t switch. Tap to try again.‎‏‎‎‏‎"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‎Pair new device‎‏‎‎‏‎"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎To cast this session, please open the app.‎‏‎‎‏‎"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎Unknown app‎‏‎‎‏‎"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎Build number‎‏‎‎‏‎"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎Build number copied to clipboard.‎‏‎‎‏‎"</string>
     <string name="basic_status" msgid="2315371112182658176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎Open conversation‎‏‎‎‏‎"</string>
@@ -839,6 +857,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="NUMBER">%d</xliff:g>‎‏‎‎‏‏‏‎+‎‏‎‎‏‎"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‎‎‎‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎See recent messages, missed calls, and status updates‎‏‎‎‏‎"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‎‎‎Conversation‎‏‎‎‏‎"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎Paused by Do Not Disturb‎‏‎‎‏‎"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ sent a message: ‎‏‎‎‏‏‎<xliff:g id="NOTIFICATION">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ sent an image‎‏‎‎‏‎"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ has a status update: ‎‏‎‎‏‏‎<xliff:g id="STATUS">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
@@ -890,4 +909,11 @@
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‎‎‏‎‎Send to nearby device‎‏‎‎‏‎"</string>
     <string name="add" msgid="81036585205287996">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‎Add‎‏‎‎‏‎"</string>
     <string name="manage_users" msgid="1823875311934643849">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‎Manage users‎‏‎‎‏‎"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎This notification does not support dragging to Splitscreen.‎‏‎‎‏‎"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‎Wi‑Fi unavailable‎‏‎‎‏‎"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎Priority mode‎‏‎‎‏‎"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎‎Alarm set‎‏‎‎‏‎"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎Assistant guest mode enabled‎‏‎‎‏‎"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎Camera and mic are off‎‏‎‎‏‎"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notification‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notifications‎‏‎‎‏‎}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3f1cc42..4363ce9 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -20,7 +20,12 @@
 <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">"IU del sistema"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Es posible que pronto se agote la batería"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> de batería."</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"No se puede cargar mediante USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Usa el cargador que se incluyó con el dispositivo"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Se autenticó el rostro"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmado"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Presiona Confirmar para completar"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Cerrar"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silencio total"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"solo alarmas"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"No interrumpir."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activado"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarma: <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Caja para postres"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Protector pantalla"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"No interrumpir"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No hay dispositivos sincronizados disponibles"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificaciones"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas las notificaciones silenciosas"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificaciones pausadas por el modo \"No interrumpir\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Comenzar ahora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tu padre o madre administra este dispositivo"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Estado:&lt;/b&gt; Se clasificó en una posición inferior"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Aparece como foto de perfil en la parte superior de las notificaciones de conversación, en la pantalla de bloqueo"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Aparece en forma de burbuja y como foto de perfil en la parte superior de las notificaciones de conversación, en la pantalla de bloqueo"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Aparece como foto de perfil en la parte superior de las notificaciones de conversación, en la pantalla de bloqueo, y detiene el modo No interrumpir"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece en forma de burbuja y como foto de perfil en la parte superior de las notificaciones de conversación, en la pantalla de bloqueo, y detiene el modo No interrumpir"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritaria"</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">"No se pueden modificar estas notificaciones."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <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 interrumpir"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Combinación de teclas de botones de volumen"</string>
     <string name="battery" msgid="769686279459897127">"Batería"</string>
     <string name="headset" msgid="4485892374984466437">"Auriculares"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi desactivado"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desactivado"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"No interrumpir desactivado"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Se activó el modo No interrumpir con una regla automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Se activó el modo No interrumpir con una app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Se activó el modo No interrumpir con una app o regla automática."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps que se ejecutan en segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Presiona para obtener información sobre el uso de datos y de la batería"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"¿Deseas desactivar los datos móviles?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabajo)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Llamada telefónica"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(a través de <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"cámara"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ubicación"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"micrófono"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No se pudo conectar. Presiona para volver a intentarlo."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo nuevo"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sesión, abre la app"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconocida"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g> o más"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Consulta mensajes recientes, llamadas perdidas y actualizaciones de estado"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversación"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Se detuvo por el modo No interrumpir"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> envió un mensaje: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> envió una imagen"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> actualizó su estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps activas</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app activa</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nueva información"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps activas"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Detener"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Detenida"</string>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Se copió"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"De <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Descartar la copia de la IU"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar el texto copiado"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar la imagen copiada"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar a dispositivos cercanos"</string>
+    <string name="add" msgid="81036585205287996">"Agregar"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Administrar usuarios"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación no admite arrastrar entre pantallas divididas."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"La red Wi-Fi no está disponible"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo prioridad"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Se estableció la alarma"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Se habilitó el Modo de Invitado de Asistente"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están apagados"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificaciones}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index b84ed65..0e7be44 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI del sistema"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Puede que te quedes sin batería pronto"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> de batería"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"No se puede cargar por USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Utiliza el cargador original incluido con el dispositivo"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Cara autenticada"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Cerrar"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silencio total"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"solo alarmas"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"No molestar."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activado."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"La alarma sonará a la(s) <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Caja para postres"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Salvapantallas"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"No molestar"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No hay dispositivos vinculados disponibles"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificaciones"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas las notificaciones silenciosas"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificaciones pausadas por el modo No molestar"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Empezar ahora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo lo gestionan tu padre o tu madre"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Estado:&lt;/b&gt; posición más baja"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Se muestra encima de las notificaciones de conversaciones y como imagen de perfil en la pantalla de bloqueo"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Se muestra encima de las notificaciones de conversaciones y como imagen de perfil en la pantalla de bloqueo, y aparece como burbuja"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Se muestra encima de las notificaciones de conversaciones y como imagen de perfil en la pantalla de bloqueo, e interrumpe el modo No molestar"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Se muestra encima de las notificaciones de conversaciones y como imagen de perfil en la pantalla de bloqueo, aparece como burbuja e interrumpe el modo No molestar"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <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="battery" msgid="769686279459897127">"Batería"</string>
     <string name="headset" msgid="4485892374984466437">"Auriculares"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi desactivado"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desactivado"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"No molestar está desactivado"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Una regla automática (<xliff:g id="ID_1">%s</xliff:g>) ha activado No molestar."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Una aplicación (<xliff:g id="ID_1">%s</xliff:g>) ha activado No molestar."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Una aplicación o una regla automática han activado No molestar."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplicaciones que se están ejecutando en segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Toca para ver información detallada sobre el uso de datos y de la batería"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"¿Desactivar datos móviles?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabajo)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Llamada telefónica"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(a través de <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"cámara"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ubicación"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"micrófono"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No se puede cambiar. Toca para volver a intentarlo."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Emparejar nuevo dispositivo"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para enviar esta sesión, abre la aplicación."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación desconocida"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número de compilación copiado en el portapapeles."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Consulta los mensajes recientes, las llamadas perdidas y los cambios de estado"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversación"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Pausado por No molestar"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ha enviado un mensaje: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha enviado una imagen"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ha cambiado su estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplicaciones activas</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicación activa</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Información nueva"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicaciones activas"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Detener"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Detenida"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Cerrar la interfaz de copia"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagen copiada"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar a dispositivo cercano"</string>
+    <string name="add" msgid="81036585205287996">"Añadir"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Gestionar usuarios"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación no se puede arrastrar a la pantalla dividida."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi no disponible"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo prioritario"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma añadida"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modo invitado del asistente habilitado"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están desactivados"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 91250c3..0c9d46e 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -20,7 +20,12 @@
 <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">"Süsteemi UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Aku võib peagi tühjaks saada"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Jäänud on <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Ei saa USB kaudu laadida"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Kasutage seadmega kaasas olnud laadijat"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Nägu on autenditud"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Sulgemine"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"täielik vaikus"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ainult alarmid"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Mitte segada."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth on sees."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Määratud äratus: <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Maiustusekorv"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Ekraanisäästja"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Mitte segada"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ühtegi seotud seadet pole saadaval"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> akut"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Märguanded"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Vestlused"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Kustuta kõik hääletud märguanded"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Režiim Mitte segada peatas märguanded"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Alusta kohe"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Märguandeid pole"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Seda seadet haldab sinu vanem"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Olek:&lt;/b&gt; määrati madalam prioriteet"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Kuvatakse vestluste märguannete ülaosas ja profiilipildina lukustuskuval"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Kuvatakse mullina vestluste märguannete ülaosas ja profiilipildina lukustuskuval"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Kuvatakse vestluste märguannete ülaosas ja profiilipildina lukustuskuval ning katkestab režiimi Mitte segada"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Kuvatakse mullina vestluste märguannete ülaosas ja profiilipildina lukustuskuval ning katkestab režiimi Mitte segada"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muusika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Mitte segada"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Helitugevuse nuppude otsetee"</string>
     <string name="battery" msgid="769686279459897127">"Aku"</string>
     <string name="headset" msgid="4485892374984466437">"Peakomplekt"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"WiFi on välja lülitatud"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth on välja lülitatud"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Funktsioon Mitte segada on välja lülitatud"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automaatne reegel (<xliff:g id="ID_1">%s</xliff:g>) lülitas funktsiooni Mitte segada sisse."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Rakendus (<xliff:g id="ID_1">%s</xliff:g>) lülitas funktsiooni Mitte segada sisse."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automaatne reegel või rakendus lülitas funktsiooni Mitte segada sisse."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Rakendusi käitatakse taustal"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Aku ja andmekasutuse üksikasjade nägemiseks puudutage"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Kas lülitada mobiilne andmeside välja?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(töö)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonikõne"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(rakenduse <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> kaudu)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kaamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"asukoht"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ühendus on katkestatud)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ei saa lülitada. Puudutage uuesti proovimiseks."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uue seadme sidumine"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Selle seansi ülekandmiseks avage rakendus."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tundmatu rakendus"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string>
     <string name="basic_status" msgid="2315371112182658176">"Avage vestlus"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Vaadake hiljutisi sõnumeid, vastamata kõnesid ja olekuvärskendusi"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Vestlus"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Peatas režiim Mitte segada"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> saatis sõnumi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> saatis pildi"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> värskendas olekut: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktiivset rakendust</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiivne rakendus</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Uus teave"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiivsed rakendused"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Peata"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Peatatud"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopeeritud"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Rakendusest <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Koopiast loobumise kasutajaliides"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Muuda kopeeritud teksti"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Muuda kopeeritud pilti"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Saada läheduses olevasse seadmesse"</string>
+    <string name="add" msgid="81036585205287996">"Lisa"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Kasutajate haldamine"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"See märguanne ei toeta jagatud ekraanikuvale lohistamist."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi pole saadaval"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Režiim Prioriteetne"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm on määratud"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistendi külalisrežiim on lubatud"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kaamera ja mikrofon on välja lülitatud"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index b531794..90d24e5 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -20,7 +20,12 @@
 <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">"Sistemaren interfazea"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Laster agortuko da bateria"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> gelditzen da"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Ezin da USB bidez kargatu"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Erabili gailuaren kargagailua"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Autentifikatu da aurpegia"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Berretsita"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Amaitzeko, sakatu \"Berretsi\""</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Itxi"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"isiltasun osoa"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alarmak soilik"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ez molestatzeko modua."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth-a."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth bidezko konexioa aktibatuta dago."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarma ordu honetarako ezarri da: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Postreen kutxa"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Pantaila-babeslea"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ez molestatzeko modua"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth-a"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ez dago parekatutako gailurik erabilgarri"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Jakinarazpenak"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Elkarrizketak"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Garbitu soinurik gabeko jakinarazpen guztiak"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ez molestatzeko moduak pausatu egin ditu jakinarazpenak"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Hasi"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ez dago jakinarazpenik"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Zure gurasoak kudeatzen du gailua"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"Mailaz jaitsi da &lt;b&gt;egoera:&lt;/b&gt;"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Elkarrizketen jakinarazpenen goialdean eta profileko argazki gisa agertzen da pantaila blokeatuan"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Elkarrizketen jakinarazpenen goialdean eta profileko argazki gisa agertzen da pantaila blokeatuan, burbuila batean"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Elkarrizketen jakinarazpenen goialdean eta profileko argazki gisa agertzen da pantaila blokeatuan, eta ez molestatzeko modua eteten du"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Elkarrizketen jakinarazpenen goialdean eta profileko argazki gisa agertzen da pantaila blokeatuan, burbuila batean, eta ez molestatzeko modua eteten du"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMSak"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ez molestatzeko modua"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Bolumen-botoietarako lasterbidea"</string>
     <string name="battery" msgid="769686279459897127">"Bateria"</string>
     <string name="headset" msgid="4485892374984466437">"Mikrofonodun entzungailua"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> (<xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>)"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi konexioa desaktibatuta dago"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth bidezko konexioa desaktibatuta dago"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Ez molestatzeko modua desaktibatuta dago"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Ez molestatzeko modua aktibatu du arau automatiko batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Ez molestatzeko modua aktibatu du aplikazio batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Ez molestatzeko modua aktibatu du arau automatiko edo aplikazio batek."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikazioak abian dira atzeko planoan"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Sakatu bateria eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Datu-konexioa desaktibatu nahi duzu?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(lanekoa)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefono-deia"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> aplikazioaren bidez)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"kokapena"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonoa"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(deskonektatuta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ezin da aldatu. Berriro saiatzeko, sakatu hau."</string>
     <string name="media_output_dialog_pairing_new" msgid="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="build_number_clip_data_label" msgid="3623176728412560914">"Konpilazio-zenbakia"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string>
     <string name="basic_status" msgid="2315371112182658176">"Elkarrizketa irekia"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Ikusi azken mezuak, dei galduak eta egoerari buruzko informazio eguneratua"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Elkarrizketa"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Ez molestatzeko moduak pausatu du"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak mezu bat bidali du: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak irudi bat bidali du"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak egoera eguneratu du: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikazio aktibo</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikazio aktibo</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informazio berria"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktibo dauden aplikazioak"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Gelditu"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Geldituta"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopiatu da"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Jatorria: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Kopiatutako UIa baztertzeko botoia"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editatu kopiatutako testua"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editatu kopiatutako irudia"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Bidali inguruko gailu batera"</string>
+    <string name="add" msgid="81036585205287996">"Gehitu"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Kudeatu erabiltzaileak"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Jakinarazpen hau ezin da arrastatu pantaila zatitura."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi-konexioa ez dago erabilgarri"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Lehentasun modua"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma ezarrita dago"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Laguntzailea zerbitzuaren gonbidatu modua gaituta dago"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera eta mikrofonoa desaktibatuta daude"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 642a826..99e214b 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"ممکن است باتری به‌زودی تمام شود"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> باقی مانده است"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"‏ازطریق USB شارژ نمی‌شود"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"از شارژر ارائه‌شده با دستگاه استفاده کنید"</string>
@@ -111,7 +116,7 @@
     <string name="accessibility_phone_button" msgid="4256353121703100427">"تلفن"</string>
     <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"دستیار صوتی"</string>
     <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
-    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"اسکنر رمزینه پاسخ‌سریع"</string>
+    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"کدخوان پاسخ‌سریع"</string>
     <string name="accessibility_unlock_button" msgid="122785427241471085">"باز کردن قفل"</string>
     <string name="accessibility_lock_icon" msgid="661492842417875775">"دستگاه قفل است"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"درحال اسکن کردن چهره"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"چهره اصالت‌سنجی شد"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تأیید شد"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"برای تکمیل، روی تأیید ضربه بزنید"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"بستن"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"سکوت کامل"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"فقط زنگ ساعت"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"مزاحم نشوید."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"بلوتوث."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"بلوتوث روشن است."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"زنگ برای <xliff:g id="TIME">%s</xliff:g> تنظیم شد."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"ویترین دسر"</string>
     <string name="start_dreams" msgid="9131802557946276718">"محافظ صفحه"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"اترنت"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"مزاحم نشوید"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"بلوتوث"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"هیچ دستگاه مرتبط شده‌ای موجود نیست"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"شارژ باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"اعلان‌ها"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"مکالمه‌ها"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"پاک کردن همه اعلان‌های بی‌صدا"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"اعلان‌ها توسط «مزاحم نشوید» موقتاً متوقف شدند"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"‏&lt;b&gt;وضعیت:&lt;/b&gt; در رده‌بندی پایین‌تری قرار گرفت"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"در بالای اعلان‌های مکالمه و به‌صورت عکس نمایه در صفحه قفل نشان داده می‌شود"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"در بالای اعلان‌های مکالمه و به‌صورت عکس نمایه در صفحه قفل نشان داده می‌شود، به‌صورت حبابک ظاهر می‌شود"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"در بالای اعلان‌های مکالمه و به‌صورت عکس نمایه در صفحه قفل نشان داده می‌شود، در حالت «مزاحم نشوید» وقفه ایجاد می‌کند"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"در بالای اعلان‌های مکالمه و به‌صورت عکس نمایه در صفحه قفل نشان داده می‌شود، به‌صورت حبابک ظاهر می‌شود، در حالت «مزاحم نشوید» وقفه ایجاد می‌کند"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"پیامک"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"موسیقی"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"تقویم"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"مزاحم نشوید"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"میان‌بر دکمه‌های صدا"</string>
     <string name="battery" msgid="769686279459897127">"باتری"</string>
     <string name="headset" msgid="4485892374984466437">"هدست"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>، <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"‏Wi-Fi خاموش است"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"بلوتوث خاموش است"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"«مزاحم نشوید» خاموش است"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"قانون خودکاری (<xliff:g id="ID_1">%s</xliff:g>) «مزاحم نشوید» را روشن کرد."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"برنامه‌ای (<xliff:g id="ID_1">%s</xliff:g>) «مزاحم نشوید» را روشن کرد."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"برنامه یا قانون خودکاری، «مزاحم نشوید» را روشن کرد."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"برنامه‌هایی که در پس‌زمینه اجرا می‌شوند"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"برای جزئیات مربوط به مصرف باتری و داده، ضربه بزنید"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"داده تلفن همراه خاموش شود؟"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(کاری)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"تماس تلفنی"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(ازطریق <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"دوربین"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"مکان"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"میکروفون"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(اتصال قطع شد)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"عوض نمی‌شود. برای تلاش مجدد ضربه بزنید."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"مرتبط کردن دستگاه جدید"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"برای ارسال محتوای این جلسه، لطفاً برنامه را باز کنید."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"برنامه ناشناس"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریده‌دان کپی شد."</string>
     <string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"بیش‌از <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"دیدن به‌روزرسانی‌های وضعیت، تماس‌های بی‌پاسخ، و پیام‌های اخیر"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"مکالمه"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"با «مزاحم نشوید» موقتاً متوقف شده است"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> پیامی ارسال کرد: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> تصویری ارسال کرد"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> وضعیتش را به‌روزرسانی کرد: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"اطلاعات جدید"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"برنامه‌های فعال"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"کپی شد"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"از <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"رد کردن رابط کاربری کپی کردن"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"ویرایش نوشتار کپی‌شده"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ویرایش تصویر کپی‌شده"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ارسال به دستگاهی در اطراف"</string>
+    <string name="add" msgid="81036585205287996">"افزودن"</string>
+    <string name="manage_users" msgid="1823875311934643849">"مدیریت کاربران"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"این اعلان از تنظیم کشیدن برای دو نیمه کردن صفحه پشتیبانی نمی‌کند."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi‑Fi دردسترس نیست"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"حالت اولویت"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"زنگ ساعت تنظیم شد"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"«حالت مهمان» «دستیار» فعال شد"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"دوربین و میکروفون خاموش هستند"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index a9c11bc..5aca1ce 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -20,7 +20,12 @@
 <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">"Käyttöliitt."</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Akku voi loppua pian"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> jäljellä"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Lataaminen USB:llä ei onnistu"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Käytä laitteesi mukana tullutta laturia"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Kasvot tunnistettu"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Vahvistettu"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Valitse lopuksi Vahvista"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Todennettu"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Käytä PIN-koodia"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Käytä kuviota"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Sulje"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"hiljennä kaikki"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"vain herätykset"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Älä häiritse."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth on päällä."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Hälytys asetettu, aika: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Jälkiruokavitriini"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Näytönsäästäjä"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Älä häiritse"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Laitepareja ei ole käytettävissä"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Ilmoitukset"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Keskustelut"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Tyhjennä kaikki hiljaiset ilmoitukset"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Älä häiritse ‑tila keskeytti ilmoitukset"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Aloita nyt"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ei ilmoituksia"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Vanhempasi ylläpitää tätä laitetta"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Tila:&lt;/b&gt; valittu vähemmän tärkeäksi"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Näkyy keskusteluilmoitusten yläosassa ja profiilikuvana lukitusnäytöllä"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Näkyy keskusteluilmoitusten yläosassa ja profiilikuvana lukitusnäytöllä, näkyy kuplana"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Näkyy keskusteluilmoitusten yläosassa ja profiilikuvana lukitusnäytöllä, keskeyttää Älä häiritse ‑tilan"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Näkyy keskusteluilmoitusten yläosassa ja profiilikuvana lukitusnäytöllä, näkyy kuplana, keskeyttää Älä häiritse ‑tilan"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Tärkeä"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei tue keskusteluominaisuuksia"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Näitä ilmoituksia ei voi muokata"</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Tekstiviesti"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiikki"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalenteri"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Älä häiritse"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Äänenvoimakkuuspainikkeiden pikanäppäin"</string>
     <string name="battery" msgid="769686279459897127">"Akku"</string>
     <string name="headset" msgid="4485892374984466437">"Kuulokemikrofoni"</string>
@@ -679,11 +692,15 @@
     <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Sovellus avattiin ilman asennusta. Katso lisätietoja napauttamalla."</string>
     <string name="app_info" msgid="5153758994129963243">"Sovelluksen tiedot"</string>
     <string name="go_to_web" msgid="636673528981366511">"Siirry selaimeen"</string>
-    <string name="mobile_data" msgid="4564407557775397216">"Mobiilitiedonsiirto"</string>
+    <string name="mobile_data" msgid="4564407557775397216">"Mobiilidata"</string>
     <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi on pois päältä"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ei ole käytössä"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Älä häiritse ‑tila on pois päältä"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Automaattinen sääntö otti käyttöön Älä häiritse ‑tilan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Sovellus otti käyttöön Älä häiritse ‑tilan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Automaattinen sääntö tai sovellus otti käyttöön Älä häiritse ‑tilan."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Sovelluksia käynnissä taustalla"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Katso lisätietoja akun ja datan käytöstä napauttamalla"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Laitetaanko mobiilidata pois päältä?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(työ)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Puhelu"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(kautta: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"sijainti"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoni"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(yhteys katkaistu)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Vaihtaminen ei onnistunut. Yritä uudelleen."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Muodosta uusi laitepari"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jos haluat striimata tämän käyttökerran, avaa sovellus."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tuntematon sovellus"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Koontiversion numero"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Koontiversion numero kopioitu leikepöydälle"</string>
     <string name="basic_status" msgid="2315371112182658176">"Avaa keskustelu"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Yli <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Katso viimeaikaiset viestit, vastaamattomat puhelut ja tilapäivitykset"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Keskustelu"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Älä häiritse ‑tilan keskeyttämä"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> lähetti viestin: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> lähetti kuvan"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> on päivittänyt tilansa: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktiivista sovellusta</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiivinen sovellus</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Uutta tietoa"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiiviset sovellukset"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Lopeta"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Pysäytetty"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopioitu"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Lähde: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Hylkää kopioitu UI"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Muokkaa kopioitua tekstiä"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Muokkaa kopioitua kuvaa"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Lähetä lähellä olevaan laitteeseen"</string>
+    <string name="add" msgid="81036585205287996">"Lisää"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Ylläpidä käyttäjiä"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Ilmoitus ei tue jaetulle näytölle vetämistä."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ei ole saatavilla"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tärkeät-tila"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Hälytys asetettu"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistantin vierastila käytössä"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ja mikrofoni ovat pois päältä"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 3ee8efa..1a599b5 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -20,7 +20,12 @@
 <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">"IU système"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"La pile sera bientôt épuisée"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restants"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Impossible de charger l\'appareil par USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Servez-vous du chargeur fourni avec votre appareil"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Visage authentifié"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Fermer"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"aucune interruption"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alarmes seulement"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne pas déranger."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activé."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarme réglée sur <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Vitrine des desserts"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Écran de veille"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne pas déranger"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Aucun des appareils associés n\'est disponible"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Effacer toutes les notifications silencieuses"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Les notifications sont suspendues par le mode Ne pas déranger"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par ton parent"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;État :&lt;/b&gt; abaissé d\'un niveau"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"S\'affiche dans le haut des notifications de conversation et comme photo de profil à l\'écran de verrouillage"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"S\'affiche dans le haut des notifications de conversation et comme photo de profil à l\'écran de verrouillage, s\'affiche comme bulle"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"S\'affiche dans le haut des notifications de conversation et comme photo de profil à l\'écran de verrouillage, interrompt le mode Ne pas déranger"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"S\'affiche dans le haut des notifications de conversation et comme photo de profil à l\'écran de verrouillage, s\'affiche comme bulle, interrompt le mode Ne pas déranger"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Message texte"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musique"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne pas déranger"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Raccourci des boutons de volume"</string>
     <string name="battery" msgid="769686279459897127">"Pile"</string>
     <string name="headset" msgid="4485892374984466437">"Écouteurs"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Le Wi-Fi est désactivé"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Le Bluetooth est désactivé"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Le mode Ne pas déranger est désactivé"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Le mode Ne pas déranger a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode Ne pas déranger a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode Ne pas déranger a été activé par une règle automatique ou une application."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Applications qui fonctionnent en arrière-plan"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Désactiver les données cellulaires?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(travail)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Appel téléphonique"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(par l\'intermédiaire de <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"appareil photo"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"position"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(déconnecté)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Changement impossible. Touchez pour réessayer."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un autre appareil"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour diffuser cette session, veuillez ouvrir l\'application."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Application inconnue"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de version"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Le numéro de version a été copié dans le presse-papiers."</string>
     <string name="basic_status" msgid="2315371112182658176">"Ouvrir la conversation"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Affichez les messages récents, les appels manqués et les mises à jour d\'état"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Interrompue par la fonctionnalité Ne pas déranger"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé un message : <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé une image"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> a mis à jour son état : <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> application active</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> applications actives</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nouvelle information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Applications actives"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Arrêter"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Arrêtée"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copié"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"À partir de <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignorer la copie de l\'IU"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifier le texte copié"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifier l\'image copiée"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Envoyer à un appareil à proximité"</string>
+    <string name="add" msgid="81036585205287996">"Ajouter"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Gérer les utilisateurs"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Cette notification ne prend pas en charge le partage d\'écran par glissement."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi non disponible"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode priorité"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"L\'alarme a été réglée"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Mode Invité de l\'assistant activé"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"L\'appareil photo et le micro sont désactivés"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 0af35ba..1465bdb 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -20,7 +20,12 @@
 <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">"Interface"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"La batterie est bientôt épuisée"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restants"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Impossible de recharger via USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Utiliser le chargeur d\'origine fourni avec votre appareil"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Visage authentifié"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmé"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Appuyez sur \"Confirmer\" pour terminer"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utiliser un code PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utiliser un schéma"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Fermer"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"aucune interruption"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alarmes uniquement"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne pas déranger."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activé."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarme réglée sur <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Vitrine des desserts"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Économiseur d\'écran"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne pas déranger"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Aucun appareil associé disponible."</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batterie"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Effacer toutes les notifications silencieuses"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications suspendues par le mode Ne pas déranger"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par tes parents"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;État ::&lt;/b&gt; Abaissée d\'un niveau"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"S\'affiche en haut des notifications de conversation et en tant que photo de profil sur l\'écran de verrouillage"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"S\'affiche en haut des notifications de conversation et en tant que photo de profil sur l\'écran de verrouillage, apparaît sous forme de bulle"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"S\'affiche en haut des notifications de conversation et en tant que photo de profil sur l\'écran de verrouillage, interrompt le mode Ne pas déranger"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"S\'affiche en haut des notifications de conversation et en tant que photo de profil sur l\'écran de verrouillage, apparaît sous forme de bulle, interrompt le mode Ne pas déranger"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritaire"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas compatible avec les fonctionnalités de conversation"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Impossible de modifier ces notifications."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musique"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne pas déranger"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Raccourci des boutons de volume"</string>
     <string name="battery" msgid="769686279459897127">"Batterie"</string>
     <string name="headset" msgid="4485892374984466437">"Casque"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi désactivé"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth désactivé"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Mode \"Ne pas déranger\" désactivé"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Le mode \"Ne pas déranger\" a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode \"Ne pas déranger\" a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode \"Ne pas déranger\" a été activé par une règle automatique ou une application."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Applications en cours d\'exécution en arrière-plan"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Appuyer pour obtenir des informations sur l\'utilisation de la batterie et des données"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Désactiver les données mobiles ?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(travail)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Appel téléphonique"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(via <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"l\'appareil photo"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"la position"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"le micro"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(déconnecté)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Impossible de changer. Appuyez pour réessayer."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un nouvel appareil"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour caster cette session, veuillez ouvrir l\'appli."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Appli inconnue"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numéro de build copié dans le presse-papiers."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversation ouverte"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+ de <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Voir les messages récents, les appels manqués et les notifications d\'état"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Mise en pause par Ne pas déranger"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé un message : <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé une image"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> a mis à jour son statut : <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> appli active</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> applis actives</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nouvelles informations"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Applis actives"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Arrêter"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Arrêtée"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copié"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"De <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Désactiver l\'interface de copie"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifier le texte copié"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifier l\'image copiée"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Envoyer à un appareil à proximité"</string>
+    <string name="add" msgid="81036585205287996">"Ajouter"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Gérer les utilisateurs"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Impossible de faire glisser cette notification vers l\'écran partagé."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi non disponible"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode Prioritaire"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme réglée"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Mode Invité activé pour l\'Assistant"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Appareil photo et micro désactivés"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 81efcb5..5faa3df 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -20,7 +20,12 @@
 <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">"IU do sistema"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"A batería pode esgotarse en breve"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restante"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Non se puido realizar a carga por USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Utiliza o cargador que incluía o dispositivo"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Autenticouse a cara"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirmar para completar o proceso"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrón"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Pechar"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silencio total"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"só alarmas"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Modo Non molestar."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth activado."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarma definida para as <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Caixa de sobremesa"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Protector pantalla"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Non molestar"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Non hai dispositivos vinculados dispoñibles"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificacións"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borra todas as notificacións silenciadas"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"O modo Non molestar puxo en pausa as notificacións"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Non hai notificacións"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"O teu pai ou nai xestiona este dispositivo"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Estado:&lt;/b&gt; clasificouse nun nivel inferior"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Móstrase na parte superior das notificacións das conversas e como imaxe do perfil na pantalla de bloqueo"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Móstrase na parte superior das notificacións das conversas e como imaxe do perfil na pantalla de bloqueo, e aparece como unha burbulla"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Móstrase na parte superior das notificacións das conversas e como imaxe do perfil na pantalla de bloqueo, e interrompe o modo Non molestar"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Móstrase na parte superior das notificacións das conversas e como imaxe do perfil na pantalla de bloqueo, aparece como unha burbulla e interrompe o modo Non molestar"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non admite funcións de conversa"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificacións non se poden modificar."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Non molestar"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Atallo dos botóns de volume"</string>
     <string name="battery" msgid="769686279459897127">"Batería"</string>
     <string name="headset" msgid="4485892374984466437">"Auriculares"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"A wifi está desactivada"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"O Bluetooth está desactivado"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"O modo Non molestar está desactivado"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Unha norma automática (<xliff:g id="ID_1">%s</xliff:g>) activou o modo Non molestar."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Unha aplicación (<xliff:g id="ID_1">%s</xliff:g>) activou o modo Non molestar."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Unha aplicación ou norma automática activou o modo Non molestar."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplicacións que se executan en segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Toca para obter información sobre o uso de datos e a batería"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Queres desactivar os datos móbiles?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(traballo)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada de teléfono"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(mediante <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"a cámara"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"a localiz."</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"o micrófono"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Non se puido realizar o cambio. Toca para tentalo de novo."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo novo"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para emitir esta sesión, abre a aplicación."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación descoñecida"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Copiouse o número de compilación no portapapeis."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+ de <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Consulta as mensaxes recentes, as chamadas perdidas e as actualizacións dos estados"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Púxose en pausa debido ao modo Non molestar"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou unha mensaxe: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou unha imaxe"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> cambiou de estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplicacións activas</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicación activa</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nova información"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicacións activas"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Deter"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Detida"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiouse"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"De <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignorar interface de copia"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imaxe copiada"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar a dispositivo próximo"</string>
+    <string name="add" msgid="81036585205287996">"Engadir"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Xestionar usuarios"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación non pode arrastrarse á pantalla dividida."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"A wifi non está dispoñible"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"O modo Convidados do Asistente está activado"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A cámara e o micrófono están desactivados"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 98510d5..763d39d 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -20,7 +20,12 @@
 <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">"સિસ્ટમ UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"બૅટરી ટૂંક સમયમાં સમાપ્ત થશે"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> બાકી"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB મારફતે ચાર્જ કરી શકતા નથી"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"તમારા ઉપકરણ સાથે આવેલ ચાર્જરનો ઉપયોગ કરો"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ચહેરાનું પ્રમાણીકરણ થયું"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"પુષ્ટિ કરી"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"પરીક્ષણ પૂર્ણ કરવા કન્ફર્મ કરોને ટૅપ કરો"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"બંધ કરો"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"બિલકુલ અવાજ નહીં"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"માત્ર અલાર્મ"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ખલેલ પાડશો નહીં."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"બ્લૂટૂથ."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"બ્લૂટૂથ ચાલુ."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> માટે એલાર્મ સેટ કર્યું."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"ડેઝર્ટ કેસ"</string>
     <string name="start_dreams" msgid="9131802557946276718">"સ્ક્રીન સેવર"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ઇથરનેટ"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"ખલેલ પાડશો નહીં"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"બ્લૂટૂથ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"કોઈ જોડી કરેલ ઉપકરણો ઉપલબ્ધ નથી"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> બૅટરી"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"નોટિફિકેશન"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"વાતચીત"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"બધા સાઇલન્ટ નોટિફિકેશન સાફ કરો"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ખલેલ પાડશો નહીં દ્વારા થોભાવેલ નોટિફિકેશન"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;સ્ટેટસ:&lt;/b&gt; નીચલી રેંક આપવામાં આવી"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"વાતચીતના નોટિફિકેશન વિભાગની ટોચ પર અને લૉક કરેલી સ્ક્રીન પર પ્રોફાઇલ ફોટો તરીકે બતાવે છે"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"વાતચીતના નોટિફિકેશન વિભાગની ટોચ પર અને લૉક કરેલી સ્ક્રીન પર પ્રોફાઇલ ફોટો તરીકે બતાવે છે, બબલ તરીકે દેખાય છે"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"વાતચીતના નોટિફિકેશન વિભાગની ટોચ પર અને લૉક કરેલી સ્ક્રીન પર પ્રોફાઇલ ફોટો તરીકે બતાવે છે, ખલેલ પાડશો નહીં મોડમાં વિક્ષેપ ઊભો કરે છે"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"વાતચીતના નોટિફિકેશન વિભાગની ટોચ પર અને લૉક કરેલી સ્ક્રીન પર પ્રોફાઇલ ફોટો તરીકે બતાવે છે, બબલ તરીકે દેખાય છે, ખલેલ પાડશો નહીં મોડમાં વિક્ષેપ ઊભો કરે છે"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"સંગીત"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ખલેલ પાડશો નહીં"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"વૉલ્યૂમ બટન્સ શૉર્ટકટ"</string>
     <string name="battery" msgid="769686279459897127">"બૅટરી"</string>
     <string name="headset" msgid="4485892374984466437">"હૅડસેટ"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"વાઇ-ફાઇ બંધ છે"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"બ્લૂટૂથ બંધ છે"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"ખલેલ પાડશો નહીં બંધ છે"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ખલેલ પાડશો નહીં એક સ્વચાલિત નિયમ દ્વારા ચાલુ કરાયું હતું (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ખલેલ પાડશો નહીં એક ઍપ્લિકેશન દ્વારા ચાલુ કરાયું હતું (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ખલેલ પાડશો નહીં એક સ્વચાલિત નિયમ અથવા ઍપ્લિકેશન દ્વારા ચાલુ કરાયું હતું."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"પૃષ્ઠભૂમિમાં ચાલી રહેલ ઍપ્લિકેશનો"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"બૅટરી અને ડેટા વપરાશ વિશેની વિગતો માટે ટૅપ કરો"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"મોબાઇલ ડેટા બંધ કરીએ?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ઑફિસ)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ફોન કૉલ"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> મારફતે)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"કૅમેરા"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"સ્થાન"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"માઇક્રોફોન"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ડિસ્કનેક્ટ કરેલું)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"સ્વિચ કરી શકતા નથી. ફરી પ્રયાસ કરવા માટે ટૅપ કરો."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"નવા ડિવાઇસ સાથે જોડાણ કરો"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"આ સત્ર કાસ્ટ કરવા માટે, કૃપા કરીને ઍપ ખોલો."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"અજાણી ઍપ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"બિલ્ડ નંબર"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"બિલ્ડ નંબર ક્લિપબૉર્ડ પર કૉપિ કર્યો."</string>
     <string name="basic_status" msgid="2315371112182658176">"વાતચીત ખોલો"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"તાજેતરના સંદેશા, ચૂકી ગયેલા કૉલ અને સ્ટેટસ અપડેટ જુઓ"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"વાતચીત"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"\'ખલેલ પાડશો નહીં\'ની સુવિધા દ્વારા થોભાવેલું"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કોઈ સંદેશ મોકલવામાં આવ્યો: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કોઈ છબી મોકલવામાં આવી"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા નવી સ્ટેટસ અપડેટ પોસ્ટ કરવામાં આવી: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"નવી માહિતી"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"સક્રિય ઍપ"</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>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"કૉપિ કરવામાં આવી"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g>માંથી"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"\'UI | યૂઝર ઇન્ટરફેસ (UI) કૉપિ કરો\'ને છોડી દો"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"કૉપિ કરેલી ટેક્સ્ટમાં ફેરફાર કરો"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"કૉપિ કરેલી છબીમાં ફેરફાર કરો"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"નજીકના ડિવાઇસને મોકલો"</string>
+    <string name="add" msgid="81036585205287996">"ઉમેરો"</string>
+    <string name="manage_users" msgid="1823875311934643849">"વપરાશકર્તાઓને મેનેજ કરો"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"આ નોટિફિકેશન તેને સ્પ્લિટસ્ક્રીનમાં ખેંચવાની સુવિધાને સપોર્ટ કરતું નથી."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"વાઇ-ફાઇ ઉપલબ્ધ નથી"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"પ્રાધાન્યતા મોડ"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"અલાર્મ સેટ"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant અતિથિ મોડ ચાલુ કર્યો"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"કૅમેરા અને માઇક બંધ છે"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# નોટિફિકેશન}one{# નોટિફિકેશન}other{# નોટિફિકેશન}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 2631f55..27e5091 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"बैटरी जल्दी ही खत्म हो जाएगी"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> शेष"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"यूएसबी के ज़रिए चार्ज नहीं किया जा सकता"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"अपने डिवाइस के साथ मिलने वाले चार्जर का इस्तेमाल करें"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"चेहरे की पुष्टि हो गई"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि हो गई"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"\'पुष्टि करें\' पर टैप करके पूरा करें"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"बंद करें"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"कोई आवाज़ सुनाई नहीं देगी"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"सिर्फ़ अलार्म की आवाज़ सुनाई देगी"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"परेशान न करें."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ब्लूटूथ."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ब्लूटूथ चालू है."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> के लिए अलार्म सेट किया गया."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"मिठाई का डिब्बा"</string>
     <string name="start_dreams" msgid="9131802557946276718">"स्क्रीन सेवर"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ईथरनेट"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"परेशान न करें"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ब्लूटूथ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"कोई भी युग्मित डिवाइस उपलब्ध नहीं"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> बैटरी"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाएं"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"बातचीत"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"बिना आवाज़ की सभी सूचनाएं हटाएं"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'परेशान न करें\' सुविधा के ज़रिए कुछ समय के लिए सूचनाएं दिखाना रोक दिया गया है"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;स्थिति:&lt;/b&gt; रैंकिंग में नीचे किया गया"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"यह कई तरीकों से दिखती है, जैसे कि लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो के तौर पर और बातचीत वाली सूचनाओं में सबसे ऊपर"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"यह कई तरीकों से दिखती है, जैसे कि बातचीत वाली सूचनाओं में सबसे ऊपर, बबल के तौर पर, और लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो के तौर पर"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"यह कई तरीकों से दिखती है, जैसे कि लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो के तौर पर और बातचीत वाली सूचनाओं में सबसे ऊपर. साथ ही, इसकी वजह से, \'परेशान न करें\' सुविधा में भी रुकावट आती है"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"यह कई तरीकों से दिखती है, जैसे कि बातचीत वाली सूचनाओं में सबसे ऊपर, बबल के तौर पर, और लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो के तौर पर. साथ ही, इसकी वजह से, \'परेशान न करें\' सुविधा में भी रुकावट आती है"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"मैसेज (एसएमएस) करें"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"संगीत"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"परेशान न करें"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"वॉल्यूम बटन का शॉर्टकट"</string>
     <string name="battery" msgid="769686279459897127">"बैटरी"</string>
     <string name="headset" msgid="4485892374984466437">"हेडसेट"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"वाई-फ़ाई बंद है"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ब्लूटूथ बंद है"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"परेशान न करें बंद है"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"एक ऑटोमैटिक नियम (<xliff:g id="ID_1">%s</xliff:g>) ने परेशान न करें को चालू कर दिया था."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"एक ऐप्लिकेशन (<xliff:g id="ID_1">%s</xliff:g>) ने परेशान न करें को चालू कर दिया था."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"एक ऑटोमैटिक नियम या ऐप्लिकेशन ने परेशान न करें को चालू कर दिया था."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"बैकग्राउंड में चल रहे ऐप्लिकेशन"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"बैटरी और डेटा खर्च की जानकारी के लिए छूएं"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"मोबाइल डेटा बंद करना चाहते हैं?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ऑफ़िस)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"फ़ोन कॉल"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> की मदद से)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"कैमरा"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"जगह"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"माइक्रोफ़ोन"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिसकनेक्ट हो गया)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"स्विच नहीं किया जा सकता. फिर से कोशिश करने के लिए टैप करें."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नया डिवाइस जोड़ें"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"इस सेशन को कास्ट करने के लिए, कृपया ऐप्लिकेशन खोलें."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अनजान ऐप्लिकेशन"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string>
     <string name="basic_status" msgid="2315371112182658176">"ऐसी बातचीत जिसमें इंटरैक्शन डेटा मौजूद नहीं है"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"हाल के मैसेज, मिस्ड कॉल, और स्टेटस अपडेट देखें"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"बातचीत"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"\'परेशान न करें\' की वजह से सूचनाएं नहीं दिख रहीं"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ने एक मैसेज भेजा है: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ने एक इमेज भेजी है"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ने स्टेटस अपडेट किया है: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"नई जानकारी"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ये ऐप्लिकेशन चालू हैं"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"कॉपी किया गया"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> से"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"कॉपी किया गया यूज़र इंटरफ़ेस (यूआई) खारिज करें"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"कॉपी किए गए टेक्स्ट में बदलाव करें"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"कॉपी की गई इमेज में बदलाव करें"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"कॉन्टेंट को आस-पास मौजूद डिवाइस पर भेजें"</string>
+    <string name="add" msgid="81036585205287996">"जोड़ें"</string>
+    <string name="manage_users" msgid="1823875311934643849">"उपयोगकर्ताओं को मैनेज करें"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"इस सूचना को स्प्लिट स्क्रीन मोड में, खींचा और छोड़ा नहीं जा सकता."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"वाई-फ़ाई उपलब्ध नहीं है"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राथमिकता मोड"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट किया गया"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant का मेहमान मोड चालू किया गया"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कैमरा और माइक बंद हैं"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index da84b86..d3905e7 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI sustava"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Baterija bi se uskoro mogla isprazniti"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Preostalo <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Punjenje putem USB-a nije moguće"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Koristite punjač koji ste dobili s uređajem"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je autentificirano"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi za dovršetak"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentičnost provjerena"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite uzorak"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvaranje"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"potpuna tišina"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne uznemiravaj."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth uključen."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Vrijeme alarma: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Izlog za slastice"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Čuvar zaslona"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne uznemiravaj"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Upareni uređaji nisu dostupni"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string>
@@ -351,6 +360,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Obavijesti"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Razgovori"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Izbriši sve bešumne obavijesti"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Značajka Ne uznemiravaj pauzirala je Obavijesti"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Započni"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nema obavijesti"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
@@ -494,6 +504,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; niže rangirana"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Prikazuje se pri vrhu obavijesti razgovora i kao profilna slika na zaključanom zaslonu"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Prikazuje se pri vrhu obavijesti razgovora i kao profilna slika na zaključanom zaslonu, izgleda kao oblačić"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikazuje se pri vrhu obavijesti razgovora i kao profilna slika na zaključanom zaslonu, prekida Ne uznemiravaj"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se pri vrhu obavijesti razgovora i kao profilna slika na zaključanom zaslonu, izgleda kao oblačić, prekida Ne uznemiravaj"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava značajke razgovora"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Te se obavijesti ne mogu izmijeniti."</string>
@@ -571,6 +583,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Glazba"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne uznemiravaj"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Prečac tipki za glasnoću"</string>
     <string name="battery" msgid="769686279459897127">"Baterija"</string>
     <string name="headset" msgid="4485892374984466437">"Slušalice"</string>
@@ -689,6 +702,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi je isključen"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je isključen"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Način Ne uznemiravaj isključen"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Način Ne uznemiravaj uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Način Ne uznemiravaj uključila je aplikacija (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način Ne uznemiravaj uključilo je automatsko pravilo ili aplikacija."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Izvođenje aplikacija u pozadini"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podatkovnom prometu"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Isključiti mobilne podatke?"</string>
@@ -713,6 +730,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(posao)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski poziv"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(putem apl. <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparat"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -812,6 +831,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nije povezano)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nije prebačeno. Dodirnite da biste pokušali ponovo."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste emitirali ovu sesiju, otvorite aplikaciju."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj međuverzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj međuverzije kopiran je u međuspremnik."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
@@ -845,6 +866,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Pogledajte nedavne poruke, propuštene pozive i ažuriranja statusa"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Razgovor"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Pauzirala značajka Ne uznemiravaj"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> šalje poruku: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"Korisnik <xliff:g id="NAME">%1$s</xliff:g> poslao je sliku"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ima ažuriranje statusa: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
       <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aktivne aplikacije</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktivnih aplikacija</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</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>
@@ -893,14 +914,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopirano"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Iz aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Odbaci kopiranje korisničkog sučelja"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Uredi kopirani tekst"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Uredi kopiranu sliku"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošalji uređaju u blizini"</string>
+    <string name="add" msgid="81036585205287996">"Dodaj"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Upravljanje korisnicima"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Ova obavijest ne podržava povlačenje na podijeljeni zaslon."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nije dostupan"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni način rada"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Omogućen je način rada za goste u Asistentu"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat i mikrofon su isključeni"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavijest}one{# obavijest}few{# obavijesti}other{# obavijesti}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 30a5be8..3b94d8f 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -20,7 +20,12 @@
 <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">"Rendszer UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Az akkumulátor hamarosan lemerül"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> maradt"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Nem tölthető USB-n keresztül"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Használja az eszközhöz kapott eredeti töltőt"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Arc hitelesítve"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Megerősítve"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Koppintson a Megerősítés lehetőségre"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Hitelesítve"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-kód használata"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Minta használata"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Bezárás"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"teljes némítás"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"csak ébresztések"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne zavarjanak."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth bekapcsolva."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Ébresztés időpontja: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Képernyővédő"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne zavarjanak"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nem áll rendelkezésre párosított eszköz"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Értesítések"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Beszélgetések"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Az összes néma értesítés törlése"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ne zavarjanak funkcióval szüneteltetett értesítések"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Indítás most"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nincs értesítés"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Az eszközt a szülőd felügyeli"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Állapot:&lt;/b&gt; hátrébb sorolva"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"A beszélgetésekre vonatkozó értesítések tetején látható, és megjeleníti a profilképet a lezárási képernyőn"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"A beszélgetésekre vonatkozó értesítések tetején, lebegő buborékként látható, és megjeleníti a profilképet a lezárási képernyőn"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"A beszélgetésekre vonatkozó értesítések tetején látható, megjeleníti a profilképet a lezárási képernyőn, és megszakítja a Ne zavarjanak funkciót"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"A beszélgetésekre vonatkozó értesítések tetején, lebegő buborékként látható, megjeleníti a profilképet a lezárási képernyőn, és megszakítja a Ne zavarjanak funkciót"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritás"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> nem támogatja a beszélgetési funkciókat"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ezeket az értesítéseket nem lehet módosítani."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS-üzenetek"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Zene"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Naptár"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne zavarjanak"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"A hangerőgombok gyorsbillentyűk"</string>
     <string name="battery" msgid="769686279459897127">"Akkumulátor"</string>
     <string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"A Wi-Fi ki van kapcsolva"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"A Bluetooth ki van kapcsolva"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"A „Ne zavarjanak” mód ki van kapcsolva"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Az egyik automatikus szabály (<xliff:g id="ID_1">%s</xliff:g>) bekapcsolta a „Ne zavarjanak” módot."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Az egyik alkalmazás (<xliff:g id="ID_1">%s</xliff:g>) bekapcsolta a „Ne zavarjanak” módot."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Az egyik alkalmazás vagy automatikus szabály bekapcsolta a „Ne zavarjanak” módot."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"A háttérben még futnak alkalmazások"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Koppintson az akkumulátor- és adathasználat részleteinek megtekintéséhez"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Kikapcsolja a mobiladatokat?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(munkahely)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonhívás"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(a következőn keresztül: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"helyadatok"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(leválasztva)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"A váltás nem sikerült. Próbálja újra."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Új eszköz párosítása"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"A munkamenet átküldéséhez nyissa meg az alkalmazást."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ismeretlen alkalmazás"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildszám"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildszám a vágólapra másolva."</string>
     <string name="basic_status" msgid="2315371112182658176">"Beszélgetés megnyitása"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Megtekintheti a legutóbbi üzeneteket, a nem fogadott hívásokat és az állapotfrissítéseket."</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Beszélgetés"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"A Ne zavarjanak mód által szüneteltetve"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> üzenetet küldött: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> képet küldött"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> frissítette állapotát: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktív alkalmazás</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktív alkalmazás</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <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>
     <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>
@@ -889,8 +910,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Vágólapra másolt szöveg szerkesztése"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Vágólapra másolt kép szerkesztése"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Küldés közeli eszközre"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"Hozzáadás"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Felhasználók kezelése"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Az értesítés nem támogatja a megosztott képernyőre való áthúzást."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"A Wi‑Fi nem áll rendelkezésre"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritás mód"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ébresztő beállítva"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"A Segéd vendég módja engedélyezve"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A kamera és a mikrofon ki vannak kapcsolva"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# értesítés}other{# értesítés}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 443da54..488aa76 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"Մարտկոցի լիցքը շուտով կարող է սպառվել"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Մնաց <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Սարքը հնարավոր չէ լիցքավորել USB-ի միջոցով"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Օգտագործեք սարքի լիցքավորիչը"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Դեմքը ճանաչվեց"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Հաստատվեց"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ավարտելու համար հպեք «Հաստատել»"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Փակել"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"կատարյալ լռություն"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"միայն զարթուցիչը"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Չանհանգստացնել։"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth:"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth-ը միացված է:"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Զարթուցիչը դրված է <xliff:g id="TIME">%s</xliff:g>-ին:"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Էկրանապահ"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Չանհանգստացնել"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Զուգակցված սարքեր չկան"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Ծանուցումներ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Զրույցներ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ջնջել բոլոր անձայն ծանուցումները"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ծանուցումները չեն ցուցադրվի «Չանհանգստացնել» ռեժիմում"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Կարգավիճակը․&lt;/b&gt; կարևորության մակարդակն իջեցվել է"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Ցուցադրվում է զրույցների ծանուցումների վերևում, ինչպես նաև կողպէկրանին որպես պրոֆիլի նկար"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Ցուցադրվում է զրույցների ծանուցումների վերևում, ինչպես նաև կողպէկրանին որպես պրոֆիլի նկար, հայտնվում է ամպիկի տեսքով"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Ցուցադրվում է զրույցների ծանուցումների վերևում, ինչպես նաև կողպէկրանին որպես պրոֆիլի նկար, ընդհատում է «Չանհանգստացնել» ռեժիմը"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ցուցադրվում է զրույցների ծանուցումների վերևում, ինչպես նաև կողպէկրանին որպես պրոֆիլի նկար, հայտնվում է ամպիկի տեսքով, ընդհատում է «Չանհանգստացնել» ռեժիմը"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Երաժշտություն"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Օրացույց"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Չանհանգստացնել"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Ձայնի կոճակների դյուրանցում"</string>
     <string name="battery" msgid="769686279459897127">"Մարտկոց"</string>
     <string name="headset" msgid="4485892374984466437">"Ականջակալ"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi-ն անջատված է"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth-ն անջատված է"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Չանհանգստացնելու ռեժիմն անջատված է"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Չանհանգստացնել գործառույթը միացված է ավտոմատ կանոնի կողմից (<xliff:g id="ID_1">%s</xliff:g>):"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Չանհանգստացնել գործառույթը միացված է հավելվածի կողմից (<xliff:g id="ID_1">%s</xliff:g>):"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Չանհանգստացնել գործառույթը միացված է ավտոմատ կանոնի կամ հավելվածի կողմից:"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Ֆոնային ռեժիմում աշխատող հավելվածներ"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Հպեք՝ մարտկոցի և թրաֆիկի մանրամասները տեսնելու համար"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Անջատե՞լ բջջային ինտերնետը"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(աշխատանքային)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Հեռախոսազանգ"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(հետևյալ հավելված(ներ)ի միջոցով՝ <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"տեսախցիկը"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"վայրը"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"խոսափողը"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(անջատված է)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Սխալ առաջացավ։ Հպեք՝ կրկնելու համար։"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Նոր սարքի զուգակցում"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Այս աշխատաշրջանը հեռարձակելու համար բացեք հավելվածը"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Անհայտ հավելված"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string>
     <string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Տեսեք վերջին հաղորդագրությունները, բաց թողնված զանգերը և կարգավիճակի մասին թարմացումները"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Զրույց"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Դադարեցվել է «Չանհանգստացնել» գործառույթի կողմից"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> օգտատերը հաղորդագրություն է ուղարկել. «<xliff:g id="NOTIFICATION">%2$s</xliff:g>»"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> օգտատերը պատկեր է ուղարկել"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> օգտատերը նոր կարգավիճակ է հրապարակել. «<xliff:g id="STATUS">%2$s</xliff:g>»"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Նոր տեղեկություն"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ակտիվ հավելվածներ"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Պատճենվեց"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածից"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Փակել պատճենների միջերեսը"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Փոփոխել պատճենված տեքստը"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Փոփոխել պատճենված պատկերը"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Ուղարկել մոտակա սարքի"</string>
+    <string name="add" msgid="81036585205287996">"Ավելացնել"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Օգտատերերի կառավարում"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Այս ծանուցումը հնարավոր չէ քաշել տրոհված էկրանի մեկ հատվածից մյուսը։"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi-ը հասանելի չէ"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Առաջնահերթության ռեժիմ"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Զարթուցիչը դրված է"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Օգնականի հյուրի ռեժիմը միացված է"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Տեսախցիկը և խոսափողն անջատված են"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index c7339c7..0913166 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI Sistem"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Baterai mungkin akan segera habis"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Tersisa <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Tidak dapat mengisi daya melalui USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Gunakan pengisi daya yang disertakan dengan perangkat"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Wajah diautentikasi"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Dikonfirmasi"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ketuk Konfirmasi untuk menyelesaikan"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Diautentikasi"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gunakan PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gunakan pola"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Tutup"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"senyap total"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"hanya alarm"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Jangan Ganggu."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth aktif."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm disetel ke <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Etalase Hidangan Penutup"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Jangan Ganggu"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Perangkat yang disandingkan tak tersedia"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifikasi"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Percakapan"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Hapus semua notifikasi senyap"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifikasi dijeda oleh mode Jangan Ganggu"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Mulai sekarang"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Tidak ada notifikasi"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Perangkat ini dikelola oleh orang tuamu"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Diberi Peringkat Lebih Rendah"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci, ditampilkan sebagai balon"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci, mengganggu fitur Jangan Ganggu"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci, ditampilkan sebagai balon, mengganggu fitur Jangan Ganggu"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritas"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak mendukung fitur percakapan"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Notifikasi ini tidak dapat diubah."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Jangan Ganggu"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Pintasan tombol volume"</string>
     <string name="battery" msgid="769686279459897127">"Baterai"</string>
     <string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi nonaktif"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth nonaktif"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Fitur Jangan Ganggu nonaktif"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Mode Jangan Ganggu diaktifkan oleh aturan otomatis (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Mode Jangan Ganggu diaktifkan oleh aplikasi (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Mode Jangan Ganggu diaktifkan oleh aturan otomatis atau aplikasi."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikasi yang sedang berjalan di latar belakang"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Ketuk untuk melihat detail penggunaan baterai dan data"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Nonaktifkan data seluler?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(kerja)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Panggilan telepon"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(melalui <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"lokasi"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(terputus)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Tidak dapat beralih. Ketuk untuk mencoba lagi."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sambungkan perangkat baru"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Buka aplikasi untuk mentransmisikan sesi ini."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikasi tidak dikenal"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nomor versi disalin ke papan klip."</string>
     <string name="basic_status" msgid="2315371112182658176">"Membuka percakapan"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Lihat pesan terbaru, panggilan tak terjawab, dan pembaruan status"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Percakapan"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Dijeda oleh fitur Jangan Ganggu"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> mengirim pesan: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> mengirim gambar"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> memposting pembaruan status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikasi aktif</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikasi aktif</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informasi baru"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplikasi aktif"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Berhenti"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Dihentikan"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Disalin"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Dari <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Tutup UI salin"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit teks yang disalin"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit gambar yang disalin"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Kirim ke perangkat di sekitar"</string>
+    <string name="add" msgid="81036585205287996">"Tambahkan"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Kelola pengguna"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Notifikasi ini tidak mendukung fitur tarik ke Layar terpisah."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi tidak tersedia"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode prioritas"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm disetel"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Mode Tamu Asisten diaktifkan"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon nonaktif"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index eddd246..cddb8f8 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -20,7 +20,12 @@
 <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">"Kerfisviðmót"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Rafhlaðan gæti tæmst bráðlega"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> eftir"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Ekki er hægt að hlaða í gegnum USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Notaðu hleðslutækið sem fylgdi tækinu þínu"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Andlit staðfest"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Staðfest"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ýttu á „Staðfesta“ til að ljúka"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Auðkennt"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Nota PIN-númer"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Nota mynstur"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Loka"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"algjör þögn"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"aðeins vekjarar"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ónáðið ekki."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Kveikt á Bluetooth."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Vekjari stilltur á <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Eftirréttaborð"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Skjávari"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ónáðið ekki"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Engin pöruð tæki til staðar"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> rafhlöðuhleðsla"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Tilkynningar"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtöl"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Hreinsa allar þöglar tilkynningar"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Hlé gert á tilkynningum þar sem stillt er á „Ónáðið ekki“"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Byrja núna"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Engar tilkynningar"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Foreldri þitt stjórnar þessu tæki"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Staða:&lt;/b&gt; fékk lægri stöðu"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Birtist efst í samtalstilkynningum og sem prófílmynd á lásskjánum"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Birtist efst í samtalstilkynningum og sem prófílmynd á lásskjánum, birtist sem blaðra"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Birtist efst í samtalstilkynningum og sem prófílmynd á lásskjánum. Truflar „Ónáðið ekki“"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Birtist efst í samtalstilkynningum og sem prófílmynd á lásskjánum. Birtist sem blaðra sem truflar „Ónáðið ekki“"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Forgangur"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> styður ekki samtalseiginleika"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ekki er hægt að breyta þessum tilkynningum."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS-skilaboð"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Tónlist"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Dagatal"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ónáðið ekki"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Flýtihnappar fyrir hljóðstyrk"</string>
     <string name="battery" msgid="769686279459897127">"Rafhlaða"</string>
     <string name="headset" msgid="4485892374984466437">"Höfuðtól"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Slökkt á Wi-Fi"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Slökkt á Bluetooth"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Slökkt á „Ónáðið ekki“"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Sjálfvirk regla kveikti á „Ónáðið ekki“ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Forrit kveikti á „Ónáðið ekki“ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Sjálfvirk regla eða forrit kveikti á „Ónáðið ekki“"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Forrit sem keyra í bakgrunni"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Ýttu til að fá upplýsingar um rafhlöðu- og gagnanotkun"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Viltu slökkva á farsímagögnum?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(vinna)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Símtal"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(í gegnum <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"myndavél"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"staðsetning"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"hljóðnemi"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(aftengt)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ekki er hægt að skipta. Ýttu til að reyna aftur."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Para nýtt tæki"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Opnaðu forritið til að senda þessa lotu út."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Óþekkt forrit"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Útgáfunúmer smíðar"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Útgáfunúmer smíðar afritað á klippiborð."</string>
     <string name="basic_status" msgid="2315371112182658176">"Opna samtal"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Sjá nýleg skilboð, ósvöruð símtöl og stöðuuppfærslur"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Samtal"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Sett í bið af „Ónáðið ekki“"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> sendi skilaboð: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sendi mynd"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> er með stöðuuppfærslu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> virkt forrit</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> virk forrit</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nýjar upplýsingar"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Virk forrit"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Afritað"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Frá <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Loka afriti notendaviðmóts"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Breyta afrituðum texta"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Breyta afritaðri mynd"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Senda í nálægt tæki"</string>
+    <string name="add" msgid="81036585205287996">"Bæta við"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Stjórna notendum"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Þessi tilkynning styður ekki að draga yfir á skiptan skjá."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi ekki tiltækt"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Forgangsstilling"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Vekjari stilltur"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Kveikt á gestastillingu Hjálpara"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Slökkt á myndavél og hljóðnema"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 6a07f79..ed125cd 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI sistema"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"La batteria potrebbe esaurirsi a breve"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> rimanente"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Impossibile ricaricare tramite USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Utilizza il caricabatterie fornito in dotazione con il dispositivo"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Volto autenticato"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confermato"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tocca Conferma per completare"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticazione eseguita"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilizza PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usa sequenza"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Chiudi"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silenzio totale"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"solo sveglie"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Non disturbare."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth attivo."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Sveglia impostata per le <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Vetrina di dolci"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Salvaschermo"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Non disturbare"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nessun dispositivo accoppiato disponibile"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifiche"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversazioni"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Cancella tutte le notifiche silenziose"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifiche messe in pausa in base alla modalità Non disturbare"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Avvia adesso"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nessuna notifica"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Questo dispositivo è gestito dai tuoi genitori"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stato:&lt;/b&gt; posizionata più in basso"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Appare in cima alle notifiche delle conversazioni e compare come immagine del profilo nella schermata di blocco"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Appare in cima alle notifiche delle conversazioni, nonché compare come immagine del profilo nella schermata di blocco e come bolla"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Appare in cima alle notifiche delle conversazioni, interrompe la modalità Non disturbare e compare come immagine del profilo nella schermata di blocco"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Appare in cima alle notifiche delle conversazioni, interrompe la modalità Non disturbare, nonché compare come immagine del profilo nella schermata di blocco e come bolla"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorità"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non supporta le funzionalità delle conversazioni"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Impossibile modificare queste notifiche."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musica"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendario"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Non disturbare"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Pulsanti del volume come scorciatoia"</string>
     <string name="battery" msgid="769686279459897127">"Batteria"</string>
     <string name="headset" msgid="4485892374984466437">"Auricolare"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi disattivato"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth non attivo"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Funzione Non disturbare disattivata"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"La funzione Non disturbare è stata attivata da una regola automatica (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"La funzione Non disturbare è stata attivata da un\'app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"La funzione Non disturbare è stata attivata da una regola automatica o da un\'app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"App in esecuzione in background"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tocca per conoscere i dettagli sull\'utilizzo dei dati e della batteria"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Disattivare i dati mobili?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(lavoro)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonata"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(tramite <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"fotocamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"posizione"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"microfono"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnesso)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Non puoi cambiare. Tocca per riprovare."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Accoppia nuovo dispositivo"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per trasmettere questa sessione devi aprire l\'app."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App sconosciuta"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numero build copiato negli appunti."</string>
     <string name="basic_status" msgid="2315371112182658176">"Apri conversazione"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+<xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Visualizza messaggi recenti, chiamate senza risposta e aggiornamenti dello stato"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversazione"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"In pausa in base alla modalità Non disturbare"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ha inviato un messaggio: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha inviato un\'immagine"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ha aggiornato lo stato: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,22 +899,24 @@
       <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app attiva</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> app attive</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nuove informazioni"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"App attive"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Interrompi"</string>
-    <!-- no translation found for fgs_manager_app_item_stop_button_stopped_label (6950382004441263922) -->
-    <skip />
+    <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Interrotta"</string>
     <string name="clipboard_edit_text_copy" msgid="770856373439969178">"Copia"</string>
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiato"</string>
-    <!-- no translation found for clipboard_edit_source (9156488177277788029) -->
-    <skip />
+    <string name="clipboard_edit_source" msgid="9156488177277788029">"Da <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignora copia UI"</string>
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifica testo copiato"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifica immagine copiata"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Invia a dispositivo nelle vicinanze"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"Aggiungi"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Gestisci utenti"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Non è possibile trascinare questa notifica tra le due parti dello schermo diviso."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi non disponibile"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modalità Priorità"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Sveglia impostata"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modalità Ospite dell\'assistente attiva"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotocamera e microfono non attivi"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifica}one{# notifica}other{# notifiche}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index f959774..f88605a 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"ייתכן שהסוללה תתרוקן בקרוב"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"נותרו <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"‏לא ניתן לטעון באמצעות USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"שימוש במטען שסופק עם המכשיר"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"זיהוי הפנים בוצע"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"יש אישור"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"יש להקיש על \'אישור\' לסיום התהליך"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"סגירה"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"השתקה מוחלטת"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"רק התראות"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"נא לא להפריע."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"‏Bluetooth מופעל."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ההתראה נקבעה ל-<xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"מזנון קינוחים"</string>
     <string name="start_dreams" msgid="9131802557946276718">"שומר מסך"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"אתרנט"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"נא לא להפריע"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"אין מכשירים מותאמים זמינים"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> סוללה"</string>
@@ -354,6 +363,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"התראות"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"שיחות"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ניקוי כל ההתראות השקטות"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"התראות הושהו על ידי מצב \'נא לא להפריע\'"</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>
@@ -497,6 +507,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"‏&lt;b&gt;הסטטוס:&lt;/b&gt; דורג נמוך יותר"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"מוצגת בחלק העליון של קטע ההתראות וכתמונת פרופיל במסך הנעילה"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מופיעה בבועה"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מפריעה במצב \'נא לא להפריע\'"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מופיעה בבועה צפה ומפריעה במצב \'נא לא להפריע\'"</string>
     <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>
@@ -576,6 +588,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"מוזיקה"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"יומן"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"נא לא להפריע"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"קיצור דרך ללחצני עוצמת קול"</string>
     <string name="battery" msgid="769686279459897127">"סוללה"</string>
     <string name="headset" msgid="4485892374984466437">"אוזניות"</string>
@@ -694,6 +707,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"‏Wi-Fi כבוי"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"‏Bluetooth כבוי"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"מצב \'נא לא להפריע\' כבוי"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"מצב \'נא לא להפריע\' הופעל על ידי כלל אוטומטי (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה או על ידי כלל אוטומטי."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"אפליקציות שפועלות ברקע"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"אפשר להקיש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"לכבות את חבילת הגלישה?"</string>
@@ -718,6 +735,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(עבודה)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"שיחת טלפון"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(באמצעות <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"מצלמה"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"מיקום"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"מיקרופון"</string>
@@ -818,6 +837,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(מנותק)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"לא ניתן להחליף. צריך להקיש כדי לנסות שוב."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"התאמה של מכשיר חדש"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"‏כדי להעביר (cast) את הסשן הזה, צריך לפתוח את האפליקציה."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"אפליקציה לא ידועה"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"‏מספר Build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"‏מספר ה-Build הועתק ללוח."</string>
     <string name="basic_status" msgid="2315371112182658176">"פתיחת שיחה"</string>
@@ -851,6 +872,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"ההודעות האחרונות, שיחות שלא נענו ועדכוני סטטוס"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"שיחה"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"ההתראה הושהתה על ידי \'נא לא להפריע\'"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"התקבלה הודעה מ<xliff:g id="NAME">%1$s</xliff:g>: ‏<xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> שלח/ה תמונה"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"הסטטוס של <xliff:g id="NAME">%1$s</xliff:g> עודכן: ‏<xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"מידע חדש"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"אפליקציות פעילות"</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>
@@ -900,14 +921,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"הועתק"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"המקור: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"ביטול של העתקת ממשק המשתמש"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"עריכת הטקסט שהועתק"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"עריכת התמונה שהועתקה"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"שליחה למכשיר בקרבת מקום"</string>
+    <string name="add" msgid="81036585205287996">"הוספה"</string>
+    <string name="manage_users" msgid="1823875311934643849">"ניהול משתמשים"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"ההתראה הזו לא תומכת בגרירה למסך מפוצל."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi‑Fi לא זמין"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"מצב עדיפות"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ההתראה מוגדרת"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"‏מצב אורח ב‑Assistant מופעל"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"המצלמה והמיקרופון כבויים"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 05ddace..b946344 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -20,7 +20,12 @@
 <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">"システム UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"もうすぐ電池がなくなります"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"残量が<xliff:g id="PERCENTAGE">%s</xliff:g>です"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB 経由では充電できません"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"デバイスに付属の充電器を使用してください"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"顔を認証しました"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"確認しました"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"完了するには [確認] をタップしてください"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"閉じる"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"サイレント"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"アラームのみ"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"サイレント モード。"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"BluetoothがONです。"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"アラームは<xliff:g id="TIME">%s</xliff:g>に設定されています。"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"デザートケース"</string>
     <string name="start_dreams" msgid="9131802557946276718">"スクリーン セーバー"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"イーサネット"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"サイレント モード"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ペア設定されたデバイスがありません"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"会話"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"サイレント通知がすべて消去されます"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"サイレント モードにより通知は一時停止中です"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ステータス:&lt;/b&gt; ランクが下がりました"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"会話通知の一番上に表示されると同時に、ロック画面にプロフィール写真として表示されます"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"会話通知の一番上に表示されると同時に、ロック画面にプロフィール写真として表示されるほか、バブルとして表示されます"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"会話通知の一番上に表示されると同時に、ロック画面にプロフィール写真として表示され、サイレント モードが中断されます"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"会話通知の一番上に表示されると同時に、ロック画面にプロフィール写真として表示されるほか、バブルとして表示され、サイレント モードが中断されます"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音楽"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"カレンダー"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"サイレント モード"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"音量ボタンのショートカット"</string>
     <string name="battery" msgid="769686279459897127">"バッテリー"</string>
     <string name="headset" msgid="4485892374984466437">"ヘッドセット"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>、<xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi は OFF です"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth は OFF です"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"サイレント モードは OFF です"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"サイレント モードが自動ルール(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"サイレント モードがアプリ(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"サイレント モードが自動ルールまたはアプリによって ON になりました。"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"バックグラウンドで実行中のアプリ"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"タップしてバッテリーやデータの使用量を確認"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"モバイルデータを OFF にしますか?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(業務用)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"通話"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> 経由)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"カメラ"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"現在地情報"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"マイク"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(接続解除済み)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"切り替えられません。タップしてやり直してください。"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"新しいデバイスとのペア設定"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"このセッションをキャストするには、アプリを開いてください。"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明なアプリ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string>
     <string name="basic_status" msgid="2315371112182658176">"空の会話"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g> 件以上"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"最近のメッセージ、不在着信、最新のステータスが表示されます"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"会話"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"サイレント モードにより一時停止"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> さんからのメッセージ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> さんが画像を送信しました"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> さんの近況: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"最新情報"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"有効なアプリ"</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>
@@ -889,8 +910,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"コピーしたテキストを編集"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"コピーした画像を編集"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"付近のデバイスに送信"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"追加"</string>
+    <string name="manage_users" msgid="1823875311934643849">"ユーザーの管理"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"この通知は、分割画面へのドラッグがサポートされていません。"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi を利用できません"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先順位モード"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"アラームを設定しました"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"アシスタント ゲストモードを有効にしました"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"カメラとマイクが OFF です"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 件の通知}other{# 件の通知}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index cf77cac..31d7606 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -20,7 +20,12 @@
 <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">"სისტემის UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"ბატარეა შესაძლოა მალე ამოიწუროს"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"დარჩენილია <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB-თ დატენვა ვერ ხერხდება"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"გამოიყენეთ დამტენი, რომელიც თქვენს მოწყობილობას მოჰყვა"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"სახის ამოცნობილია"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"დადასტურებული"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"დასასრულებლად შეეხეთ „დადასტურებას“"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"დახურვა"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"სრული სიჩუმე"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"მხოლოდ მაღვიძარები"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"არ შემაწუხოთ."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ჩართულია."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"მაღვიძარა დაყენებულია: <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"სადესერტო ყუთი"</string>
     <string name="start_dreams" msgid="9131802557946276718">"ეკრანმზოგი"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ეთერნეტი"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"არ შემაწუხოთ"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"დაწყვილებული მოწყობილობები მიუწვდომელია"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ბატარეა"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"შეტყობინებები"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"საუბრები"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ყველა ჩუმი შეტყობინების გასუფთავება"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"შეტყობინებები დაპაუზდა „არ შემაწუხოთ“ რეჟიმის მეშვეობით"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;სტატუსი:&lt;/b&gt; ნაკლებად პრიორიტეტული"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"გამოჩნდება საუბრის შეტყობინებების თავში და პროფილის სურათის სახით ჩაკეტილ ეკრანზე"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"გამოჩნდება საუბრის შეტყობინებების თავში და პროფილის სურათის სახით ჩაკეტილ ეკრანზე, ჩნდება ბუშტის სახით"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"გამოჩნდება საუბრის შეტყობინებების თავში და პროფილის სურათის სახით ჩაკეტილ ეკრანზე, წყვეტს ფუნქციას „არ შემაწუხოთ“"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"გამოჩნდება საუბრის შეტყობინებების თავში და პროფილის სურათის სახით ჩაკეტილ ეკრანზე, ჩნდება ბუშტის სახით, წყვეტს ფუნქციას „არ შემაწუხოთ“"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"მუსიკა"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"კალენდარი"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"არ შემაწუხოთ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ხმის ღილაკების მალსახმობი"</string>
     <string name="battery" msgid="769686279459897127">"ბატარეა"</string>
     <string name="headset" msgid="4485892374984466437">"ყურსაცვამი"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi გამორთულია"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth გამორთულია"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"„არ შემაწუხოთ“ რეჟიმი გამორთულია"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"„არ შემაწუხოთ“ ჩაირთო ავტომატური წესის მიხედვით (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"„არ შემაწუხოთ“ ჩაირთო აპის მიერ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"„არ შემაწუხოთ“ ჩაირთო ავტომატური წესის მიხედვით ან აპის მიერ."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"ფონურ რეჟიმში გაშვებული აპები"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"შეეხეთ ბატარეისა და მონაცემების მოხმარების შესახებ დეტალური ინფორმაციისთვის"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"გსურთ მობილური ინტერნეტის გამორთვა?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(სამსახური)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"სატელეფონო ზარი"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>-ის მეშვეობით)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"კამერა"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"მდებარეობა"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"მიკროფონი"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(კავშირი გაწყვეტილია)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ვერ გადაირთო. შეეხეთ ხელახლა საცდელად."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ახალი მოწყობილობის დაწყვილება"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ამ სესიის ტრანსლირებისთვის გახსენით აპი."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"უცნობი აპი"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ანაწყობის ნომერი"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ანაწყობის ნომერი დაკოპირებულია გაცვლის ბუფერში."</string>
     <string name="basic_status" msgid="2315371112182658176">"მიმოწერის გახსნა"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"ბოლოდროინდელი შეტყობინებების, გამოტოვებული ზარების და სტატუსის განახლებების ნახვა"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"მიმოწერა"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"დაპაუზებულია ფუნქციის „არ შემაწუხოთ“ მიერ"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>-მა გაგზავნა შეტყობინება: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>-მ(ა) სურათი გამოგზავნა"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>-მა განაახლა სტატუსი: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"ახალი ინფორმაცია"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"აქტიური აპები"</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>
@@ -889,8 +910,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"კოპირებული ტექსტის რედაქტირება"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"კოპირებული სურათის რედაქტირება"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ახლომახლო მოწყობილობაზე გაგზავნა"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"დამატება"</string>
+    <string name="manage_users" msgid="1823875311934643849">"მომხმარებლების მართვა"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"ამ შეტყობინების გადათრევა გაყოფილ ეკრანებს შორის არ არის მხარდაჭერილი."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi მიუწვდომელია"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"პრიორიტეტული რეჟიმი"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"მაღვიძარა დაყენებულია"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"ასისტენტის სტუმრის რეჟიმი ჩართულია"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"კამერა და მიკროფონი გამორთულია"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# შეტყობინება}other{# შეტყობინება}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 32d2e51..c8abf95 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"Батерея заряды жақын арада бітуі мүмкін"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> қалды"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB арқылы зарядтау мүмкін емес"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Құрылғымен бірге берілген зарядтау құралын пайдаланыңыз"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Бет танылды."</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Расталды"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Аяқтау үшін \"Растау\" түймесін түртіңіз."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Жабу"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"үнсіз"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"оятқыштар ғана"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Мазаламау."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth қосулы."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Дабыл <xliff:g id="TIME">%s</xliff:g> уақытына реттелген."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Десерт жағдайы"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Скринсейвер"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Этернет"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Мазаламау"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Жұптасқан құрылғылар жоқ"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Хабарландырулар"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Әңгімелер"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Барлық үнсіз хабарландыруларды өшіру"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Хабарландырулар Мазаламау режимінде кідіртілді"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Күйі:&lt;/b&gt; маңыздылық деңгейі төмендетілген"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Әңгіме туралы хабарландырулардың жоғарғы жағында тұрады және құлыптаулы экранда профиль суреті ретінде көрсетіледі."</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Әңгіме туралы хабарландырулардың жоғарғы жағында тұрады және құлыптаулы экранда профиль суреті болып көрсетіледі, қалқыма хабар түрінде шығады."</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Әңгіме туралы хабарландырулардың жоғарғы жағында тұрады және құлыптаулы экранда профиль суреті ретінде көрсетіледі, Мазаламау режимін тоқтатады."</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Әңгіме туралы хабарландырулардың жоғарғы жағында тұрады және құлыптаулы экранда профиль суреті болып көрсетіледі, қалқыма хабар түрінде шығады, Мазаламау режимін тоқтатады."</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Мәтіндік хабар"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Mузыка"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Күнтізбе"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Мазаламау"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Дыбыс деңгейі түймелерінің төте жолы"</string>
     <string name="battery" msgid="769686279459897127">"Батарея"</string>
     <string name="headset" msgid="4485892374984466437">"Құлақаспап жинағы"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi өшірулі"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth өшірулі"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Мазаламау режимі өшірулі"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Мазаламау режимі (<xliff:g id="ID_1">%s</xliff:g>) автоматты ережесі арқылы қосылды."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Мазаламау режимі (<xliff:g id="ID_1">%s</xliff:g>) қолданбасы арқылы қосылды."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Мазаламау режимі автоматты ереже немесе қолданба арқылы қосылды."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Фонда жұмыс істеп тұрған қолданбалар"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Батарея мен деректер трафигі туралы білу үшін түртіңіз"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Мобильдік деректер өшірілсін бе?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(жұмыс)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефон қоңырауы"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> арқылы)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"геодерек"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ажыратулы)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ауысу мүмкін емес. Әрекетті қайталау үшін түртіңіз."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңа құрылғымен жұптау"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бұл сеансты трансляциялау үшін қолданбаны ашыңыз."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгісіз қолданба"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Құрама нөмірі"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Құрама нөмірі буферге көшірілді."</string>
     <string name="basic_status" msgid="2315371112182658176">"Ашық әңгіме"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Соңғы хабарларды, өткізіп алған қоңыраулар мен жаңартылған күйлерді көруге болады."</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Әңгіме"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Мазаламау режимі арқылы кідіртілді."</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> хабар жіберді: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> сурет жіберді."</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ағымдағы күйін жаңартты: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Жаңа ақпарат"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Белсенді қолданбалар"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Көшірілді"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасынан"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Көшіру интерфейсін жабу"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Көшірілген мәтінді өңдеу"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Көшірілген суретті өңдеу"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Маңайдағы құрылғыға жіберу"</string>
+    <string name="add" msgid="81036585205287996">"Қосу"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Пайдаланушыларды басқару"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Бұл хабарландыруды бөлінген экранға сүйреп апару мүмкін емес."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi қолжетімсіз"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Басымдық режимі"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Оятқыш орнатылды"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant қонақ режимі қосылды"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера мен микрофон өшірулі"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 581d3e6..78e6c84 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI ប្រព័ន្ធ"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"អាចនឹងអស់ថ្មក្នុងពេលបន្តិចទៀត"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"នៅ​សល់ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"មិន​អាច​សាក​តាម USB បានទេ"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"សូមប្រើ​ឆ្នាំង​សាក​ដែល​ភ្ជាប់​មក​ជាមួយ​ឧបករណ៍​របស់អ្នក"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"បានផ្ទៀងផ្ទាត់​មុខ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"បានបញ្ជាក់"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ចុច \"បញ្ជាក់\" ដើម្បីបញ្ចប់"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"បិទ"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"បិទសំឡេង​ទាំងស្រុង"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"សំឡេងរោទ៍​ប៉ុណ្ណោះ"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"កុំ​រំខាន។"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ប៊្លូធូស"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"បើក​ប៊្លូធូស។"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"កំណត់​សំឡេង​រោទ៍​សម្រាប់ <xliff:g id="TIME">%s</xliff:g> ។"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"ករណី Dessert"</string>
     <string name="start_dreams" msgid="9131802557946276718">"ធាតុរក្សាអេក្រង់"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"អ៊ីសឺរណិត"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"កុំ​រំខាន"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ប៊្លូធូស"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"មិន​មាន​ឧបករណ៍​ផ្គូផ្គង​ដែល​អាច​ប្រើ​បាន"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"ការជូនដំណឹង"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ការសន្ទនា"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"សម្អាត​ការជូនដំណឹង​ស្ងាត់ទាំងអស់"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ការជូនដំណឹង​បានផ្អាក​ដោយ​មុខងារកុំរំខាន"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ស្ថានភាព៖&lt;/b&gt; បានចាត់ថ្នាក់ទាបជាងមុន"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"បង្ហាញនៅខាងលើ​ការជូនដំណឹងអំពីការសន្ទនា និងជារូបភាព​កម្រង​ព័ត៌មាននៅលើអេក្រង់ចាក់សោ"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"បង្ហាញនៅខាងលើ​ការជូនដំណឹងអំពីការសន្ទនា និងជារូបភាព​កម្រង​ព័ត៌មាននៅលើអេក្រង់ចាក់សោ បង្ហាញជាពពុះ"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"បង្ហាញនៅខាងលើ​ការជូនដំណឹងអំពីការសន្ទនា និងជារូបភាព​កម្រង​ព័ត៌មាននៅលើអេក្រង់ចាក់សោ បង្អាក់មុខងារកុំ​រំខាន"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"បង្ហាញនៅខាងលើ​ការជូនដំណឹងអំពីការសន្ទនា និងជារូបភាព​កម្រង​ព័ត៌មាននៅលើអេក្រង់ចាក់សោ បង្ហាញជាពពុះ បង្អាក់មុខងារកុំ​រំខាន"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"សារ SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"តន្ត្រី"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ប្រតិទិន"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"កុំ​រំខាន"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ផ្លូវកាត់ប៊ូតុងកម្រិតសំឡេង"</string>
     <string name="battery" msgid="769686279459897127">"ថ្ម"</string>
     <string name="headset" msgid="4485892374984466437">"កាស"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi បាន​បិទ"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ប៊្លូធូស​បាន​បិទ"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"មុខងារ​កុំរំខាន​បាន​បិទ"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"មុខងារ​កុំ​រំខាន​ត្រូវបាន​បើកដោយច្បាប់​ស្វ័យ​ប្រវត្តិ (<xliff:g id="ID_1">%s</xliff:g>)។"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"មុខងារ​កុំ​រំខាន​ត្រូវបាន​បើកដោយកម្មវិធី (<xliff:g id="ID_1">%s</xliff:g>)។"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"មុខងារ​កុំ​រំខាន​ត្រូវបាន​បើកដោយច្បាប់​ស្វ័យ​ប្រវត្តិ ឬ​កម្មវិធី។"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"កម្មវិធីដែលកំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"ចុចដើម្បីមើលព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ទិន្នន័យ និងថ្ម"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"បិទទិន្នន័យទូរសព្ទចល័ត?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ការងារ)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ការហៅ​ទូរសព្ទ"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(តាមរយៈ <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"កាមេរ៉ា"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ទីតាំង"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"មីក្រូហ្វូន"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(បាន​ដាច់)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"មិនអាចប្ដូរបានទេ។ សូមចុចដើម្បី​ព្យាយាម​ម្ដងទៀត។"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ផ្គូផ្គង​ឧបករណ៍ថ្មី"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ដើម្បីភ្ជាប់វគ្គនេះ សូមបើកកម្មវិធី។"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"កម្មវិធី​ដែលមិន​ស្គាល់"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"លេខ​កំណែបង្កើត"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"បានចម្លងលេខ​កំណែបង្កើតទៅឃ្លីបបត។"</string>
     <string name="basic_status" msgid="2315371112182658176">"បើកការសន្ទនា"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"មើលព័ត៌មាន​ថ្មីៗ​អំពីស្ថានភាព ការខកខាន​ទទួល និងសារថ្មីៗ"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"ការ​សន្ទនា"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"បានផ្អាក​ដោយមុខងារ​កុំរំខាន"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> បានផ្ញើសារ៖ <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> បាន​ផ្ញើ​រូបភាព"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> មាន​បច្ចុប្បន្នភាព​ស្ថានភាព៖ <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"ព័ត៌មានថ្មី"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"កម្មវិធីសកម្ម"</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>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"បានចម្លង"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"ពី <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"ច្រានចោល UI ចម្លង"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"កែអត្ថបទ​ដែលបានចម្លង"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"កែរូបភាព​ដែលបានចម្លង"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ផ្ញើទៅ​ឧបករណ៍​នៅជិត"</string>
+    <string name="add" msgid="81036585205287996">"បញ្ចូល"</string>
+    <string name="manage_users" msgid="1823875311934643849">"គ្រប់គ្រង​អ្នក​ប្រើប្រាស់"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"ការជូនដំណឹងនេះមិនអាចឱ្យអូសដើម្បីបំបែកអេក្រង់បានទេ។"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ត្រូវបានបិទ"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"មុខងារ​អាទិភាព"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"រូបកំណត់​ម៉ោងរោទ៍"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"បានបើក​មុខងារភ្ញៀវរបស់ Assistant"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"កាមេរ៉ា និង​មីក្រូហ្វូន​ត្រូវបានបិទ"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{ការ​ជូន​ដំណឹង #}other{ការ​ជូនដំណឹង #}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index f1428a0..e10f5d3 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -20,7 +20,12 @@
 <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">"ಸಿಸ್ಟಂ UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"ಬ್ಯಾಟರಿ ಸದ್ಯದಲ್ಲೇ ಖಾಲಿಯಾಗಬಹುದು"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ಉಳಿದಿದೆ"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB ಮೂಲಕ ಚಾರ್ಜ್‌ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"ನಿಮ್ಮ ಸಾಧನದೊಂದಿಗೆ ನೀಡಲಾಗಿರುವ ಚಾರ್ಜರ್‌ ಬಳಸಿ"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ಪೂರ್ಣಗೊಳಿಸಲು ದೃಢೀಕರಿಸಿ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -176,11 +183,12 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ಅಧಿಸೂಚನೆಯ ಛಾಯೆ."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು."</string>
-    <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ಲಾಕ್‌ ಪರದೆ."</string>
+    <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ಲಾಕ್‌ ಸ್ಕ್ರೀನ್."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ಕೆಲಸದ ಲಾಕ್ ಪರದೆ"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ಮುಚ್ಚು"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ಸಂಪೂರ್ಣ ನಿಶ್ಯಬ್ಧ"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ಅಲಾರಮ್‌ಗಳು ಮಾತ್ರ"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ಅಡಚಣೆ ಮಾಡಬೇಡ."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ಬ್ಲೂಟೂತ್."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿದೆ."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> ಗಂಟೆಗೆ ಅಲಾರಮ್ ಹೊಂದಿಸಲಾಗಿದೆ."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"ಡೆಸರ್ಟ್ ಕೇಸ್"</string>
     <string name="start_dreams" msgid="9131802557946276718">"ಸ್ಕ್ರೀನ್ ಸೇವರ್"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ಇಥರ್ನೆಟ್"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"ಅಡಚಣೆ ಮಾಡಬೇಡ"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ಬ್ಲೂಟೂತ್‌"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ಯಾವುದೇ ಜೋಡಿಸಲಾದ ಸಾಧನಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ಬ್ಯಾಟರಿ"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"ಅಧಿಸೂಚನೆಗಳು"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ಸಂಭಾಷಣೆಗಳು"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ಎಲ್ಲಾ ನಿಶ್ಶಬ್ಧ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸಿ"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಎನ್ನುವ ಮೂಲಕ ಅಧಿಸೂಚನೆಗಳನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ಸ್ಥಿತಿ:&lt;/b&gt; ಕಡಿಮೆ ಸ್ಥಾನವನ್ನು ಹೊಂದಿದೆ"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"ಸಂಭಾಷಣೆ ಅಧಿಸೂಚನೆಗಳ ಮೇಲ್ಭಾಗದಲ್ಲಿ ಹಾಗೂ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲೆ ಪ್ರೊಫೈಲ್ ಚಿತ್ರವಾಗಿ ತೋರಿಸುತ್ತದೆ"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"ಸಂಭಾಷಣೆ ಅಧಿಸೂಚನೆಗಳ ಮೇಲ್ಭಾಗದಲ್ಲಿ ಹಾಗೂ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲೆ ಪ್ರೊಫೈಲ್ ಚಿತ್ರವಾಗಿ ತೋರಿಸುತ್ತದೆ, ಬಬಲ್‌ನಂತೆ ಗೋಚರಿಸುತ್ತದೆ"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"ಸಂಭಾಷಣೆ ಅಧಿಸೂಚನೆಗಳ ಮೇಲ್ಭಾಗದಲ್ಲಿ ಹಾಗೂ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲೆ ಪ್ರೊಫೈಲ್ ಚಿತ್ರವಾಗಿ ತೋರಿಸುತ್ತದೆ, ಅಡಚಣೆ ಮಾಡಬೇಡ ಮೋಡ್‌ಗೆ ಅಡ್ಡಿಯುಂಟುಮಾಡುತ್ತದೆ"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ಸಂಭಾಷಣೆ ಅಧಿಸೂಚನೆಗಳ ಮೇಲ್ಭಾಗದಲ್ಲಿ ಹಾಗೂ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲೆ ಪ್ರೊಫೈಲ್ ಚಿತ್ರವಾಗಿ ತೋರಿಸುತ್ತದೆ, ಬಬಲ್‌ನಂತೆ ಗೋಚರಿಸುತ್ತದೆ, ಅಡಚಣೆ ಮಾಡಬೇಡ ಮೋಡ್‌ಗೆ ಅಡ್ಡಿಯುಂಟುಮಾಡುತ್ತದೆ"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"ಎಸ್ಎಂಎಸ್"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ಸಂಗೀತ"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ಅಡಚಣೆ ಮಾಡಬೇಡ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ವಾಲ್ಯೂಮ್ ಬಟನ್‌ಗಳ ಶಾರ್ಟ್‌ಕಟ್‌"</string>
     <string name="battery" msgid="769686279459897127">"ಬ್ಯಾಟರಿ"</string>
     <string name="headset" msgid="4485892374984466437">"ಹೆಡ್‌ಸೆಟ್"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"ವೈ-ಫೈ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ಬ್ಲೂಟೂತ್‌ ಆಫ್ ಆಗಿದೆ"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆಫ್ ಆಗಿದೆ"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"(<xliff:g id="ID_1">%s</xliff:g>) ಸ್ವಯಂಚಾಲಿತ ನಿಯಮದ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"(<xliff:g id="ID_1">%s</xliff:g>) ಅಪ್ಲಿಕೇಶನ್‌ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ಸ್ವಯಂಚಾಲಿತ ನಿಯಮ ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್‌ ಮೂಲಕ ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಆನ್ ಆಗಿದೆ."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"ಬ್ಯಾಟರಿ,ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"ಮೊಬೈಲ್ ಡೇಟಾ ಆಫ್ ಮಾಡಬೇಕೆ?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ಉದ್ಯೋಗ)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ಫೋನ್ ಕರೆ"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> ಮೂಲಕ)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"ಕ್ಯಾಮರಾ"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ಸ್ಥಳ"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"ಮೈಕ್ರೋಫೋನ್‌"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ಡಿಸ್‌ಕನೆಕ್ಟ್ ಆಗಿದೆ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ಬದಲಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ಈ ಸೆಶನ್ ಕಾಸ್ಟ್ ಮಾಡಲು, ಆ್ಯಪ್ ಅನ್ನು ತೆರೆಯಿರಿ."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ಅಪರಿಚಿತ ಆ್ಯಪ್"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ನಲ್ಲಿ ನಕಲಿಸಲಾಗಿದೆ."</string>
     <string name="basic_status" msgid="2315371112182658176">"ಸಂಭಾಷಣೆಯನ್ನು ತೆರೆಯಿರಿ"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"ಇತ್ತೀಚಿನ ಸಂದೇಶಗಳು, ಮಿಸ್ಡ್ ಕಾಲ್‌ಗಳು ಮತ್ತು ಸ್ಥಿತಿ ಅಪ್‌ಡೇಟ್‌ಗಳು"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"ಸಂಭಾಷಣೆ"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"\'ಅಡಚಣೆ ಮಾಡಬೇಡಿ\' ನಿಂದ ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರು ಸಂದೇಶವನ್ನು ಕಳುಹಿಸಿದ್ದಾರೆ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರು ಚಿತ್ರವನ್ನು ಕಳುಹಿಸಿದ್ದಾರೆ"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರು ಸ್ಥಿತಿಯ ಅಪ್‌ಡೇಟ್ ಹೊಂದಿದ್ದಾರೆ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"ಹೊಸ ಮಾಹಿತಿ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ಸಕ್ರಿಯ ಆ್ಯಪ್‌ಗಳು"</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>
@@ -889,8 +910,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"ನಕಲಿಸಿದ ಪಠ್ಯವನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ನಕಲಿಸಿದ ಚಿತ್ರವನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಕ್ಕೆ ಕಳುಹಿಸಿ"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"ಸೇರಿಸಿ"</string>
+    <string name="manage_users" msgid="1823875311934643849">"ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಿ"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಡ್ರ್ಯಾಗ್ ಮಾಡುವುದನ್ನು ಈ ಅಧಿಸೂಚನೆಯು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ವೈ-ಫೈ ಲಭ್ಯವಿಲ್ಲ"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ಆದ್ಯತೆ ಮೋಡ್"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ಅಲಾರಾಂ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant ಅತಿಥಿ ಮೋಡ್‌ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ ಆಫ್ ಆಗಿದೆ"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ಅಧಿಸೂಚನೆ}one{# ಅಧಿಸೂಚನೆಗಳು}other{# ಅಧಿಸೂಚನೆಗಳು}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 02246b4..ba6ef05 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -20,7 +20,12 @@
 <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">"시스템 UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"배터리가 얼마 남지 않음"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> 남았습니다."</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB로 충전할 수 없습니다."</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"기기와 함께 제공된 충전기를 사용하세요."</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"얼굴이 인증되었습니다."</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"확인함"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"완료하려면 확인을 탭하세요."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"닫기"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"모두 음소거"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"알람만 허용"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"방해 금지 모드"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"블루투스"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"블루투스: 사용"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"알람이 <xliff:g id="TIME">%s</xliff:g>(으)로 설정되었습니다."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"디저트 케이스"</string>
     <string name="start_dreams" msgid="9131802557946276718">"화면 보호기"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"이더넷"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"방해 금지 모드"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"블루투스"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"페어링된 기기가 없습니다"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"알림"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"대화"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"무음 알림 모두 삭제"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"방해 금지 모드로 알림이 일시중지됨"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;상태:&lt;/b&gt; 순위 낮춤"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"대화 알림 상단에 표시, 잠금 화면에 프로필 사진으로 표시"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"대화 알림 상단에 표시, 잠금 화면에 프로필 사진으로 표시, 대화창으로 표시"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"대화 알림 상단에 표시, 잠금 화면에 프로필 사진으로 표시, 방해 금지 모드를 무시함"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"대화 알림 상단에 표시, 잠금 화면에 프로필 사진으로 표시, 대화창으로 표시, 방해 금지 모드를 무시함"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"음악"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"캘린더"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"방해 금지 모드"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"볼륨 버튼 단축키"</string>
     <string name="battery" msgid="769686279459897127">"배터리"</string>
     <string name="headset" msgid="4485892374984466437">"헤드셋"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi가 사용 중지됨"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"블루투스가 사용 중지됨"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"방해 금지 모드가 사용 중지됨"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"방해 금지 모드가 자동 규칙(<xliff:g id="ID_1">%s</xliff:g>)에 의해 사용 설정되었습니다."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"방해 금지 모드가 앱(<xliff:g id="ID_1">%s</xliff:g>)에 의해 사용 설정되었습니다."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"방해 금지 모드가 자동 규칙 또는 앱에 의해 사용 설정되었습니다."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"백그라운드에서 실행 중인 앱"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"탭하여 배터리 및 데이터 사용량 확인"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"모바일 데이터를 사용 중지하시겠습니까?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(직장)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"전화 통화"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> 사용)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"카메라"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"위치"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"마이크"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(연결 끊김)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"전환할 수 없습니다. 다시 시도하려면 탭하세요."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"새 기기와 페어링"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"세션을 전송하려면 앱을 열어 주세요"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"알 수 없는 앱"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"빌드 번호"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"빌드 번호가 클립보드에 복사되었습니다."</string>
     <string name="basic_status" msgid="2315371112182658176">"대화 열기"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"최근 메시지, 부재중 전화, 상태 업데이트 보기"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"대화"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"방해 금지 모드로 인해 일시중지됨"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>님이 메시지를 보냈습니다: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>님이 이미지를 보냈습니다."</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>님의 상태가 업데이트되었습니다: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"새로운 정보"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"활성 상태의 앱"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"복사됨"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"복사한 위치: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI 복사 닫기"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"복사된 텍스트 편집"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"복사된 이미지 편집"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"근처 기기에 전송"</string>
+    <string name="add" msgid="81036585205287996">"추가"</string>
+    <string name="manage_users" msgid="1823875311934643849">"사용자 관리"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"드래그하여 화면을 분할하는 기능이 지원되지 않는 알림입니다."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi를 이용할 수 없습니다."</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"우선순위 모드입니다."</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"알람이 설정되었습니다."</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"어시스턴트 게스트 모드가 사용 설정되었습니다."</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"카메라 및 마이크가 사용 중지되었습니다."</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index c8c56ca..a31ab6d 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -20,7 +20,12 @@
 <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">"Тутум UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Батарея жакында отуруп калышы мүмкүн"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> калды"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB аркылуу кубатталбай жатат"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Түзмөгүңүз менен келген кубаттагычты колдонуңуз"</string>
@@ -111,7 +116,7 @@
     <string name="accessibility_phone_button" msgid="4256353121703100427">"Телефон"</string>
     <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Үн жардамчысы"</string>
     <string name="accessibility_wallet_button" msgid="1458258783460555507">"Капчык"</string>
-    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR кодунун сканери"</string>
+    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR коддорунун сканери"</string>
     <string name="accessibility_unlock_button" msgid="122785427241471085">"Кулпусун ачуу"</string>
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Түзмөк кулпуланды"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Жүз скандалууда"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Жүздүн аныктыгы текшерилди"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Ырасталды"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Бүтүрүү үчүн \"Ырастоо\" баскычын басыңыз"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Жабуу"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"тымтырс"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ойготкуч гана"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Тынчымды алба."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth күйүк."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Ойготкуч кийинкиге коюлган: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Десерт себети"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Көшөгө"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Тынчымды алба"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Жупташкан түзмөктөр жок"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Билдирмелер"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Сүйлөшүүлөр"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Бардык үнсүз билдирмелерди өчүрүү"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\"Тынчымды алба\" режиминде билдирмелер тындырылды"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Абалы:&lt;/b&gt; Төмөндөдү"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Сүйлөшүүлөр тууралуу билдирмелердин жогору жагында, ошондой эле кулпуланган экранда профилдин сүрөтү түрүндө көрүнөт"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Cүйлөшүүлөр тууралуу билдирмелердин жогору жагында жана кулпуланган экранда профилдин сүрөтү, ошондой эле калкып чыкма билдирме түрүндө көрүнөт"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Cүйлөшүүлөр тууралуу билдирмелердин жогору жагында жана кулпуланган экранда профилдин сүрөтү түрүндө көрүнүп, \"Тынчымды алба\" режимин токтотот"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Cүйлөшүүлөр тууралуу билдирмелердин жогору жагында жана кулпуланган экранда профилдин сүрөтү, ошондой эле калкып чыкма билдирме түрүндө көрүнүп, \"Тынчымды алба\" режимин токтотот"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музыка"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Жылнаама"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Тынчымды алба"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Үндү көзөмөлдөөчү баскычтардын кыска жолдору"</string>
     <string name="battery" msgid="769686279459897127">"Батарея"</string>
     <string name="headset" msgid="4485892374984466437">"Гарнитура"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi өчүк"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth өчүк"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"\"Тынчымды алба\" режими өчүк"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автоматтык эреже \"Тынчымды алба\" режимин күйгүздү (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Колдонмо \"Тынчымды алба\" режимин күйгүздү (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автоматтык эреже же колдонмо \"Тынчымды алба\" режимин күйгүздү."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Фондо иштеп жаткан колдонмолор"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Батареянын кубаты жана трафиктин көлөмү жөнүндө билүү үчүн таптап коюңуз"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Мобилдик Интернетти өчүрөсүзбү?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(жумуш)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефон чалуу"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> аркылуу)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"жайгашкан жер"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ажыратылды)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Которулбай жатат. Кайталоо үчүн басыңыз."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңы түзмөктү жупташтыруу"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бул сеансты тышкы экранга чыгаруу үчүн колдонмону ачыңыз."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгисиз колдонмо"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Курама номери"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Курама номери алмашуу буферине көчүрүлдү."</string>
     <string name="basic_status" msgid="2315371112182658176">"Ачык сүйлөшүү"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Акыркы билдирүүлөрдү, жооп берилбеген чалууларды жана статустардын жаңырганын көрөсүз"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Сүйлөшүү"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"\"Тынчымды алба\" режими тындырды"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> билдирүү жөнөттү: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> сүрөт жөнөттү"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> жаңы абалы тууралуу жарыялады: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Жаңы маалымат"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Жигердүү колдонмолор"</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>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Көчүрүлдү"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> колдонмосунан"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Көчүрмөнү жабуу интерфейси"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Көчүрүлгөн текстти түзөтүү"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Көчүрүлгөн сүрөттү түзөтүү"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Жакын жердеги түзмөккө жөнөтүү"</string>
+    <string name="add" msgid="81036585205287996">"Кошуу"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Колдонуучуларды башкаруу"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Бул билдирмени бөлүнгөн экранда сүйрөөгө болбойт."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi жеткиликсиз"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Маанилүү сүйлөшүүлөр режими"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ойготкуч коюлду"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Жардамчынын конок режими иштетилди"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера жана микрофон өчүк"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# билдирме}other{# билдирме}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-land/styles.xml b/packages/SystemUI/res/values-land/styles.xml
index f3d83645..8919198 100644
--- a/packages/SystemUI/res/values-land/styles.xml
+++ b/packages/SystemUI/res/values-land/styles.xml
@@ -18,15 +18,4 @@
     <style name="BrightnessDialogContainer" parent="@style/BaseBrightnessDialogContainer">
         <item name="android:layout_width">360dp</item>
     </style>
-
-    <style name="DockedDividerBackground">
-        <item name="android:layout_width">10dp</item>
-        <item name="android:layout_height">match_parent</item>
-        <item name="android:layout_gravity">center_horizontal</item>
-    </style>
-
-    <style name="DockedDividerMinimizedShadow">
-        <item name="android:layout_width">8dp</item>
-        <item name="android:layout_height">match_parent</item>
-    </style>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 6b96c1a..204e3d9 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"ແບັດເຕີຣີໃກ້ຈະໝົດແລ້ວ"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"ຍັງ​ເຫຼືອ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"ບໍ່ສາມາດສາກຜ່ານ USB ໄດ້"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"ກະລຸນາໃຊ້ຕົວສາກທີ່ມາພ້ອມກັບອຸປະກອນຂອງທ່ານ"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ພິສູດຢືນຢັນໃບໜ້າແລ້ວ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ຢືນຢັນແລ້ວ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ແຕະຢືນຢັນເພື່ອສຳເລັດ"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ປິດ"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ງຽບທັງໝົດ"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ໂມງປຸກເທົ່ານັ້ນ"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ຫ້າມລົບກວນ."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ເປີດ."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ຕັ້ງໂມງປຸກ <xliff:g id="TIME">%s</xliff:g> ແລ້ວ."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"ກ່ອງຂອງຫວານ"</string>
     <string name="start_dreams" msgid="9131802557946276718">"ພາບພັກໜ້າຈໍ"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"ຫ້າມລົບກວນ"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ບໍ່​ມີ​ອຸ​ປະ​ກອນ​ທີ່​ສາ​ມາດ​ຈັບ​ຄູ່​ໄດ້"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"ການແຈ້ງເຕືອນ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ການສົນທະນາ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ລຶບລ້າງການແຈ້ງເຕືອນແບບງຽບທັງໝົດ"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ຢຸດການແຈ້ງເຕືອນໂດຍໂໝດຫ້າມລົບກວນແລ້ວ"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ສະຖານະ:&lt;/b&gt; ມີອັນດັບຕ່ຳລົງແລ້ວ"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"ສະແດງຢູ່ເທິງສຸດຂອງການແຈ້ງເຕືອນການສົນທະນາ ແລະ ເປັນຮູບໂປຣໄຟລ໌ຢູ່ໜ້າຈໍລັອກ"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"ສະແດງຢູ່ເທິງສຸດຂອງການແຈ້ງເຕືອນການສົນທະນາ ແລະ ເປັນຮູບໂປຣໄຟລ໌ຢູ່ໜ້າຈໍລັອກ, ປາກົດເປັນຟອງ"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"ສະແດງຢູ່ເທິງສຸດຂອງການແຈ້ງເຕືອນການສົນທະນາ ແລະ ເປັນຮູບໂປຣໄຟລ໌ຢູ່ໜ້າຈໍລັອກ, ສະແດງໃນໂໝດຫ້າມລົບກວນໄດ້"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ສະແດງຢູ່ເທິງສຸດຂອງການແຈ້ງເຕືອນການສົນທະນາ ແລະ ເປັນຮູບໂປຣໄຟລ໌ຢູ່ໜ້າຈໍລັອກ, ປາກົດເປັນຟອງ, ສະແດງໃນໂໝດຫ້າມລົບກວນໄດ້"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"ຂໍ້ຄວາມສັ້ນ(SMS)"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ດົນຕີ"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ປະຕິທິນ"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ຫ້າມລົບກວນ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ທາງລັດປຸ່ມສຽງ"</string>
     <string name="battery" msgid="769686279459897127">"ແບັດເຕີຣີ"</string>
     <string name="headset" msgid="4485892374984466437">"​ຊຸດ​ຫູ​ຟັງ"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ປິດຢູ່"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ປິດຢູ່"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"ຫ້າມລົບກວນ ປິດຢູ່"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ໂໝດຫ້າມລົບກວນຖືກເປີດໃຊ້ໂດຍກົດອັດຕະໂນມັດ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ມີແອັບເປີດໃຊ້ໂໝດຫ້າມລົບກວນ (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ໂໝດຫ້າມລົບກວນຖືກເປີດໃຊ້ໂດຍກົດອັດຕະໂນມັດ ຫຼື ແອັບໃດໜຶ່ງ."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"ແອັບທີ່ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"ແຕະເພື່ອເບິ່ງລາຍລະອຽດການນຳໃຊ້ແບັດເຕີຣີ ແລະ ອິນເຕີເນັດ"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"ປິດອິນເຕີເນັດມືຖືໄວ້ບໍ?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ວຽກ)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ໂທລະສັບ"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(ຜ່ານ <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"ກ້ອງຖ່າຍຮູບ"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ສະຖານທີ່"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"ໄມໂຄຣໂຟນ"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ຕັດການເຊື່ອມຕໍ່ແລ້ວ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ບໍ່ສາມາດສະຫຼັບໄດ້. ແຕະເພື່ອລອງໃໝ່."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ຈັບຄູ່ອຸປະກອນໃໝ່"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ເພື່ອສົ່ງສັນຍານເຊດຊັນນີ້, ກະລຸນາເປີດແອັບ."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ແອັບທີ່ບໍ່ຮູ້ຈັກ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string>
     <string name="basic_status" msgid="2315371112182658176">"ເປີດການສົນທະນາ"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"ເບິ່ງຂໍ້ຄວາມຫຼ້າສຸດ, ສາຍບໍ່ໄດ້ຮັບ ແລະ ອັບເດດສະຖານະ"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"ການສົນທະນາ"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"ຢຸດຊົ່ວຄາວແລ້ວໂດຍໂໝດຫ້າມລົບກວນ"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ສົ່ງຂໍ້ຄວາມ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ສົ່ງຮູບພາບແລ້ວ"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ອັບເດດສະຖານະ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"ຂໍ້ມູນໃໝ່"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ແອັບທີ່ນຳໃຊ້ຢູ່"</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>
@@ -889,8 +910,14 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"ແກ້ໄຂຂໍ້ຄວາມທີ່ສຳເນົາແລ້ວ"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ແກ້ໄຂຮູບທີ່ສຳເນົາແລ້ວ"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ສົ່ງໄປຫາອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="add" msgid="81036585205287996">"ເພີ່ມ"</string>
+    <string name="manage_users" msgid="1823875311934643849">"ຈັດການຜູ້ໃຊ້"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"ການແຈ້ງເຕືອນນີ້ບໍ່ຮອງຮັບການລາກໄປໃສ່ Splitscreen."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ບໍ່ສາມາດໃຊ້ Wi‑Fi ໄດ້"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ໂໝດຄວາມສຳຄັນ"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ຕັ້ງໂມງປຸກແລ້ວ"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"ເປີດການນຳໃຊ້ໂໝດແຂກຜູ້ຊ່ວຍແລ້ວ"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ປິດກ້ອງຖ່າຍຮູບ ແລະ ໄມແລ້ວ"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 5179ad9..6bcfa0e 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -20,7 +20,12 @@
 <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">"Sistemos NS"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Akumuliatoriaus energija gali netrukus išsekti"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Liko <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Negalima įkrauti naudojant USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Naudokite originalų su įrenginiu pateiktą įkroviklį"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Veidas autentifikuotas"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Uždaryti"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"visiška tyla"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"tik įspėjimai"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Netrukdymo režimas."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"„Bluetooth“."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"„Bluetooth“ įjungtas."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Signalas nustatytas <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Desertų dėklas"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Ekrano užsklanda"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Eternetas"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Netrukdymo režimas"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nėra pasiekiamų susietų įrenginių"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumuliatorius: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Pranešimai"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Pokalbiai"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Išvalyti visus tylius pranešimus"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Pranešimai pristabdyti naudojant netrukdymo režimą"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Pradėti dabar"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nėra įspėjimų"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šį įrenginį tvarko vienas iš tavo tėvų"</string>
@@ -497,6 +507,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Būsenos:&lt;/b&gt; reitingas sumažintas"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane, burbule"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane, pertraukia netrukdymo režimą"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane, debesėlyje, pertraukia netrukdymo režimą"</string>
     <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>
@@ -576,6 +588,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendorius"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Netrukdymo režimas"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Garsumo mygtukų spartusis klavišas"</string>
     <string name="battery" msgid="769686279459897127">"Akumuliatorius"</string>
     <string name="headset" msgid="4485892374984466437">"Ausinės"</string>
@@ -694,6 +707,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"„<xliff:g id="CARRIER_NAME">%1$s</xliff:g>“, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"„Wi-Fi“ išjungtas"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"„Bluetooth“ išjungtas"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Netrukdymo režimas išjungtas"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Netrukdymo režimą įjungė automatinė taisyklė (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Netrukdymo režimą įjungė programa (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Netrukdymo režimą įjungė automatinė taisyklė arba programa."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Programos, veikiančios fone"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Palieskite ir sužinokite išsamios informacijos apie akumuliatoriaus bei duomenų naudojimą"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Išjungti mobiliojo ryšio duomenis?"</string>
@@ -718,6 +735,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(darbas)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefono skambutis"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(naud. <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparatą"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"vietovę"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoną"</string>
@@ -818,6 +837,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(atjungta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nepavyko perjungti. Bandykite vėl palietę."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Naujo įrenginio susiejimas"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jei norite perduoti šį seansą, atidarykite programą."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nežinoma programa"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string>
     <string name="basic_status" msgid="2315371112182658176">"Atidaryti pokalbį"</string>
@@ -851,6 +872,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g> +"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Peržiūrėkite naujausius pranešimus, praleistus skambučius ir būsenos atnaujinimus"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Pokalbis"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Pristabdyta dėl netrukdymo režimo"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> išsiuntė pranešimą: „<xliff:g id="NOTIFICATION">%2$s</xliff:g>“"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> išsiuntė vaizdą"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atnaujino būseną: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
       <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> aktyvios programos</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktyvių programų</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nauja informacija"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktyvios programos"</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>
@@ -903,8 +924,14 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Redaguoti nukopijuotą tekstą"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Redaguoti nukopijuotą vaizdą"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Siųsti į įrenginį netoliese"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="add" msgid="81036585205287996">"Pridėti"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Tvarkyti naudotojus"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Šio pranešimo vilkimas išskaidyto ekrano režimu nepalaikomas."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"„Wi‑Fi“ ryšys nepasiekiamas"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteto režimas"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signalas nustatytas"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Įgalintas Padėjėjo svečio režimas"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Vaizdo kamera ir mikrofonas išjungti"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 63b6b2e..286cdec 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -20,7 +20,12 @@
 <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">"Sistēmas UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Akumulators, iespējams, drīz izlādēsies"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Atlikuši <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Nevar veikt uzlādi, izmantojot USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Izmantojiet ierīces komplektācijā iekļauto lādētāju"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Seja autentificēta"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Aizvērt"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"pilnīgs klusums"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"tikai signāli"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Režīms “Netraucēt”."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth savienojums ir ieslēgts."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Signāls ir iestatīts uz: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Saldo ēdienu stends"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Ekrānsaudzētājs"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Tīkls Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Režīms “Netraucēt”"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nav pieejama neviena pārī savienota ierīce."</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumulators: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -351,6 +360,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Paziņojumi"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Sarunas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Notīrīt visus klusos paziņojumus"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Paziņojumi pārtraukti, izmantojot iestatījumu “Netraucēt”"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Sākt tūlīt"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nav paziņojumu"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šo ierīci pārvalda viens no jūsu vecākiem."</string>
@@ -494,6 +504,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Statuss:&lt;/b&gt; rangs pazemināts"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Parādās sarunu paziņojumu augšdaļā un kā profila attēls bloķēšanas ekrānā."</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Parādās sarunu paziņojumu augšdaļā un kā profila attēls bloķēšanas ekrānā, arī kā burbulis."</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Parādās sarunu paziņojumu augšdaļā un kā profila attēls bloķēšanas ekrānā, pārtrauc režīmu “Netraucēt”."</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Parādās sarunu paziņojumu augšdaļā un kā profila attēls bloķēšanas ekrānā, arī kā burbulis, pārtrauc režīmu “Netraucēt”."</string>
     <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>
@@ -571,6 +583,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Īsziņas"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Mūzika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendārs"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Režīms “Netraucēt”"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Skaļuma pogu saīsne"</string>
     <string name="battery" msgid="769686279459897127">"Akumulators"</string>
     <string name="headset" msgid="4485892374984466437">"Austiņas"</string>
@@ -689,6 +702,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ir izslēgts"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ir izslēgts"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Režīms “Netraucēt” ir izslēgts"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režīmu “Netraucēt” ieslēdza automātiska kārtula (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režīmu “Netraucēt” ieslēdza lietotne (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režīmu “Netraucēt” ieslēdza automātiska kārtula vai lietotne."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Lietotnes, kas darbojas fonā"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Pieskarieties, lai skatītu detalizētu informāciju par akumulatora un datu lietojumu"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Vai izslēgt mobilos datus?"</string>
@@ -713,6 +730,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(darbs)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Tālruņa zvans"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(izmantojot: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"atrašanās vieta"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofons"</string>
@@ -812,6 +831,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(savienojums pārtraukts)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nevar pārslēgt. Pieskarieties, lai mēģinātu vēlreiz."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Savienošana pārī ar jaunu ierīci"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Lai apraidītu šo sesiju, lūdzu, atveriet lietotni."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nezināma lietotne"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijas numurs"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versijas numurs ir kopēts starpliktuvē."</string>
     <string name="basic_status" msgid="2315371112182658176">"Atvērt sarunu"</string>
@@ -845,6 +866,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Skatiet jaunākos ziņojumus, neatbildētos zvanus un statusa atjauninājumus."</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Saruna"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Rādīšana pārtraukta režīma Netraucēt dēļ"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> nosūtīja ziņojumu: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> nosūtīja attēlu"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atjaunināja statusu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
       <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aktīva lietotne</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktīvas lietotnes</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Jauna informācija"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktīvās lietotnes"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Apturēt"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Apturēta"</string>
@@ -893,14 +914,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Nokopēts"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"No lietotnes <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Noraidīt ar kopēšanu saistīto lietotāja saskarnes elementu"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Rediģēt nokopēto tekstu"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Rediģēt nokopēto attēlu"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Sūtīt uz tuvumā esošu ierīci"</string>
+    <string name="add" msgid="81036585205287996">"Pievienot"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Pārvaldīt lietotājus"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Šis paziņojums neatbalsta vilkšanu uz dalīto ekrānu."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nav pieejams"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritātes režīms"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signāls ir iestatīts"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Asistenta viesa režīms ir iespējots"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera un mikrofons ir izslēgti"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 7642a9a..ffa0e58 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"Наскоро може да снема батерија"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Преостануваат <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Не може да се полни преку USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Користете го полначот што дојде со вашиот уред"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицето е проверено"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврдено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Допрете „Потврди“ за да се заврши"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Затвори"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"целосна тишина"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"само аларми"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не вознемирувај."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth е вклучен."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Аларм наместен за <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Заштитник на екран"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Етернет"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не вознемирувај"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Нема достапни спарени уреди"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батерија"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Известувања"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Разговори"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Избриши ги сите бесчујни известувања"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Известувањата се паузирани од „Не вознемирувај“"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Статус:&lt;/b&gt; рангирано пониско"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Се прикажува најгоре во известувањата за разговор и како профилна слика на заклучен екран"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Се прикажува најгоре во известувањата за разговор и како профилна слика на заклучен екран, се појавува како балонче"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Се прикажува најгоре во известувањата за разговор и како профилна слика на заклучен екран, го прекинува „Не вознемирувај“"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Се прикажува најгоре во известувањата за разговор и како профилна слика на заклучен екран, се појавува како балонче, го прекинува „Не вознемирувај“"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не вознемирувај"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Кратенка за копчињата за јачина на звук"</string>
     <string name="battery" msgid="769686279459897127">"Батерија"</string>
     <string name="headset" msgid="4485892374984466437">"Слушалки"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi е исклучено"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth е исклучен"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"„Не вознемирувај“ е исклучено"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Едно автоматско правило (<xliff:g id="ID_1">%s</xliff:g>) ја вклучи „Не вознемирувај“."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Една апликација (<xliff:g id="ID_1">%s</xliff:g>) ја вклучи „Не вознемирувај“."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Едно автоматско правило или апликација ја вклучи „Не вознемирувај“."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Апликациите се извршуваат во заднина"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Допрете за детали за батеријата и потрошениот интернет"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Да се исклучи мобилниот интернет?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(службена)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонски повик"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(преку <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"локација"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(врската е прекината)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не се префрла. Допрете и обидете се пак."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спарете нов уред"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да ја емитувате сесијава, отворете ја апликацијата."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број на верзија"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Бројот на верзијата е копиран во привремената меморија."</string>
     <string name="basic_status" msgid="2315371112182658176">"Започни разговор"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Видете ги неодамнешните пораки, пропуштени повици и промени на статусот"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Разговор"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Паузирано од „Не вознемирувај“"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> испрати порака: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> испрати слика"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има ажурирање на статусот: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нови информации"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активни апликации"</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>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Од <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Отфрли го корисничкиот интерфејс за копирање"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Изменете го копираниот текст"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Изменете ја копираната слика"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Испратете до уред во близина"</string>
+    <string name="add" msgid="81036585205287996">"Додај"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Управувајте со корисниците"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Известувањево не поддржува влечење на поделен екран."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi е недостапна"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетен режим"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Алармот е наместен"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Режимот на гостин за „Помошникот“ е овозможен"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонот се исклучени"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известување}one{# известување}other{# известувања}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 1bde5a0..6aeb7e7 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -20,7 +20,12 @@
 <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">"സിസ്റ്റം UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"ബാറ്ററി ഉടൻ തീർന്നേക്കാം"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB വഴി ചാർജ് ചെയ്യാനാകില്ല"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"ഉപകരണത്തിനൊപ്പം ലഭിച്ച ചാർജർ ഉപയോഗിക്കുക"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"മുഖം പരിശോധിച്ചുറപ്പിച്ചു"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"സ്ഥിരീകരിച്ചു"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"പൂർത്തിയാക്കാൻ സ്ഥിരീകരിക്കുക ടാപ്പ് ചെയ്യൂ"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"അവസാനിപ്പിക്കുക"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"പൂർണ്ണ നിശബ്‌ദത"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"അലാറങ്ങൾ മാത്രം"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ശല്യപ്പെടുത്തരുത്."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ബ്ലൂടൂത്ത് ഓണാണ്."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g>-ന് അലാറം സജ്ജീകരിച്ചു."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"ഡെസേർട്ട് കെയ്സ്"</string>
     <string name="start_dreams" msgid="9131802557946276718">"സ്ക്രീൻ സേവർ"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ഇതർനെറ്റ്"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"ശല്യപ്പെടുത്തരുത്"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ജോടിയാക്കിയ ഉപകരണങ്ങളൊന്നും ലഭ്യമല്ല"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ബാറ്ററി"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"അറിയിപ്പുകൾ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"സംഭാഷണങ്ങൾ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"എല്ലാ നിശബ്‌ദ അറിയിപ്പുകളും മായ്ക്കുക"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ശല്യപ്പെടുത്തരുത്\' വഴി അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തി"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;നില:&lt;/b&gt; താഴ്ന്ന റാങ്കിംഗ് നൽകി"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും കാണിക്കുന്നു"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും കാണിക്കുന്നു, ഒരു ബബിൾ രൂപത്തിൽ ദൃശ്യമാകുന്നു"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും കാണിക്കുന്നു, ശല്യപ്പെടുത്തരുത് മോഡ് തടസ്സപ്പെടുത്തുന്നു"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും ബബിൾ രൂപത്തിൽ ദൃശ്യമാകുന്നു, ശല്യപ്പെടുത്തരുത് മോഡ് തടസ്സപ്പെടുത്തുന്നു"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS:"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"സംഗീതം"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ശല്യപ്പെടുത്തരുത്"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"വോളിയം ബട്ടൺ കുറുക്കുവഴി"</string>
     <string name="battery" msgid="769686279459897127">"ബാറ്ററി"</string>
     <string name="headset" msgid="4485892374984466437">"ഹെഡ്‌സെറ്റ്"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"വൈഫൈ ഓഫാണ്"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth ഓഫാണ്"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"\'ശല്യപ്പെടുത്തരുത്\' ഓഫാണ്"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"സ്വയമേവയുള്ള ഒരു നയം (<xliff:g id="ID_1">%s</xliff:g>) \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ഒരു ആപ്പ് (<xliff:g id="ID_1">%s</xliff:g>) \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"സ്വയമേവയുള്ള ഒരു നയമോ ആപ്പോ \'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കിയിരിക്കുന്നു."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"ആപ്പുകൾ പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"ബാറ്ററി, ഡാറ്റ ഉപയോഗം എന്നിവയുടെ വിശദാംശങ്ങളറിയാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"മൊബൈൽ ഡാറ്റ ഓഫാക്കണോ?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ഔദ്യോഗികം)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ഫോൺ കോൾ"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> എന്നതിലൂടെ)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"ക്യാമറ"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ലൊക്കേഷന്‍"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"മൈക്രോഫോൺ"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(വിച്ഛേദിച്ചു)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"മാറാനാകുന്നില്ല. വീണ്ടും ശ്രമിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"പുതിയ ഉപകരണവുമായി ജോടിയാക്കുക"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ഈ സെഷൻ കാസ്റ്റ് ചെയ്യാൻ, ആപ്പ് തുറക്കുക."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"അജ്ഞാതമായ ആപ്പ്"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ബിൽഡ് നമ്പർ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ക്ലിപ്പ്ബോർഡിലേക്ക് ബിൽഡ് നമ്പർ പകർത്തി."</string>
     <string name="basic_status" msgid="2315371112182658176">"സംഭാഷണം തുറക്കുക"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"അടുത്തിടെയുള്ള സന്ദേശങ്ങൾ, മിസ്‌ഡ് കോൾ, സ്റ്റാറ്റസ് അപ്‌ഡേറ്റുകൾ എന്നിവ കാണൂ"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"സംഭാഷണം"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"\'ശല്യപ്പെടുത്തരുത്\' ഓണായതിനാൽ തൽക്കാലം നിർത്തി"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ഒരു സന്ദേശം അയച്ചു: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>, ഒരു ചിത്രം അയച്ചു"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> എന്നയാൾ സ്‌റ്റാറ്റസ് അപ്‌ഡേറ്റ് ചെയ്‌തു: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"പുതിയ വിവരങ്ങൾ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"സജീവമായ ആപ്പുകൾ"</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>
@@ -889,8 +910,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"പകർത്തിയ ടെക്സ്റ്റ് എഡിറ്റ് ചെയ്യുക"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"പകർത്തിയ ചിത്രം എഡിറ്റ് ചെയ്യുക"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"സമീപത്തുള്ള ഉപകരണത്തിലേക്ക് അയയ്ക്കുക"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"ചേർക്കുക"</string>
+    <string name="manage_users" msgid="1823875311934643849">"ഉപയോക്താക്കളെ മാനേജ് ചെയ്യുക"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"സ്പ്ലിറ്റ് സ്ക്രീനിലേക്ക് വലിച്ചിടുന്നതിനെ ഈ അറിയിപ്പ് പിന്തുണയ്ക്കുന്നില്ല."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"വൈഫൈ ലഭ്യമല്ല"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"മുൻഗണനാ മോഡ്"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"അലാറം സജ്ജീകരിച്ചു"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"സഹായി അതിഥി മോഡ് പ്രവർത്തനക്ഷമമാക്കി"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ക്യാമറയും മൈക്കും ഓഫാണ്"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# അറിയിപ്പ്}other{# അറിയിപ്പുകൾ}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index c63bd3d..4abfe1b 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -20,7 +20,12 @@
 <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">"Систем UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Батaрей удахгүй дуусaж болзошгүй"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> үлдсэн"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB-р цэнэглэх боломжгүй байна"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Төхөөрөмждөө дагалдаж ирсэн цэнэглэгчийг ашиглах"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Царайг баталгаажууллаа"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Баталгаажсан"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Дуусгахын тулд баталгаажуулахыг товших"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Хаах"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"бүх дууг хаах"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"зөвхөн сэрүүлэг"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Бүү саад бол."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth идэвхтэй."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Сэрүүлгийг <xliff:g id="TIME">%s</xliff:g>-д тохируулсан."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Амттаны хайрцаг"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Дэлгэц амраагч"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Этернет"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Бүү саад бол"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Хослуулсан төхөөрөмж байхгүй"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батерей"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Мэдэгдлүүд"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Харилцан яриа"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Бүх чимээгүй мэдэгдлийг арилгах"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Бүү саад бол горимын түр зогсоосон мэдэгдэл"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Төлөв:&lt;/b&gt; Доогуур зэрэглэл хийсэн"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Харилцан ярианы дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулна"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд бөмбөлөг хэлбэрээр харагдана"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд Бүү саад бол горимыг тасалдуулна"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд бөмбөлөг хэлбэрээр харагдана. Бүү саад бол горимыг тасалдуулна"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Хөгжим"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календарь"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Бүү саад бол"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Дууны түвшний товчлуурын товчлол"</string>
     <string name="battery" msgid="769686279459897127">"Батарей"</string>
     <string name="headset" msgid="4485892374984466437">"Чихэвч"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi унтраалттай байна"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth унтраалттай байна"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Бүү саад бол горим унтраалттай байна"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автомат дүрэм (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апп (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автомат дүрэм эсвэл апп Бүү саад бол горимыг асаасан."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Цаана ажиллаж буй апп"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Мобайл датаг унтраах уу?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ажил)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Утасны дуудлага"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>-р)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"камер"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"байршил"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(салсан)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Сэлгэх боломжгүй. Дахин оролдохын тулд товшино уу."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Шинэ төхөөрөмж хослуулах"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Энэ үйл явдлыг дамжуулахын тулд аппыг нээнэ үү."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Үл мэдэгдэх апп"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Хийцийн дугаар"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Хийцийн дугаарыг түр санах ойд хуулсан."</string>
     <string name="basic_status" msgid="2315371112182658176">"Харилцан яриаг нээх"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Саяхны мессеж, аваагүй дуудлага болон төлөвийн шинэчлэлтийг харах"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Харилцан яриа"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Бүү саад бол горимоор түр зогсоосон"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> мессеж илгээсэн: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> зураг илгээсэн"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> төлөвийн шинэчлэлт хийсэн байна: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Шинэ мэдээлэл"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Идэвхтэй аппууд"</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>
@@ -889,8 +910,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Хуулсан текстийг засах"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Хуулсан зургийг засах"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Ойролцоох төхөөрөмж рүү илгээх"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"Нэмэх"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Хэрэглэгчдийг удирдах"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Энэ мэдэгдэл нь Дэлгэцийг хуваах горим руу чирэхийг дэмждэггүй."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi боломжгүй"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Чухал горим"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Сэрүүлгийг тохируулсан"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Туслахын зочны горимыг идэвхжүүлсэн"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камер болон микрофон унтраалттай байна"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# мэдэгдэл}other{# мэдэгдэл}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index fca67d2..2ec0073 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -20,7 +20,12 @@
 <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">"सिस्टीम UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"बॅटरी लवकर संपू शकते"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> शिल्लक"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB द्वारे चार्ज होऊ शकत नाही"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"तुमच्या डिव्हाइससह आलेल्या चार्जरचा वापर करा"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"चेहरा ऑथेंटिकेशन केलेला आहे"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"निश्चित केले"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूर्ण करण्यासाठी खात्री करा वर टॅप करा"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"बंद करा"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"संपूर्ण शांतता"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"फक्‍त अलार्म"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"व्यत्यय आणू नका."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ब्लूटूथ."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ब्लूटूथ सुरू."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> साठी अलार्म सेट केला."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"मिष्ठान्न प्रकरण"</string>
     <string name="start_dreams" msgid="9131802557946276718">"स्क्रीन सेव्हर"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"इथरनेट"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"व्यत्यय आणू नका"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ब्लूटूथ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"कोणतेही जोडलेले डिव्हाइसेस उपलब्ध नाहीत"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> बॅटरी"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचना"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"संभाषणे"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"सर्व सायलंट सूचना साफ करा"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"व्यत्यय आणून नकाद्वारे सूचना थांबवल्या"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;स्थिती&lt;/b&gt; ला थोडी कमी म्हणून रँक केले गेले"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, बबल म्हणून दिसते"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, व्यत्यय आणू नका यामध्ये अडथळा आणते"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, बबल म्हणून दिसते, व्यत्यय आणू नका यामध्ये अडथळा आणते"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"संगीत"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"कॅलेंडर"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"व्यत्यय आणू नका"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"आवाजाच्या बटणांचा शार्टकट"</string>
     <string name="battery" msgid="769686279459897127">"बॅटरी"</string>
     <string name="headset" msgid="4485892374984466437">"हेडसेट"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"वाय-फाय बंद आहे"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ब्लूटूथ बंद आहे"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"व्यत्यय आणू नका बंद आहे"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"व्यत्यय आणू नका एका <xliff:g id="ID_1">%s</xliff:g> स्वयंचलित नियमाने सुरू केले."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"व्यत्यय आणू नका (<xliff:g id="ID_1">%s</xliff:g>) ॲपने सुरू केले."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"व्यत्यय आणू नका एका स्वयंचलित नियमाने किंवा ॲपने सुरू केले."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"अ‍ॅप्स बॅकग्राउंडमध्‍ये सुरू आहेत"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"बॅटरी आणि डेटा वापराच्‍या तपशीलांसाठी टॅप करा"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"मोबाइल डेटा बंद करायचा?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ऑफिस)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"फोन कॉल"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> द्वारे)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"स्थान"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"मायक्रोफोन"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिस्कनेक्ट केलेले)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"स्विच करू शकत नाही. पुन्हा प्रयत्न करण्यासाठी टॅप करा."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नवीन डिव्हाइससोबत पेअर करा"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"हे सेशन कास्ट करण्यासाठी, कृपया ॲप उघडा."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात अ‍ॅप"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर क्लिपबोर्डवर कॉपी केला."</string>
     <string name="basic_status" msgid="2315371112182658176">"संभाषण उघडा"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"अलीकडील मेसेज, मिस्ड कॉल आणि स्टेटस अपडेट पहा"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"संभाषण"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"व्यत्यय आणू नका द्वारे थांबवले गेले"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> यांनी मेसेज पाठवला: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> यांनी इमेज पाठवली"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> यांनी स्टेटस अपडेट केले: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"नवीन माहिती"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"अ‍ॅक्टिव्ह ॲप्स"</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>
@@ -889,8 +910,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"कॉपी केलेला मजकूर संपादित करा"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"कॉपी केलेली इमेज संपादित करा"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"जवळपासच्या डिव्हाइसवर पाठवा"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"जोडा"</string>
+    <string name="manage_users" msgid="1823875311934643849">"वापरकर्ते व्यवस्‍थापित करा"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"ही सूचना स्प्लिटस्क्रीनवर ड्रॅग करण्याला सपोर्ट करत नाही."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"वाय-फाय उपलब्ध नाही"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राधान्य मोड"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट केला"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant चा अतिथी मोड सुरू केला"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कॅमेरा आणि माइक बंद आहेत"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}other{# सूचना}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index b87a79c..06270d7 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI Sistem"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Bateri mungkin kehabisan tidak lama lagi"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> yang tinggal"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Tidak dapat mengecas melalui USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Gunakan pengecas yang disertakan dengan peranti anda"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Wajah disahkan"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Disahkan"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ketik Sahkan untuk menyelesaikan"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Disahkan"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gunakan PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gunakan corak"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Tutup"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"senyap sepenuhnya"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"penggera sahaja"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Jangan Ganggu."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth dihidupkan."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Penggera ditetapkan pada <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Bekas Pencuci Mulut"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Penyelamat skrin"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Jangan Ganggu"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Tiada peranti berpasangan tersedia"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Pemberitahuan"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Perbualan"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Kosongkan semua pemberitahuan senyap"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Pemberitahuan dijeda oleh Jangan Ganggu"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Mulakan sekarang"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Tiada pemberitahuan"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Peranti ini diurus oleh ibu bapa anda"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Dinilai Lebih Rendah"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Ditunjukkan di bahagian atas pemberitahuan perbualan dan sebagai gambar profil pada skrin kunci"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Ditunjukkan di bahagian atas pemberitahuan perbualan dan sebagai gambar profil pada skrin kunci, muncul sebagai gelembung"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Ditunjukkan di bahagian atas pemberitahuan perbualan dan sebagai gambar profil pada skrin kunci, mengganggu Jangan Ganggu"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ditunjukkan di bahagian atas pemberitahuan perbualan dan sebagai gambar profil pada skrin kunci, muncul sebagai gelembung, mengganggu Jangan Ganggu"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Keutamaan"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak menyokong ciri perbualan"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Pemberitahuan ini tidak boleh diubah suai."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Jangan Ganggu"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Pintasan butang kelantangan"</string>
     <string name="battery" msgid="769686279459897127">"Bateri"</string>
     <string name="headset" msgid="4485892374984466437">"Set Kepala"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi dimatikan"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth dimatikan"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Jangan Ganggu dimatikan"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Jangan Ganggu dihidupkan oleh peraturan automatik (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Jangan Ganggu dihidupkan oleh apl (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Jangan Ganggu dihidupkan oleh peraturan automatik atau apl."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apl yang berjalan di latar belakang"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Ketik untuk mendapatkan butiran tentang penggunaan kuasa bateri dan data"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Matikan data mudah alih?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(kerja)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Panggilan telefon"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(melalui <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"lokasi"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(diputuskan sambungan)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Tidak dapat menukar. Ketik untuk mencuba lagi."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Gandingkan peranti baharu"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Untuk menghantar sesi ini, sila buka apl."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Apl yang tidak diketahui"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nombor binaan"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nombor binaan disalin ke papan keratan."</string>
     <string name="basic_status" msgid="2315371112182658176">"Buka perbualan"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Lihat mesej terbaharu, panggilan terlepas dan kemaskinian status"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Perbualan"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Dijeda oleh Jangan Ganggu"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> menghantar mesej: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> menghantar imej"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> mempunyai kemaskinian status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apl aktif</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> apl aktif</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Maklumat baharu"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apl aktif"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Berhenti"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Dihentikan"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Disalin"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Daripada <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ketepikan penyalinan UI"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit teks yang disalin"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit imej yang disalin"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Hantar ke peranti berdekatan"</string>
+    <string name="add" msgid="81036585205287996">"Tambah"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Urus pengguna"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Pemberitahuan ini tidak menyokong penyeretan ke Skrin pisah."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi dimatikan"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mod keutamaan"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Penggera ditetapkan"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Mod tetamu Assistant didayakan"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon dimatikan"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 0248d10..4a4f1a1 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -20,7 +20,12 @@
 <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">"စနစ်၏ UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"မကြာမီ ဘက်ထရီကုန်သွားနိုင်ပါသည်"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ကျန်ရှိနေ"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB ဖြင့် အားသွင်း၍မရပါ"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"သင့်စက်ပစ္စည်းနှင့် အတူပါလာသည့် အားသွင်းကိရိယာကို အသုံးပြုပါ"</string>
@@ -111,7 +116,7 @@
     <string name="accessibility_phone_button" msgid="4256353121703100427">"ဖုန်း"</string>
     <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"အသံ အကူအညီ"</string>
     <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
-    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR ကုဒ် စကင်ဖတ်စနစ်"</string>
+    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR ကုဒ်ဖတ်စနစ်"</string>
     <string name="accessibility_unlock_button" msgid="122785427241471085">"သော့ဖွင့်ရန်"</string>
     <string name="accessibility_lock_icon" msgid="661492842417875775">"စက်ပစ္စည်းကို လော့ခ်ချထားသည်"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"မျက်နှာ စကင်ဖတ်နေသည်"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"အတည်ပြုပြီးပြီ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"အပြီးသတ်ရန်အတွက် \'အတည်ပြုရန်\' ကို တို့ပါ"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ပိတ်ရန်"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"လုံးဝ အသံပိတ်ထားရန်"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"နှိုးစက်များသာ"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"မနှောင့်ယှက်ရ။"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ဘလူးတုသ်။"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ဘလူးတုသ် ဖွင့်ထား။"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"နိုးစက်ပေးထားသော အချိန် <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"မုန့်ထည့်သော ပုံး"</string>
     <string name="start_dreams" msgid="9131802557946276718">"ဖန်သားပြင်အသုံးပြုမှု ချွေတာမှုစနစ်"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"အီသာနက်"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"မနှောင့်ယှက်ရ"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ဘလူးတုသ်"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ချိတ်တွဲထားသည့် ကိရိယာများ မရှိ"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ဘက်ထရီ"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"အကြောင်းကြားချက်များ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"စကားဝိုင်းများ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"အသံတိတ် အကြောင်းကြားချက်များအားလုံးကို ရှင်းလင်းရန်"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"အကြောင်းကြားချက်များကို \'မနှောင့်ယှက်ရ\' က ခေတ္တရပ်ထားသည်"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;အခြေအနေ-&lt;/b&gt; အဆင့်လျှော့ထားသည်"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းတွင် ပြ၍ လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံအဖြစ် ပြသည်"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းတွင် ပြ၍ လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံအဖြစ် ပြကာ ပူဖောင်းကွက်အဖြစ် မြင်ရသည်"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းတွင် ပြ၍ လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံအဖြစ် ပြကာ ‘မနှောင့်ယှက်ရ’ ကို ရပ်တန့်သည်"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းတွင် ပြ၍ လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံအဖြစ် ပြကာ ပူဖောင်းကွက်အဖြစ် မြင်ရပြီး ‘မနှောင့်ယှက်ရ’ ကို ရပ်တန့်သည်"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS စာတိုစနစ်"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ပြက္ခဒိန်"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"မနှောင့်ယှက်ရ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"အသံထိန်းချုပ်သည့်ခလုတ် ဖြတ်လမ်း"</string>
     <string name="battery" msgid="769686279459897127">"ဘက်ထရီ"</string>
     <string name="headset" msgid="4485892374984466437">"မိုက်ခွက်ပါနားကြပ်"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>၊ <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ပိတ်ထားသည်"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ဘလူးတုသ်ကို ပိတ်ထားသည်"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"\"မနှောင့်ယှက်ရ\" ကို ပိတ်ထားသည်"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"မနှောင့်ယှက်ရ\" ကို အလိုအလျောက်စည်းမျဉ်း (<xliff:g id="ID_1">%s</xliff:g>) က ဖွင့်ခဲ့သည်။"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"မနှောင့်ယှက်ရ\" ကို အက်ပ် (<xliff:g id="ID_1">%s</xliff:g>) က ဖွင့်ခဲ့သည်။"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"မနှောင့်ယှက်ရ\" ကို အလိုအလျောက်စည်းမျဉ်းတစ်ခု သို့မဟုတ် အက်ပ်တစ်ခုက ဖွင့်ခဲ့သည်။"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"နောက်ခံတွင် ပွင့်နေသော အက်ပ်များ"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"ဘက်ထရီနှင့် ဒေတာအသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန် တို့ပါ"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"မိုဘိုင်းဒေတာ ပိတ်မလား။"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(လုပ်ငန်းသုံး)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ဖုန်းခေါ်ဆိုမှု"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> မှတစ်ဆင့်)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"ကင်မရာ"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"တည်နေရာ"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"မိုက်ခရိုဖုန်း"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ချိတ်ဆက်မှု မရှိပါ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ပြောင်း၍ မရပါ။ ပြန်စမ်းကြည့်ရန် တို့ပါ။"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"စက်အသစ် တွဲချိတ်ရန်"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"အက်ပ်ဖွင့်ပြီး ဤစက်ရှင်ကို ကာစ်လုပ်နိုင်သည်။"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"အမည်မသိ အက်ပ်"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်မှုနံပါတ်"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string>
     <string name="basic_status" msgid="2315371112182658176">"စကားဝိုင်းကို ဖွင့်ရန်"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"မကြာသေးမီက မက်ဆေ့ဂျ်၊ လွတ်သွားသောခေါ်ဆိုမှုနှင့် အခြေအနေအပ်ဒိတ်များကို ကြည့်နိုင်သည်"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"စကားဝိုင်း"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"‘မနှောင့်ယှက်ရ’ ဖြင့် ခဏရပ်ထားသည်"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> က မက်ဆေ့ဂျ်ပို့လိုက်သည်- <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> က ပုံပို့လိုက်သည်"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> က အခြေအနေ အပ်ဒိတ်လုပ်လိုက်သည်- <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"အချက်အလက်သစ်"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ပွင့်နေသည့်အက်ပ်များ"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"ကူးပြီးပါပြီ"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> ထံမှ"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI မိတ္တူမကူးတော့ရန်"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"ကူးထားသည့်စာသားကို တည်းဖြတ်ရန်"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ကူးထားသည့်ပုံကို ပြင်ဆင်ရန်"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"အနီးတစ်ဝိုက်ရှိ စက်များသို့ ပို့ရန်"</string>
+    <string name="add" msgid="81036585205287996">"ထည့်ရန်"</string>
+    <string name="manage_users" msgid="1823875311934643849">"အသုံးပြုသူများ စီမံရန်"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"ဤအကြောင်းကြားချက်သည် ‘မျက်နှာပြင်ခွဲ၍ပြသမှု’ သို့ ဖိဆွဲခြင်းကို မပံ့ပိုးပါ။"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi မရပါ"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ဦးစားပေးမုဒ်"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"နိုးစက် သတ်မှတ်ထားသည်"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant ဧည့်သည်သုံးခွင့်မုဒ် ဖွင့်ထားသည်"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ကင်မရာနှင့် မိုက် ပိတ်ထားသည်"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 76cfef5..5ccf528 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -20,7 +20,12 @@
 <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">"System-UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Batteriet går kanskje snart tomt"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> gjenstår"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Kan ikke lade via USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Bruk laderen som fulgte med enheten"</string>
@@ -128,6 +133,8 @@
     <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>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trykk på Bekreft for å fullføre"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentisert"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Bruk PIN-kode"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Bruk mønster"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Lukk"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"total stillhet"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"bare alarmer"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ikke forstyrr."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth er på."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarmen ble stilt for <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessertmonter"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Skjermsparer"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ikke forstyrr"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ingen sammenkoblede enheter er tilgjengelige"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Varsler"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Fjern alle lydløse varsler"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Varsler er satt på pause av «Ikke forstyrr»"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start nå"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ingen varsler"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enheten administreres av forelderen din"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Rangert lavere"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Vises øverst på samtalevarsler og som et profilbilde på låseskjermen"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Vises øverst på samtalevarsler og som et profilbilde på låseskjermen, vises som en boble"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Vises øverst på samtalevarsler og som et profilbilde på låseskjermen, avbryter «Ikke forstyrr»"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Vises øverst på samtalevarsler og som et profilbilde på låseskjermen, vises som en boble, avbryter «Ikke forstyrr»"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> støtter ikke samtalefunksjoner"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse varslene kan ikke endres."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musikk"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ikke forstyrr"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Hurtigtast for volumknappene"</string>
     <string name="battery" msgid="769686279459897127">"Batteri"</string>
     <string name="headset" msgid="4485892374984466437">"Hodetelefoner"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi er av"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth er av"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Ikke forstyrr er av"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Ikke forstyrr ble slått på av en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Ikke forstyrr ble slått på av en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Ikke forstyrr ble slått på av en automatisk regel eller en app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apper kjører i bakgrunnen"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Trykk for detaljer om batteri- og databruk"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Vil du slå av mobildata?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(jobb)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonsamtale"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(via <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kameraet"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"posisjon"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonen"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(frakoblet)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan ikke bytte. Trykk for å prøve igjen."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Koble til en ny enhet"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"For å caste denne økten, åpne appen."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukjent app"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delversjonsnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Delversjonsnummeret er kopiert til utklippstavlen."</string>
     <string name="basic_status" msgid="2315371112182658176">"Åpen samtale"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Se nylige meldinger, tapte anrop og statusoppdateringer"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Samtale"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Satt på pause av «Ikke forstyrr»"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> har sendt en melding: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> har sendt et bilde"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> har en statusoppdatering: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktive apper</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiv app</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Ny informasjon"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive apper"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stopp"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stoppet"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopiert"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Fra <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Lukk kopi-UI"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Rediger den kopierte teksten"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Rediger det kopierte bildet"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send til en enhet i nærheten"</string>
+    <string name="add" msgid="81036585205287996">"Legg til"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Administrer brukere"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Dette varselet støtter ikke at du drar det til en delt skjerm."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi er utilgjengelig"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteringsmodus"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er stilt inn"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Gjestemodus for assistenten er slått på"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er av"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 158a891..471bf14 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -20,7 +20,12 @@
 <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">"सिस्टम UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"ब्याट्री चाँडै सकिन सक्छ"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> बाँकी"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB मार्फत चार्ज गर्न सकिँदैन"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"तपाईंको यन्त्रसँगै आएको चार्जर प्रयोग गर्नुहोस्‌"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"अनुहार प्रमाणीकरण गरियो"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि भयो"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूरा गर्नका लागि पुष्टि गर्नुहोस् नामक विकल्पमा ट्याप गर्नुहोस्"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"बन्द गर्नुहोस्"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"पूर्ण मौनता"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"अलार्महरू मात्र"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"बाधा नपुऱ्याउनुहोस्।"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ब्लुटुथ।"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ब्लुटुथ खुला छ।"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g>को लागि सङ्केत घन्टी सेट गरिएको"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"स्क्रिन सेभर"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"बाधा नपुऱ्याउनुहोस्"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ब्लुटुथ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"जोडी उपकरणहरू उपलब्ध छैन"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ब्याट्री"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाहरू"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"वार्तालापहरू"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"सबै मौन सूचनाहरू हटाउनुहोस्"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"बाधा नपुऱ्याउनुहोस् नामक मोडमार्फत पज पारिएका सूचनाहरू"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;स्थिति:&lt;/b&gt; कम महत्त्वपूर्ण सूचनाका रूपमा सेट गरिएको छ"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"यो वार्तालापका सूचनाहरूको सिरानमा र लक स्क्रिनमा प्रोफाइल फोटोका रूपमा देखिन्छ"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"यो वार्तालापका सूचनाहरूको सिरानमा, बबलका रूपमा र लक स्क्रिनमा प्रोफाइल फोटोका रूपमा देखिन्छ"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"यो वार्तालापका सूचनाहरूको सिरानमा र लक स्क्रिनमा प्रोफाइल फोटोका रूपमा देखिन्छ। साथै, यसले गर्दा \'बाधा नपुऱ्याउनुहोस्\' नामक सुविधामा अवरोध आउँछ"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"यो वार्तालापका सूचनाहरूको सिरानमा, बबलका रूपमा र लक स्क्रिनमा प्रोफाइल फोटोका रूपमा देखिन्छ। साथै, यसले गर्दा \'बाधा नपुऱ्याउनुहोस्\' नामक सुविधामा अवरोध आउँछ"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"सङ्गीत"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"पात्रो"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"बाधा नपुऱ्याउनुहोस्"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"भोल्युम बटनका सर्टकट"</string>
     <string name="battery" msgid="769686279459897127">"ब्याट्री"</string>
     <string name="headset" msgid="4485892374984466437">"हेडसेट"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi‑Fi निष्क्रिय छ"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ब्लुटुथ निष्क्रिय छ"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"बाधा नपुर्‍याउनुहोस् नामक विकल्प निष्क्रिय छ"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"कुनै स्वचालित नियमले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रियो गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"कुनै अनुप्रयोगले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"कुनै स्वचालित नियम वा अनुप्रयोगले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो।"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"पृष्ठभूमिमा चल्ने एपहरू"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"ब्याट्री र डेटाका प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"मोबाइल डेटा निष्क्रिय पार्ने हो?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(कार्यालय)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"फोन कल"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> मार्फत)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"क्यामेरा"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"स्थान"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"माइक्रोफोन"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिस्कनेक्ट गरिएको छ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"बदल्न सकिएन। फेरि प्रयास गर्न ट्याप गर्नुहोस्।"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नयाँ डिभाइस कनेक्ट गर्नुहोस्"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"यो सत्र कास्ट गर्न चाहनुहुन्छ भने कृपया एप खोल्नुहोस्।"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात एप"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नम्बर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नम्बर कपी गरी क्लिपबोर्डमा सारियो।"</string>
     <string name="basic_status" msgid="2315371112182658176">"वार्तालाप खोल्नुहोस्"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"हालसालैका म्यासेज, मिस कल र स्ट्याटस अपडेट हेर्नुहोस्"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"वार्तालाप"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"\'बाधा नपुऱ्याउनुहोस्\' ले पज गरेको छ"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ले एउटा म्यासेज पठाउनुभएको छ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ले एउटा फोटो पठाउनुभयो"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ले स्ट्याटस अपडेट गर्नुभएको छ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"नयाँ जानकारी"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"सक्रिय एपहरू"</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>
@@ -889,8 +910,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"कपी गरिएको टेक्स्ट सम्पादन गर्नुहोस्"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"कपी गरिएको फोटो सम्पादन गर्नुहोस्"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"नजिकैको डिभाइसमा पठाउनुहोस्"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"हाल्नुहोस्"</string>
+    <string name="manage_users" msgid="1823875311934643849">"प्रयोगकर्ताहरूको व्यवस्थापन गर्नुहोस्"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"यो सूचना ड्र्याग गरेर स्प्लिटस्क्रिनमा लैजान मिल्दैन।"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi उपलब्ध छैन"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राथमिकता मोड"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट गरिएको छ"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"सहायकको अतिथि मोड अन गरिएको छ"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"क्यामेरा र माइक अफ छन्"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# वटा सूचना}other{# वटा सूचनाहरू}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index f85bbee..047f99f 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -20,7 +20,12 @@
 <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">"Systeem-UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Batterij is bijna leeg"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Nog <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Kan niet opladen via USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Gebruik de oplader die bij je apparaat is geleverd"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gezicht geverifieerd"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bevestigd"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tik op Bevestigen om te voltooien"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Geverifieerd"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Pincode gebruiken"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Patroon gebruiken"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Sluiten"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"totale stilte"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"alleen wekkers"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Niet storen."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth aan."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Wekker is ingesteld op <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessertshowcase"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Screensaver"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Niet storen"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Geen gekoppelde apparaten beschikbaar"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterijniveau"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Meldingen"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Gesprekken"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Alle stille meldingen wissen"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Meldingen onderbroken door \'Niet storen\'"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Nu starten"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Geen meldingen"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dit apparaat wordt beheerd door je ouder"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; lager gerangschikt"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Wordt getoond bovenaan gespreksmeldingen en als profielfoto op het vergrendelscherm"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Wordt getoond bovenaan gespreksmeldingen en als profielfoto op het vergrendelscherm, verschijnt als bubbel"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Wordt getoond bovenaan gespreksmeldingen en als profielfoto op het vergrendelscherm, onderbreekt Niet storen"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wordt getoond bovenaan gespreksmeldingen en als profielfoto op het vergrendelscherm, verschijnt als bubbel, onderbreekt Niet storen"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ondersteunt geen gespreksfuncties"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Deze meldingen kunnen niet worden aangepast."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sms"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muziek"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Niet storen"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volumeknoppen als sneltoets"</string>
     <string name="battery" msgid="769686279459897127">"Batterij"</string>
     <string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wifi staat uit"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth staat uit"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Niet storen staat uit"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Niet storen is aangezet door een automatische regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Niet storen is aangezet door een app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Niet storen is aangezet door een automatische regel of app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps uitgevoerd op achtergrond"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tik voor batterij- en datagebruik"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Mobiele data uitzetten?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(werk)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefoongesprek"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(via <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"locatie"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"microfoon"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(verbinding verbroken)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan niet schakelen. Tik om het opnieuw te proberen."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Nieuw apparaat koppelen"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Als je deze sessie wilt casten, open je de app."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende app"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-nummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build-nummer naar klembord gekopieerd."</string>
     <string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Bekijk recente berichten, gemiste gesprekken en statusupdates"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Gesprek"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Onderbroken door Niet storen"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> heeft een bericht gestuurd: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> heeft een afbeelding gestuurd"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> heeft een statusupdate: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> actieve apps</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> actieve app</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nieuwe informatie"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Actieve apps"</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>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Gekopieerd"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Uit <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI voor kopiëren sluiten"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Gekopieerde tekst bewerken"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Gekopieerde afbeelding bewerken"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Naar apparaat in de buurt sturen"</string>
+    <string name="add" msgid="81036585205287996">"Toevoegen"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Gebruikers beheren"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Deze melding biedt geen ondersteuning voor slepen naar het gesplitste scherm."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi niet beschikbaar"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteitsmodus"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gezet"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Gastmodus voor de Assistent staat aan"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera en microfoon staan uit"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# melding}other{# meldingen}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index dab199b..0dca918 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -20,7 +20,12 @@
 <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">"ସିଷ୍ଟମ୍ UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"ଖୁବ୍ ଶୀଘ୍ର ବ୍ୟାଟେରୀ ସରିଯାଇପାରେ"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ବାକି ଅଛି"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB ଦ୍ଵାରା ଚାର୍ଜ କରିହେବନାହିଁ"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"ଆପଣଙ୍କ ଡିଭାଇସ୍ ପାଇଁ ଥିବା ଚାର୍ଜର୍‌କୁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ମୁହଁ ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ସୁନିଶ୍ଚିତ କରାଯାଇଛି"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ସୁନିଶ୍ଚିତ କରନ୍ତୁରେ ଟାପ୍ କରନ୍ତୁ"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ସମ୍ପୂର୍ଣ୍ଣ ନୀରବତା"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"କେବଳ ଆଲାର୍ମ"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ।"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ବ୍ଲୁଟୁଥ।"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ବ୍ଲୁଟୂଥ୍‍‍ ଚାଲୁ ଅଛି।"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g>ରେ ଆଲାର୍ମ ସେଟ୍‍ କରାଯାଇଛି।"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"ଡେଜର୍ଟ କେସ୍‌"</string>
     <string name="start_dreams" msgid="9131802557946276718">"ସ୍କ୍ରିନ୍‌ ସେଭର୍‌"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ଇଥରନେଟ୍‌"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ବ୍ଲୁଟୁଥ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ପେୟାର୍‍ ହୋଇଥିବା କୌଣସି ଡିଭାଇସ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ବ୍ୟାଟେରୀ"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ସମସ୍ତ ନୀରବ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଖାଲି କରନ୍ତୁ"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ବିକଳ୍ପ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତି ପଜ୍‍ ହୋଇଛି"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ସ୍ଥିତି:&lt;/b&gt; ରେଙ୍କ ତଳକୁ କରାଯାଇଛି"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"ବାର୍ତ୍ତାଳାପ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଶୀର୍ଷରେ ଏବଂ ଲକ୍ ସ୍କ୍ରିନରେ ଏକ ପ୍ରୋଫାଇଲ୍ ଛବି ଭାବେ ଦେଖାଏ"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"ବାର୍ତ୍ତାଳାପ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଶୀର୍ଷରେ ଏବଂ ଲକ୍ ସ୍କ୍ରିନରେ ଏକ ପ୍ରୋଫାଇଲ୍ ଛବି ଭାବେ ଦେଖାଏ, ଏକ ବବଲ୍ ଭାବେ ଦେଖାଯାଏ"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"ବାର୍ତ୍ତାଳାପ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଶୀର୍ଷରେ ଏବଂ ଲକ୍ ସ୍କ୍ରିନରେ ଏକ ପ୍ରୋଫାଇଲ୍ ଛବି ଭାବେ ଦେଖାଏ, \'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\'କୁ ବାଧା ଦିଏ"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ବାର୍ତ୍ତାଳାପ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଶୀର୍ଷରେ ଏବଂ ଲକ୍ ସ୍କ୍ରିନରେ ଏକ ପ୍ରୋଫାଇଲ୍ ଛବି ଭାବେ ଦେଖାଏ, ଏକ ବବଲ୍ ଭାବେ ଦେଖାଯାଏ, \'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\'କୁ ବାଧା ଦିଏ"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ମ୍ୟୁଜିକ୍‍"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"କ୍ୟାଲେଣ୍ଡର୍"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ଭଲ୍ୟୁମ ବଟନ୍‍ ଶର୍ଟକଟ୍‍"</string>
     <string name="battery" msgid="769686279459897127">"ବ୍ୟାଟେରୀ"</string>
     <string name="headset" msgid="4485892374984466437">"ହେଡସେଟ୍‍"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"ୱାଇ-ଫାଇ ଅଫ୍‍ ଅଛି"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ବ୍ଲୁଟୂଥ୍‍‌ ଅଫ୍ ଅଛି"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅଫ୍‍ ଅଛି"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ଏକ (<xliff:g id="ID_1">%s</xliff:g>) ନିୟମ ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ସ୍ୱଚାଳିତ ଭାବେ ଅନ୍‍ କରାଗଲା।"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ଏକ ଆପ୍‍ (<xliff:g id="ID_1">%s</xliff:g>) ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍‌ କରାଗଲା।"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ଏକ ସ୍ୱଚାଳିତ ନିୟମ କିମ୍ବା ଆପ୍‍ ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍‍ କରାଗଲା।"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"ବ୍ୟାକଗ୍ରାଉଣ୍ଡରେ ଆପ୍‍ ଚାଲୁଛି"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"ବ୍ୟାଟେରୀ ଏବଂ ଡାଟା ବ୍ୟବହାର ଉପରେ ବିବରଣୀ ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"ମୋବାଇଲ୍‌ ଡାଟା ବନ୍ଦ କରିବେ?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ୱାର୍କ)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ଫୋନ୍ କଲ୍"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> ମାଧ୍ୟମରେ)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"କ୍ୟାମେରା"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ଲୋକେସନ୍‍"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"ମାଇକ୍ରୋଫୋନ୍"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ବିଚ୍ଛିନ୍ନ କରାଯାଇଛି)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ସ୍ୱିଚ କରାଯାଇପାରିବ ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ନୂଆ ଡିଭାଇସକୁ ପେୟାର୍ କରନ୍ତୁ"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ଏହି ସେସନକୁ କାଷ୍ଟ କରିବା ପାଇଁ, ଦୟାକରି ଆପ ଖୋଲନ୍ତୁ।"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ଅଜଣା ଆପ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ବିଲ୍ଡ ନମ୍ୱର"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"କ୍ଲିପବୋର୍ଡକୁ କପି କରାଯାଇଥିବା ବିଲ୍ଡ ନମ୍ୱର।"</string>
     <string name="basic_status" msgid="2315371112182658176">"ବାର୍ତ୍ତାଳାପ ଖୋଲନ୍ତୁ"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"ବର୍ତ୍ତମାନର ମେସେଜ୍, ମିସ୍ଡ କଲ୍ ଏବଂ ସ୍ଥିତି ଅପଡେଟଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"ବାର୍ତ୍ତାଳାପ"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଦ୍ୱାରା ବିରତ କରାଯାଇଛି"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ମେସେଜ୍ ପଠାଇଛନ୍ତି: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ଛବି ପଠାଇଛନ୍ତି"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ସ୍ଥିତି ଅପଡେଟ୍ କରିଛନ୍ତି: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"ନୂଆ ସୂଚନା"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ସକ୍ରିୟ ଆପଗୁଡ଼ିକ"</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>
@@ -889,8 +910,14 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"କପି କରାଯାଇଥିବା ଟେକ୍ସଟକୁ ଏଡିଟ କରନ୍ତୁ"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"କପି କରାଯାଇଥିବା ଇମେଜକୁ ଏଡିଟ କରନ୍ତୁ"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ନିକଟସ୍ଥ ଡିଭାଇସକୁ ପଠାନ୍ତୁ"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="add" msgid="81036585205287996">"ଯୋଗ କରନ୍ତୁ"</string>
+    <string name="manage_users" msgid="1823875311934643849">"ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"ଏହି ବିଜ୍ଞପ୍ତି ସ୍ପ୍ଲିଟସ୍କ୍ରିନକୁ ଡ୍ରାଗ କରିବାକୁ ସମର୍ଥନ କରେ ନାହିଁ।"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ୱାଇ-ଫାଇ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ପ୍ରାଥମିକତା ମୋଡ"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ଆଲାରାମ ସେଟ"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistantର ଅତିଥି ମୋଡ ସକ୍ଷମ କରାଯାଇଛି"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"କ୍ୟାମେରା ଏବଂ ମାଇକ ବନ୍ଦ ଅଛି"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 20b5bf2..faa2062 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -20,7 +20,12 @@
 <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">"ਸਿਸਟਮ UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"ਬੈਟਰੀ ਛੇਤੀ ਹੀ ਖਤਮ ਹੋ ਸਕਦੀ ਹੈ"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ਬਾਕੀ"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB ਰਾਹੀਂ ਚਾਰਜ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"ਆਪਣੇ ਡੀਵਾਈਸ ਨਾਲ ਮਿਲੇ ਚਾਰਜਰ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ਚਿਹਰਾ ਪ੍ਰਮਾਣੀਕਿਰਤ ਹੋਇਆ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ਪੁਸ਼ਟੀ ਕੀਤੀ ਗਈ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ਪੂਰਾ ਕਰਨ ਲਈ ਪੁਸ਼ਟੀ ਕਰੋ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ਬੰਦ ਕਰੋ"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ਪੂਰਾ ਸ਼ਾਂਤ"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ਸਿਰਫ਼ ਅਲਾਰਮ"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ।"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ਬਲੂਟੁੱਥ।"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ਚਾਲੂ।"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ਅਲਾਰਮ <xliff:g id="TIME">%s</xliff:g> ਲਈ ਸੈੱਟ ਕੀਤਾ ਗਿਆ।"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"ਡੈਜ਼ਰਟ ਕੇਸ"</string>
     <string name="start_dreams" msgid="9131802557946276718">"ਸਕ੍ਰੀਨ ਸੇਵਰ"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ਈਥਰਨੈਟ"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ਬਲੂਟੁੱਥ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ਕੋਈ ਜੋੜਾਬੱਧ ਕੀਤੀਆਂ ਡੀਵਾਈਸਾਂ ਉਪਲਬਧ ਨਹੀਂ"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ਬੈਟਰੀ"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"ਸੂਚਨਾਵਾਂ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ਗੱਲਾਂਬਾਤਾਂ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਖਾਮੋਸ਼ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ਸਥਿਤੀ:&lt;/b&gt; ਦਰਜਾ ਘਟਾਇਆ ਗਿਆ"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਉਂਦਾ ਹੈ"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ, ਜੋ ਕਿ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਉਂਦਾ ਹੈ, \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੁਵਿਧਾ ਵਿੱਚ ਵੀ ਵਿਘਨ ਪੈ ਸਕਦਾ ਹੈ"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ, ਜੋ ਕਿ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ ਅਤੇ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੁਵਿਧਾ ਵਿੱਚ ਵਿਘਨ ਵੀ ਪਾ ਸਕਦੀਆਂ ਹਨ"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ਸੰਗੀਤ"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ਵੌਲਿਊਮ ਬਟਨ ਸ਼ਾਰਟਕੱਟ"</string>
     <string name="battery" msgid="769686279459897127">"ਬੈਟਰੀ"</string>
     <string name="headset" msgid="4485892374984466437">"ਹੈੱਡਸੈੱਟ"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"ਵਾਈ-ਫਾਈ ਬੰਦ ਹੈ"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ਬਲੂਟੁੱਥ ਬੰਦ ਹੈ"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਬੰਦ ਹੈ"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ਸਵੈਚਲਿਤ ਨਿਯਮ (<xliff:g id="ID_1">%s</xliff:g>) ਦੁਆਰਾ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"ਐਪ (<xliff:g id="ID_1">%s</xliff:g>) ਵੱਲੋਂ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ਇੱਕ ਸਵੈਚਲਿਤ ਨਿਯਮ ਜਾਂ ਐਪ ਵੱਲੋਂ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਐਪਾਂ"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"ਬੈਟਰੀ ਅਤੇ ਡਾਟਾ ਵਰਤੋਂ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"ਕੀ ਮੋਬਾਈਲ ਡਾਟਾ ਬੰਦ ਕਰਨਾ ਹੈ?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ਕਾਰਜ-ਸਥਾਨ)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ਫ਼ੋਨ ਕਾਲ"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> ਰਾਹੀਂ)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"ਕੈਮਰਾ"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ਟਿਕਾਣਾ"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ਡਿਸਕਨੈਕਟ ਹੈ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ਇਸ ਸੈਸ਼ਨ ਨੂੰ ਕਾਸਟ ਕਰਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਐਪ ਖੋਲ੍ਹੋ।"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ਅਗਿਆਤ ਐਪ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ਬਿਲਡ ਨੰਬਰ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ਬਿਲਡ ਨੰਬਰ ਨੂੰ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="basic_status" msgid="2315371112182658176">"ਗੱਲਬਾਤ ਖੋਲ੍ਹੋ"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"ਹਾਲੀਆ ਸੁਨੇਹੇ, ਮਿਸ ਕਾਲਾਂ ਅਤੇ ਸਥਿਤੀ ਸੰਬੰਧੀ ਅੱਪਡੇਟ ਦੇਖੋ"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"ਗੱਲਬਾਤ"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵਿਸ਼ੇਸ਼ਤਾ ਨੇ ਰੋਕ ਦਿੱਤਾ"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ਨੇ ਸੁਨੇਹਾ ਭੇਜਿਆ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ਨੇ ਇੱਕ ਚਿੱਤਰ ਭੇਜਿਆ ਹੈ"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ਨੇ ਸਥਿਤੀ ਅੱਪਡੇਟ ਕੀਤੀ ਹੈ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"ਨਵੀਂ ਜਾਣਕਾਰੀ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ਕਿਰਿਆਸ਼ੀਲ ਐਪਾਂ"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"ਕਾਪੀ ਕੀਤੀ ਗਈ"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> ਤੋਂ"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"ਕਾਪੀ ਕੀਤੇ UI ਨੂੰ ਖਾਰਜ ਕਰੋ"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"ਕਾਪੀ ਕੀਤੀ ਲਿਖਤ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ਕਾਪੀ ਕੀਤੇ ਗਏ ਚਿੱਤਰ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸ \'ਤੇ ਭੇਜੋ"</string>
+    <string name="add" msgid="81036585205287996">"ਸ਼ਾਮਲ ਕਰੋ"</string>
+    <string name="manage_users" msgid="1823875311934643849">"ਵਰਤੋਂਕਾਰਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"ਇਹ ਸੂਚਨਾ ਸਪਲਿਟ ਸਕ੍ਰੀਨ \'ਤੇ ਘਸੀਟਣ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ ਹੈ।"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ਵਾਈ-ਫਾਈ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ਤਰਜੀਹੀ ਮੋਡ"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ਅਲਾਰਮ ਸੈੱਟ ਹੈ"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant ਮਹਿਮਾਨ ਮੋਡ ਚਾਲੂ ਹੈ"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ਕੈਮਰਾ ਅਤੇ ਮਾਈਕ ਬੰਦ ਹਨ"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 4572922..5d61dfe 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI systemu"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Bateria może się wkrótce wyczerpać"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Pozostało <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Nie można naładować przez USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Użyj ładowarki dostarczonej z urządzeniem"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Twarz rozpoznana"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zamknij"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"całkowita cisza"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"tylko alarmy"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Nie przeszkadzać."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth włączony."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm ustawiony na <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Półka ze słodkościami"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Wygaszacz ekranu"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Nie przeszkadzać"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Brak dostępnych sparowanych urządzeń"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> naładowania baterii"</string>
@@ -354,6 +363,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Powiadomienia"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Rozmowy"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Usuń wszystkie ciche powiadomienia"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Powiadomienia wstrzymane przez tryb Nie przeszkadzać"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Rozpocznij teraz"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Brak powiadomień"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tym urządzeniem zarządza Twój rodzic"</string>
@@ -497,6 +507,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stan:&lt;/b&gt; obniżono ważność"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, jako dymek"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, przerywa działanie trybu Nie przeszkadzać"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, jako dymek, przerywa działanie trybu Nie przeszkadzać"</string>
     <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>
@@ -576,6 +588,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzyka"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendarz"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Nie przeszkadzać"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Wł./wył. przyciskami głośności"</string>
     <string name="battery" msgid="769686279459897127">"Bateria"</string>
     <string name="headset" msgid="4485892374984466437">"Zestaw słuchawkowy"</string>
@@ -694,6 +707,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi jest wyłączone"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth jest wyłączony"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Tryb Nie przeszkadzać jest wyłączony"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Tryb Nie przeszkadzać został włączony przez regułę automatyczną (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Tryb Nie przeszkadzać został włączony przez aplikację (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Tryb Nie przeszkadzać został włączony przez regułę automatyczną lub aplikację."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacje działające w tle"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Kliknij, by wyświetlić szczegóły wykorzystania baterii i użycia danych"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Wyłączyć mobilną transmisję danych?"</string>
@@ -718,6 +735,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(praca)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Rozmowa telefoniczna"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(przez: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"aparat"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"lokalizacja"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -818,6 +837,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odłączono)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nie można przełączyć. Spróbuj ponownie."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sparuj nowe urządzenie"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Aby przesłać tę sesję, otwórz aplikację."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nieznana aplikacja"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otwarta rozmowa"</string>
@@ -851,6 +872,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+ <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Zobacz ostatnie wiadomości, nieodebrane połączenia i stany"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Rozmowa"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Wstrzymane przez tryb Nie przeszkadzać"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> wysyła wiadomość: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> wysyła zdjęcie"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ma nowy stan: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktywnej aplikacji</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktywna aplikacja</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nowa informacja"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktywne aplikacje"</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>
@@ -900,14 +921,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Skopiowano"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Od: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Zamknij UI kopiowania"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edytuj skopiowany tekst"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edytuj skopiowany obraz"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Wyślij na urządzenie w pobliżu"</string>
+    <string name="add" msgid="81036585205287996">"Dodaj"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Zarządzaj użytkownikami"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"To powiadomienie nie obsługuje dzielenia ekranu przez przeciąganie."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Sieć Wi‑Fi niedostępna"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tryb priorytetowy"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm ustawiony"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Tryb gościa w Asystencie włączony"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Aparat i mikrofon są wyłączone"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 1c902b0..d9bb15b 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -20,7 +20,12 @@
 <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">"Interface do sistema"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"A bateria pode acabar em breve"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restantes"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Não é possível carregar via USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Usar o carregador que acompanha o dispositivo"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em \"Confirmar\" para concluir"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrão"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Fechar"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silêncio total"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"somente alarmes"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Não perturbe."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ativado."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Mostruário de sobremesas"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Protetor de tela"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Não perturbe"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Não há dispositivos pareados disponíveis"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Apagar todas as notificações silenciosas"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações pausadas pelo modo \"Não perturbe\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu pai/mãe"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; classificada com menor prioridade"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Aparece na parte superior das notificações de conversa e como uma foto do perfil na tela de bloqueio"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Aparece na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Aparece na parte superior das notificações de conversa e como uma foto do perfil na tela de bloqueio. Interrompe o Não perturbe"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão. Interrompe o Não perturbe"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Não perturbe"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Atalho de botões de volume"</string>
     <string name="battery" msgid="769686279459897127">"Bateria"</string>
     <string name="headset" msgid="4485892374984466437">"Fone de ouvido"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"O Wi-Fi está desativado"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"O recurso Não perturbe está desativado"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O recurso Não perturbe foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O recurso Não perturbe foi ativado por um app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O recurso Não perturbe foi ativado por uma regra automática ou app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps sendo executados em segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Desativar os dados móveis?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabalho)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada telefônica"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(por <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"câmera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(sem conexão)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não foi possível mudar. Toque para tentar novamente."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Veja mensagens recentes, chamadas perdidas e atualizações de status"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Pausado pelo Não perturbe"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atualizou o status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app ativo</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps ativos</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nova informação"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativos"</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>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Do app <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dispensar cópia da IU"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagem copiada"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar para dispositivo próximo"</string>
+    <string name="add" msgid="81036585205287996">"Adicionar"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Gerenciar usuários"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não tem suporte para ser arrastada para a tela dividida."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi indisponível"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modo visitante do Google Assistente ativado"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}other{# notificações}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 1562abc..73ef834 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -20,7 +20,12 @@
 <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">"IU do sistema"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Pode ficar sem bateria em breve"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restante"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Não é possível carregar através de USB."</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Utilize o carregador fornecido com o dispositivo."</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Fechar"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silêncio total"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"apenas alarmes"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Não incomodar."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ligado."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Vitrina de sobremesas"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Proteção de ecrã"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Não incomodar"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Sem dispositivos sincronizados disponíveis"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Limpar todas as notificações silenciosas"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações colocadas em pausa pelo modo Não incomodar."</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Começar agora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerido pelos teus pais"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Estado:&lt;/b&gt; passou para classificação inferior"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Aparece na parte superior das notificações de conversas e como uma imagem do perfil no ecrã de bloqueio"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Aparece na parte superior das notificações de conversas e como uma imagem do perfil no ecrã de bloqueio, surge como um balão"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Aparece na parte superior das notificações de conversas e como uma imagem do perfil no ecrã de bloqueio, interrompe o modo Não incomodar"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece na parte superior das notificações de conversas e como uma imagem do perfil no ecrã de bloqueio, surge como um balão, interrompe o modo Não incomodar"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendário"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Não incomodar"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Atalho dos botões de volume"</string>
     <string name="battery" msgid="769686279459897127">"Bateria"</string>
     <string name="headset" msgid="4485892374984466437">"Ausc. com microfone integrado"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi desativado"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Não incomodar desativado"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O modo Não incomodar foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O modo Não incomodar foi ativado por uma app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O modo Não incomodar foi ativado por uma regra automática ou por uma app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps em execução em segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Toque para obter detalhes acerca da utilização da bateria e dos dados"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Pretende desativar os dados móveis?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabalho)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(através de <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"câmara"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desligado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não é possível mudar. Toque para tentar novamente."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sincronize o novo dispositivo"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sessão, abra a app."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecida"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string>
     <string name="basic_status" msgid="2315371112182658176">"Abrir conversa"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Veja mensagens recentes, chamadas não atendidas e atualizações de estado"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Colocado em pausa pelo modo Não incomodar"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> tem uma atualização de estado: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app ativa</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps ativas</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Novas informações"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativas"</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>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Da app <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ignorar cópia de IU"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagem copiada"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar para dispositivo próximo"</string>
+    <string name="add" msgid="81036585205287996">"Adicionar"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Gerir utilizadores"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não pode ser arrastada para o ecrã dividido."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi indisponível"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo Prioridade"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modo convidado do Assistente ativado"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmara e o microfone estão desativados"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação(ões)}other{# notificações}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 1c902b0..d9bb15b 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -20,7 +20,12 @@
 <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">"Interface do sistema"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"A bateria pode acabar em breve"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> restantes"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Não é possível carregar via USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Usar o carregador que acompanha o dispositivo"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em \"Confirmar\" para concluir"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrão"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Fechar"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"silêncio total"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"somente alarmes"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Não perturbe."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth ativado."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Mostruário de sobremesas"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Protetor de tela"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Não perturbe"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Não há dispositivos pareados disponíveis"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Apagar todas as notificações silenciosas"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações pausadas pelo modo \"Não perturbe\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu pai/mãe"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; classificada com menor prioridade"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Aparece na parte superior das notificações de conversa e como uma foto do perfil na tela de bloqueio"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Aparece na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Aparece na parte superior das notificações de conversa e como uma foto do perfil na tela de bloqueio. Interrompe o Não perturbe"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão. Interrompe o Não perturbe"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Não perturbe"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Atalho de botões de volume"</string>
     <string name="battery" msgid="769686279459897127">"Bateria"</string>
     <string name="headset" msgid="4485892374984466437">"Fone de ouvido"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"O Wi-Fi está desativado"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desativado"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"O recurso Não perturbe está desativado"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"O recurso Não perturbe foi ativado por uma regra automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"O recurso Não perturbe foi ativado por um app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"O recurso Não perturbe foi ativado por uma regra automática ou app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Apps sendo executados em segundo plano"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Desativar os dados móveis?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabalho)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Chamada telefônica"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(por <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"câmera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(sem conexão)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não foi possível mudar. Toque para tentar novamente."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Veja mensagens recentes, chamadas perdidas e atualizações de status"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Pausado pelo Não perturbe"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atualizou o status: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app ativo</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps ativos</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nova informação"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativos"</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>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Copiado"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Do app <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dispensar cópia da IU"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagem copiada"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar para dispositivo próximo"</string>
+    <string name="add" msgid="81036585205287996">"Adicionar"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Gerenciar usuários"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não tem suporte para ser arrastada para a tela dividida."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi indisponível"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modo visitante do Google Assistente ativado"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}other{# notificações}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index d520d50..ff409d3 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI sistem"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Este posibil ca bateria să se descarce în curând"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Procent rămas din baterie: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Nu se poate realiza încărcarea prin USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Folosiți încărcătorul livrat împreună cu dispozitivul"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Chip autentificat"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmat"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Atingeți Confirmați pentru a finaliza"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificat"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Folosiți PIN-ul"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Folosiți modelul"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Închideți"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"niciun sunet"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"numai alarme"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Nu deranja."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Conexiunea prin Bluetooth este activată."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarmă setată pentru <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Vitrina cu dulciuri"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Economizor de ecran"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Nu deranja"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Niciun dispozitiv conectat disponibil"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -351,6 +360,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificări"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversații"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ștergeți toate notificările silențioase"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificări întrerupte prin „Nu deranja”"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Începeți acum"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nicio notificare"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dispozitivul este gestionat de unul dintre părinți"</string>
@@ -494,6 +504,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stare:&lt;/b&gt; clasificată mai jos"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Se afișează în partea de sus a notificărilor pentru conversații și ca fotografie de profil pe ecranul de blocare"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Se afișează în partea de sus a notificărilor pentru conversații și ca fotografie de profil pe ecranul de blocare, apare ca un balon"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Se afișează în partea de sus a notificărilor pentru conversații și ca fotografie de profil pe ecranul de blocare, întrerupe funcția Nu deranja"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Se afișează în partea de sus a notificărilor pentru conversații și ca fotografie de profil pe ecranul de blocare, apare ca un balon, întrerupe funcția Nu deranja"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritate"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu acceptă funcții pentru conversații"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Aceste notificări nu pot fi modificate."</string>
@@ -571,6 +583,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzică"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Nu deranja"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Comandă rapidă din butoanele de volum"</string>
     <string name="battery" msgid="769686279459897127">"Baterie"</string>
     <string name="headset" msgid="4485892374984466437">"Set căști-microfon"</string>
@@ -689,6 +702,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Conexiunea Wi-Fi este dezactivată"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Funcția Bluetooth este dezactivată"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Funcția Nu deranja este dezactivată"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Funcția Nu deranja a fost activată de o regulă automată (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Funcția Nu deranja a fost activată de o aplicație (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Funcția Nu deranja a fost activată de o regulă automată sau de o aplicație."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplicațiile rulează în fundal"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Atingeți pentru mai multe detalii privind bateria și utilizarea datelor"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Dezactivați datele mobile?"</string>
@@ -713,6 +730,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(serviciu)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Apel telefonic"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(prin <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"cameră foto"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"locație"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"microfon"</string>
@@ -812,6 +831,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(deconectat)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nu se poate comuta. Atingeți pentru a încerca din nou."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Asociați un nou dispozitiv"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pentru a proiecta această sesiune, deschideți aplicația."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicație necunoscută"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numărul versiunii"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numărul versiunii s-a copiat în clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Deschideți conversația"</string>
@@ -845,6 +866,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Vedeți mesaje recente, apeluri pierdute și actualizări de stare"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Conversație"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Întrerupt de Nu deranja"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> a trimis un mesaj: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a trimis o imagine"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> are o nouă stare: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> de aplicații active</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicație activă</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informații noi"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicații active"</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>
@@ -896,8 +917,14 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editați textul copiat"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editați imaginea copiată"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Trimiteți către un dispozitiv din apropiere"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="add" msgid="81036585205287996">"Adăugați"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Gestionați utilizatorii"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Notificarea nu acceptă tragerea pe ecranul împărțit."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi indisponibil"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modul Prioritate"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmă setată"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modul pentru invitați al Asistentului este activat"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera și microfonul sunt dezactivate"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 310a87e..a79c247 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"Батарея скоро разрядится"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Осталось: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Невозможно выполнить зарядку через USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Используйте зарядное устройство из комплекта."</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицо распознано"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Подтверждено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Нажмите \"Подтвердить\""</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Закрыть"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"полная тишина"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"только будильник"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не беспокоить."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Модуль Bluetooth включен."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Будильник установлен на <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -207,6 +215,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Коробка со сладостями"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Заставка"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не беспокоить"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Нет доступных сопряженных устройств"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Уведомления"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Разговоры"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Отклонить все беззвучные уведомления"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"В режиме \"Не беспокоить\" уведомления заблокированы"</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>
@@ -497,6 +507,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Статус:&lt;/b&gt; уровень важности понижен"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Появляется в верхней части уведомлений о сообщениях, а также в качестве фото профиля на заблокированном экране"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Появляется в верхней части уведомлений о сообщениях, в виде всплывающего чата, а также в качестве фото профиля на заблокированном экране."</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Появляется в верхней части уведомлений о сообщениях, а также в качестве фото профиля на заблокированном экране, прерывает режим \"Не беспокоить\"."</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Появляется в верхней части уведомлений о сообщениях, в виде всплывающего чата, а также в качестве фото профиля на заблокированном экране, прерывает режим \"Не беспокоить\"."</string>
     <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>
@@ -576,6 +588,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музыка"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календарь"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не беспокоить"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Кнопки регулировки громкости"</string>
     <string name="battery" msgid="769686279459897127">"Батарея"</string>
     <string name="headset" msgid="4485892374984466437">"Гарнитура"</string>
@@ -694,6 +707,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Модуль Wi-Fi отключен"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Модуль Bluetooth отключен"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Режим \"Не беспокоить\" отключен"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Режим \"Не беспокоить\" был включен специальным правилом (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Режим \"Не беспокоить\" был включен приложением (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Режим \"Не беспокоить\" был включен специальным правилом или приложением."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Приложения, работающие в фоновом режиме"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Нажмите, чтобы проверить энергопотребление и трафик"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Отключить мобильный Интернет?"</string>
@@ -718,6 +735,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(работа)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонный звонок"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(через приложение \"<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>\")"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"местоположение"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -818,6 +837,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(нет подключения)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не удается переключиться. Нажмите, чтобы повторить попытку."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Подключить новое устройство"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Чтобы начать трансляцию сеанса, откройте приложение"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестное приложение"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер сборки"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номер сборки скопирован в буфер обмена."</string>
     <string name="basic_status" msgid="2315371112182658176">"Открытый чат"</string>
@@ -851,6 +872,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Будьте в курсе последних сообщений, пропущенных вызовов и обновлений статуса."</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Чат"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Приостановлено в режиме \"Не беспокоить\""</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил сообщение: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил изображение"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> обновил статус: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Новая информация"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активные приложения"</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>
@@ -900,14 +921,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Скопировано."</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Из приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Закрыть меню копирования"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Изменить скопированный текст"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Изменить скопированное изображение"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Отправить на устройство поблизости"</string>
+    <string name="add" msgid="81036585205287996">"Добавить"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Управление пользователями"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Это уведомление нельзя перетаскивать между частями разделенного экрана."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Сеть Wi‑Fi недоступна"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Режим приоритета"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлен"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Гостевой режим для Ассистента включен"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон отключены"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# уведомление}one{# уведомление}few{# уведомления}many{# уведомлений}other{# уведомления}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index e730bb0..ffaa4bf 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -20,7 +20,12 @@
 <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">"පද්ධති UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"බැටරිය ඉක්මනින් අවසන් විය හැකිය"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> ඉතිරිව තිබේ"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB හරහා ආරෝපණය කළ නොහැකිය"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"ඔබේ උපාංගය සමඟ පැමිණි ආරෝපකය භාවිත කරන්න"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"මුහුණ සත්‍යාපන කළා"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"තහවුරු කළා"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"සම්පූර්ණ කිරීමට තහවුරු කරන්න තට්ටු කර."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"වසන්න"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"සම්පූර්ණ නිහඬතාව"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"එලාම පමණි"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"බාධා නොකරන්න."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"බ්ලූටූත්."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"බ්ලූටූත් ක්‍රියාත්මකයි."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> සඳහා සීනුව සකස් කර ඇත."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"අතුරුපස අවස්තාව"</string>
     <string name="start_dreams" msgid="9131802557946276718">"තිර සුරැකුම"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ඊතර නෙට්"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"බාධා නොකරන්න"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"බ්ලූටූත්"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"යුගල කළ උපාංග නොතිබේ"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"දැනුම් දීම්"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"සංවාද"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"සියලු නිහඬ දැනුම්දීම් හිස් කරන්න"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"බාධා නොකරන්න මගින් විරාම කරන ලද දැනුම්දීම්"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;තත්ත්වය:&lt;/b&gt; පහළට ශ්‍රේණිගත කරන ලදි"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"සංවාද දැනුම්දීම්වල ඉහළින්ම සහ අගුලු තිරයේ ඇති පැතිකඩ පින්තූරයක් ලෙස පෙන්වයි"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"සංවාද දැනුම්දීම්වල ඉහළින්ම සහ අගුලු තිරයේ ඇති පැතිකඩ පින්තූරයක් ලෙස පෙන්වයි, බුබුළක් ලෙස දිස් වේ"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"සංවාද දැනුම්දීම්වල ඉහළින්ම සහ අගුලු තිරයේ ඇති පැතිකඩ පින්තූරයක් ලෙස පෙන්වයි, බාධා නොකරන්න සඳහා බාධා කරයි"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"සංවාද දැනුම්දීම්වල ඉහළින්ම සහ අගුලු තිරයේ ඇති පැතිකඩ පින්තූරයක් ලෙස පෙන්වයි, බුබුළක් ලෙස දිස් වේ, බාධා නොකරන්න සඳහා බාධා කරයි"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"සංගීතය"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"දින දර්ශනය"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"බාධා නොකරන්න"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"හඩ පරිමා බොත්තම් කෙටිමග"</string>
     <string name="battery" msgid="769686279459897127">"බැටරිය"</string>
     <string name="headset" msgid="4485892374984466437">"හෙඩ්සෙට්"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ක්‍රියා විරහිතයි"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"බ්ලූටූත් ක්‍රියා විරහිතයි"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"බාධා නොකරන්න ක්‍රියා විරහිතයි"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ස්වයංක්‍රිය රීතියක් මගින් බාධා නොකරන්න ක්‍රියාත්මක කරන ලදී (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"යෙදුමක් මගින් බාධා නොකරන්න ක්‍රියාත්මක කරන ලදී (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ස්වයංක්‍රිය රීතියක් හෝ යෙදුමක් මගින් බාධා නොකරන්න ක්‍රියාත්මක කරන ලදී."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"පසුබිමින් ධාවනය වන යෙදුම්"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"බැටරි හා දත්ත භාවිතය පිළිබඳව විස්තර සඳහා තට්ටු කරන්න"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"ජංගම දත්ත ක්‍රියාවිරහිත කරන්නද?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"කාර්යාලය"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"දුරකථන ඇමතුම"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> හරහා)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"කැමරාව"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ස්ථානය"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"මයික්‍රෝෆෝනය"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(විසන්ධි විය)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"මාරු කිරීමට නොහැකිය. නැවත උත්සාහ කිරීමට තට්ටු කරන්න."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"නව උපාංගය යුගල කරන්න"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"මෙම සැසිය විකාශය කිරීමට, කරුණාකර යෙදුම විවෘත කරන්න."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"නොදන්නා යෙදුම"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"නිමැවුම් අංකය"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"නිමැවුම් අංකය පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
     <string name="basic_status" msgid="2315371112182658176">"සංවාදය විවෘත කරන්න"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"මෑත පණිවිඩ, මඟ හැරුණු ඇමතුම් සහ තත්ත්ව යාවත්කාලීන කිරීම් බලන්න"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"සංවාදය"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"බාධා නොකිරීම මගින් විරාම කර ඇත"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> පණිවිඩයක් එවා ඇත: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> රූපයක් යවන ලදී"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> හට තත්ත්ව යාවත්කාලීනයක් ඇත: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"නව තොරතුරු"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"සක්‍රිය යෙදුම්"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"පිටපත් කරන ලදි"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> සිට"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Dismiss copy UI"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"පිටපත් කළ පෙළ සංස්කරණය කරන්න"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"පිටපත් කළ රූපය සංස්කරණය කරන්න"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"අවට උපාංගය වෙත යවන්න"</string>
+    <string name="add" msgid="81036585205287996">"එක් කරන්න"</string>
+    <string name="manage_users" msgid="1823875311934643849">"පරිශීලකයන් කළමනාකරණය කරන්න"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"මෙම දැනුම්දීම බෙදුම් තිරය වෙත ඇද ගෙන යාමට සහාය නොදක්වයි."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ලබා ගත නොහැකිය"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ප්‍රමුඛතා ප්‍රකාරය"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"සීනුව සකසන ලදි"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"සහායක ආගන්තුක ප්‍රකාරය සබලයි"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"කැමරාව සහ මයික් ක්‍රියාවිරහිතයි"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index a3bbe44..2c2a7c8 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI systému"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Batéria sa môže čoskoro minúť"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Zostáva <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Nedá sa nabíjať cez USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Použite nabíjačku dodanú so zariadením"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Tvár bola overená"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrdené"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Overenie dokončíte klepnutím na Potvrdiť"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Overené"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Použiť PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Použiť vzor"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zavrieť"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"úplné ticho"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"iba budíky"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Režim bez vyrušení."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Rozhranie Bluetooth je zapnuté."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Budík nastavený na <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Pult s dezertami"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Šetrič obrazovky"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Režim bez vyrušení"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nie sú k dispozícii žiadne spárované zariadenia"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Upozornenia"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzácie"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vymazať všetky tiché upozornenia"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Upozornenia sú pozastavené režimom bez vyrušení"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Spustiť"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Žiadne upozornenia"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zariadenie spravuje tvoj rodič"</string>
@@ -497,6 +507,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stav:&lt;/b&gt; Preradené nižšie"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Zobrazuje sa v hornej časti upozornení konverzácie a ako profilová fotka na uzamknutej obrazovke"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Zobrazuje sa ako bublina v hornej časti upozornení konverzácie a profilová fotka na uzamknutej obrazovke"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Zobrazuje sa v hornej časti upozornení konverzácie a ako profilová fotka na uzamknutej obrazovke, preruší režim bez vyrušení"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Zobrazuje sa ako bublina v hornej časti upozornení konverzácie a profilová fotka na uzamknutej obrazovke, preruší režim bez vyrušení"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorita"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nepodporuje funkcie konverzácie"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Tieto upozornenia sa nedajú upraviť."</string>
@@ -576,6 +588,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Hudba"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendár"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Režim bez vyrušení"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Skratka tlačidiel hlasitosti"</string>
     <string name="battery" msgid="769686279459897127">"Batéria"</string>
     <string name="headset" msgid="4485892374984466437">"Náhlavná súprava"</string>
@@ -694,6 +707,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Pripojenie Wi‑Fi je vypnuté"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Rozhranie Bluetooth je vypnuté"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Režim bez vyrušení je vypnutý"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Režim bez vyrušení bol zapnutý automatickým pravidlom (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Režim bez vyrušení bol zapnutý aplikáciou (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Režim bez vyrušení bol zapnutý automatickým pravidlom alebo aplikáciou."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikácie sú spustené na pozadí"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Klepnutím zobrazíte podrobnosti o batérii a spotrebe dát"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Chcete vypnúť mobilné dáta?"</string>
@@ -718,6 +735,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(práca)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonický hovor"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(prostredníctvom aplikácie <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparát"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"poloha"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofón"</string>
@@ -818,6 +837,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odpojené)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nedá sa prepnúť. Zopakujte klepnutím."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovať nové zariadenie"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ak chcete túto reláciu prenášať, otvorte aplikáciu."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznáma aplikácia"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo zostavy"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo zostavy bolo skopírované do schránky."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvorená konverzácia"</string>
@@ -851,6 +872,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Pozrite si nedávne správy, zmeškané hovory a aktualizácie stavu"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Konverzácia"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Pozastavené režimom bez vyrušení"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> poslal(a) správu: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> poslal(a) obrázok"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> má aktualizáciu statusu: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -891,8 +913,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktívnych aplikácií</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktívna aplikácia</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <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>
     <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>
@@ -903,8 +924,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Upraviť skopírovaný text"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Upraviť skopírovaný obrázok"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Odoslať do zariadenia v okolí"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"Pridať"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Spravovať používateľov"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Toto upozornenie nepodporuje presun na rozdelenú obrazovku."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nie je k dispozícii"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Režim priority"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Budík je nastavený"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Režim Asistenta pre hostí je aktivovaný"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera a mikrofón sú vypnuté"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# upozornenie}few{# upozornenia}many{# notifications}other{# upozornení}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index d657277..6996d56 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -20,7 +20,12 @@
 <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">"Sistemski uporabniški vmesnik"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Baterija bo morda kmalu izpraznjena"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Še <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Ni mogoče polniti prek USB-ja"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Uporabite polnilnik, ki je bil priložen napravi"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Pristnost obraza je potrjena"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potrjeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Za dokončanje se dotaknite »Potrdite«"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Preverjena pristnost"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Uporabi kodo PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Uporabi vzorec"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zapri"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"popolna tišina"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ne moti."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth je vklopljen."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm je nastavljen čez: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Vitrina za sladice"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Ohranjeval. zaslona"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne moti"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Na voljo ni nobene seznanjene naprave"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterija na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -354,6 +363,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Obvestila"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Pogovori"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Brisanje vseh tihih obvestil"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Prikazovanje obvestil je začasno zaustavljeno z načinom »ne moti«"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Začni zdaj"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ni obvestil"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"To napravo upravlja tvoj starš"</string>
@@ -497,6 +507,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Stanje:&lt;/b&gt; Uvrščeno nižje"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Prikaz na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Prikaz v obliki oblačka na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu."</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikaz na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu, preglasitev načina Ne moti."</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikaz v obliki oblačka na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu, preglasitev načina Ne moti."</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prednostno"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podpira pogovornih funkcij."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Za ta obvestila ni mogoče spremeniti nastavitev."</string>
@@ -576,6 +588,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sporočila SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Glasba"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Koledar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne moti"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Bližnjica z gumboma za glasnost"</string>
     <string name="battery" msgid="769686279459897127">"Baterija"</string>
     <string name="headset" msgid="4485892374984466437">"Slušalke z mikrofonom"</string>
@@ -694,6 +707,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi je izklopljen"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth je izklopljen"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Način »ne moti« je izklopljen"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Samodejno pravilo (<xliff:g id="ID_1">%s</xliff:g>) je vklopilo način »ne moti«."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je vklopila način »ne moti«."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način »ne moti« je bil vklopljen zaradi samodejnega pravila ali aplikacije."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije, ki se izvajajo v ozadju"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Dotaknite se za prikaz podrobnosti porabe baterije in prenosa podatkov"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Želite izklopiti prenos podatkov v mobilnih omrežjih?"</string>
@@ -718,6 +735,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(za delo)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonski klic"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(prek aplikacije <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparat"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"lokacijo"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -818,6 +837,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(povezava je prekinjena)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Preklop ni mogoč. Če želite poskusiti znova, se dotaknite."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Seznanitev nove naprave"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Če želite predvajati to sejo, odprite aplikacijo."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznana aplikacija"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string>
     <string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string>
@@ -851,6 +872,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Več kot <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Ogled nedavnih sporočil, neodgovorjenih klicev in posodobitev stanj"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Pogovor"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"To je začasno zaustavil način »ne moti«."</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"Oseba <xliff:g id="NAME">%1$s</xliff:g> je poslala sporočilo: <xliff:g id="NOTIFICATION">%2$s</xliff:g>."</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"Oseba <xliff:g id="NAME">%1$s</xliff:g> je poslala sliko."</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"Oseba <xliff:g id="NAME">%1$s</xliff:g> je posodobila stanje: <xliff:g id="STATUS">%2$s</xliff:g>."</string>
@@ -891,8 +913,7 @@
       <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aktivne aplikacije</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktivnih aplikacij</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</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>
@@ -903,8 +924,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Uredi kopirano besedilo"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Uredi kopirano sliko"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošlji v napravo v bližini"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"Dodaj"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Upravljanje uporabnikov"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"To obvestilo ne podpira vlečenja v razdeljen zaslon."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ni na voljo."</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prednostni način"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je nastavljen."</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Način za goste je omogočen za Pomočnika."</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat in mikrofon sta izklopljena."</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obvestilo}one{# obvestilo}two{# obvestili}few{# obvestila}other{# obvestil}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index f8ba65af..bea8d83 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -20,7 +20,12 @@
 <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">"Ndërfaqja e përdoruesit të sistemit"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Bateria mund të mbarojë së shpejti"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Ka mbetur edhe <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Nuk mund të ngarkohet përmes USB-së"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Përdor karikuesin që ke marrë me pajisjen"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Fytyra u vërtetua"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Konfirmuar"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trokit \"Konfirmo\" për ta përfunduar"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"U vërtetua"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Përdor kodin PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Përdor motivin"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Mbylle"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"heshtje e plotë"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"vetëm alarmet"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Mos shqetëso."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth-i."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"\"Bluetooth-i\" është i aktivizuar."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarmi u caktua për në <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"\"Kutia e ëmbëlsirës\""</string>
     <string name="start_dreams" msgid="9131802557946276718">"Mbrojtësi i ekranit"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Eternet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Mos shqetëso"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nuk ofrohet për përdorim asnjë pajisje e çiftuar"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Njoftimet"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Bisedat"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Pastro të gjitha njoftimet në heshtje"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Njoftimet janë vendosur në pauzë nga modaliteti \"Mos shqetëso\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Fillo tani"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Asnjë njoftim"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kjo pajisje menaxhohet nga prindi yt"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Statusi:&lt;/b&gt; Renditur më poshtë"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Shfaqet në krye të njoftimeve të bisedës dhe si fotografia e profilit në ekranin e kyçjes"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Shfaqet në krye të njoftimeve të bisedës, shfaqet si fotografia e profilit në ekranin e kyçjes dhe shfaqet si flluskë"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Shfaqet në krye të njoftimeve të bisedës, shfaqet si fotografia e profilit në ekranin e kyçjes dhe ndërpret modalitetin \"Mos shqetëso\""</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shfaqet në krye të njoftimeve të bisedës dhe si fotografia e profilit në ekranin e kyçjes, shfaqet si flluskë dhe ndërpret modalitetin \"Mos shqetëso\""</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Me përparësi"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mbështet veçoritë e bisedës"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Këto njoftime nuk mund të modifikohen."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzikë"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendari"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Mos shqetëso"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Shkurtorja e butonave të volumit"</string>
     <string name="battery" msgid="769686279459897127">"Bateria"</string>
     <string name="headset" msgid="4485892374984466437">"Kufjet me mikrofon"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi është joaktiv"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth-i është joaktiv"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Modaliteti \"Mos shqetëso\" është joaktiv"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një rregull automatik (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një aplikacion (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Modaliteti \"Mos shqetëso\" është aktivizuar nga një rregull automatik ose një aplikacion."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacionet që ekzekutohen në sfond"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Trokit për detaje mbi baterinë dhe përdorimin e të dhënave"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Të çaktivizohen të dhënat celulare?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(puna)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonata"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(nëpërmjet <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamerën"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"vendndodhjen"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonin"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(shkëputur)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nuk mund të ndërrohet. Trokit për të provuar përsëri."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Çifto pajisjen e re"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Hap aplikacionin për të transmetuar këtë seancë."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikacion i panjohur"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numri i ndërtimit"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numri i ndërtimit u kopjua te kujtesa e fragmenteve"</string>
     <string name="basic_status" msgid="2315371112182658176">"Hap bisedën"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Mbi <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Shiko mesazhet e fundit, telefonatat e humbura dhe përditësimet e statusit"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Biseda"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Vendosur në pauzë nga \"Mos shqetëso\""</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> dërgoi një mesazh: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> dërgoi një imazh"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ka një përditësim të statusit: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacione aktive</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikacion aktiv</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informacion i ri"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplikacionet aktive"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Ndalo"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Ndaluar"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"U kopjua"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Nga <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Hiq kopjen e ndërfaqes së përdoruesit"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifiko tekstin e kopjuar"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifiko imazhin e kopjuar"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Dërgo te pajisja në afërsi"</string>
+    <string name="add" msgid="81036585205287996">"Shto"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Menaxho përdoruesit"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Ky njoftim nuk mbështet zvarritjen në \"Ekranin e ndarë\"."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nuk ofrohet"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modaliteti \"Me përparësi\""</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmi është caktuar"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Modaliteti \"vizitor\" i \"Asistentit\" është aktivizuar"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dhe mikrofoni janë joaktivë"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 5d89cf1..f373eea 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI система"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Батерија ће се можда ускоро испразнити"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Још <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Пуњење преко USB-а није успело"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Користите пуњач који сте добили уз уређај"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лице је потврђено"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврђено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Додирните Потврди да бисте завршили"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Затвори"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"потпуна тишина"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"само аларми"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не узнемиравај."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth је укључен."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Аларм је подешен за <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -206,6 +214,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Витрина са посластицама"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Чувар екрана"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Етернет"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не узнемиравај"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Није доступан ниједан упарени уређај"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -351,6 +360,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Обавештења"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Конверзације"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Обришите сва нечујна обавештења"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Обавештења су паузирана режимом Не узнемиравај"</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>
@@ -494,6 +504,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Статус:&lt;/b&gt; Рангирано ниже"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, појављује се као облачић"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, прекида режим Не узнемиравај"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, појављује се као облачић, прекида режим Не узнемиравај"</string>
     <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>
@@ -571,6 +583,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не узнемиравај"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Пречица за дугмад за јачину звука"</string>
     <string name="battery" msgid="769686279459897127">"Батерија"</string>
     <string name="headset" msgid="4485892374984466437">"Наглавне слушалице"</string>
@@ -689,6 +702,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"WiFi је искључен"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth је искључен"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Режим Не узнемиравај је искључен"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Аутоматско правило (<xliff:g id="ID_1">%s</xliff:g>) је укључило режим Не узнемиравај."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апликација (<xliff:g id="ID_1">%s</xliff:g>) је укључила режим Не узнемиравај."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Аутоматско правило или апликација су укључили режим Не узнемиравај."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Апликације покренуте у позадини"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Додирните за детаље о батерији и потрошњи података"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Желите да искључите мобилне податке?"</string>
@@ -713,6 +730,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(посао)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонски позив"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(преко: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"камеру"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"локацију"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
@@ -812,6 +831,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(веза је прекинута)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Пребацивање није успело. Пробајте поново."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Упари нови уређај"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Да бисте пребацивали ову сесију, отворите апликацију."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
     <string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string>
@@ -845,6 +866,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Погледајте недавне поруке, пропуштене позиве и ажурирања статуса"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Конверзација"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Паузирано режимом Не узнемиравај"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> је послао/ла поруку: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> шаље слику"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има ажурирање статуса: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -884,8 +906,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нове информације"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активне апликације"</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>
@@ -893,14 +914,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано је"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Из: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Одбаци копирање корисничког интерфејса"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Измените копирани текст"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Измените копирану слику"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Пошаљи на уређај у близини"</string>
+    <string name="add" msgid="81036585205287996">"Додај"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Управљаjте корисницима"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Ово обавештење не подржава превлачење на подељени екран."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi није доступан"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетни режим"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Аларм је подешен"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Омогућен је режим госта у Помоћнику"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон су искључени"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index b9a3ab1..638ba9f 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -20,7 +20,12 @@
 <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">"Gränssnitt"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Batteriet kan ta slut snart"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> kvar"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Det går inte att ladda via USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Använd laddaren som följde med enheten."</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansiktet har autentiserats"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekräftat"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Slutför genom att trycka på Bekräfta"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentiserad"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Använd pinkod"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Använd mönster"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Stäng"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"helt tyst"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"endast alarm"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Stör ej."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth på."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarmet ringer <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessertdisken"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Skärmsläckare"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Stör ej"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Det finns inga kopplade enheter tillgängliga"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Aviseringar"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konversationer"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Rensa alla ljudlösa aviseringar"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Aviseringar har pausats via Stör ej"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Starta nu"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Inga aviseringar"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Den här enheten hanteras av din förälder"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Sänkt"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Visas högst upp i konversationsaviseringarna och som profilbild på låsskärmen"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Visas högst upp i konversationsaviseringarna och som profilbild på låsskärmen, visas som bubbla"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Visas högst upp i konversationsaviseringarna och som profilbild på låsskärmen, åsidosätter Stör ej"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Visas högst upp i konversationsaviseringarna och som profilbild på låsskärmen, visas som bubbla, åsidosätter Stör ej"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inte stöd för konversationsfunktioner"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Det går inte att ändra de här aviseringarna."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sms"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Stör ej"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Genväg till volymknappar"</string>
     <string name="battery" msgid="769686279459897127">"Batteri"</string>
     <string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"wifi är inaktiverat"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth är inaktiverat"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Stör ej är inaktiverat"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Stör ej aktiverades via en automatisk regel (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Stör ej aktiverades via en app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Stör ej aktiverades via en automatisk regel eller en app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Appar körs i bakgrunden"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Tryck för information om batteri- och dataanvändning"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Vill du inaktivera mobildata?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(jobb)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonsamtal"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(via <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"plats"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(frånkopplad)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Misslyckat byte. Tryck och försök igen."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parkoppla en ny enhet"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öppna appen om du vill casta den här sessionen."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Okänd app"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string>
     <string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"över <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Se de senaste meddelandena, missade samtal och statusuppdateringar"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Konversation"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Pausad av Stör ej"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> skickade ett meddelande: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> skickade en bild"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> har gjort en statusuppdatering: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aktiva appar</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aktiv app</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Ny information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiva appar"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Stoppa"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Stoppad"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopierades"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Från <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Stäng användargränssnittet för kopiering"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Redigera kopierad text"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Redigera kopierad bild"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Skicka till enhet i närheten"</string>
+    <string name="add" msgid="81036585205287996">"Lägg till"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Hantera användare"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Det går inte att dra den här aviseringen till delad skärm."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi är inte tillgängligt"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetsläge"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmet är aktiverat"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Gästläget för assistenten är aktiverat"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kameran och mikrofonen är avstängda"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 803a2b5..931f634 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -20,7 +20,12 @@
 <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">"Kiolesura"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Chaji inaweza kuisha hivi karibuni"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Imebakisha <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Haiwezi kuchaji kupitia USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Tumia chaja ambayo ilikuja na kifaa chako"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Uso umethibitishwa"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Imethibitishwa"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Gusa Thibitisha ili ukamilishe"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Umethibitishwa"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Tumia PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Tumia mchoro"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Funga"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"kimya kabisa"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"kengele pekee"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Usinisumbue."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth imewashwa."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Kengele imewashwa na italia <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Sanduku la Vitindamlo"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Taswira ya skrini"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Usinisumbue"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Hakuna vifaa vilivyooanishwa vinavyopatikana"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Arifa"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Mazungumzo"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Futa arifa zote zisizo na sauti"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Kipengele cha Usinisumbue kimesitisha arifa"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Anza sasa"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Hakuna arifa"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kifaa hiki kinadhibitiwa na mzazi wako"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Hali:&lt;/b&gt; Imeorodheshwa Katika Nafasi ya Chini"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Huonyeshwa kwenye sehemu ya juu ya arifa za mazungumzo na kama picha ya wasifu kwenye skrini iliyofungwa"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Huonyeshwa kwenye sehemu ya juu ya arifa za mazungumzo na kama picha ya wasifu kwenye skrini iliyofungwa. Huonekana kama kiputo"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Huonyeshwa kwenye sehemu ya juu ya arifa za mazungumzo na kama picha ya wasifu kwenye skrini iliyofungwa. Hukatiza kipengele cha Usinisumbue"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Huonyeshwa kwenye sehemu ya juu ya arifa za mazungumzo na kama picha ya wasifu kwenye skrini iliyofungwa. Huonekana kama kiputo na hukatiza kipengele cha Usinisumbue"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Kipaumbele"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> haitumii vipengele vya mazungumzo"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Arifa hizi haziwezi kubadilishwa."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muziki"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalenda"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Usinisumbue"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Njia ya mkato ya vitufe vya sauti"</string>
     <string name="battery" msgid="769686279459897127">"Betri"</string>
     <string name="headset" msgid="4485892374984466437">"Vifaa vya sauti"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi imezimwa"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth imezimwa"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Kipengele cha Usinisumbue kimezimwa"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Kipengele cha Usinisumbue kimewashwa na sheria ya kiotomatiki <xliff:g id="ID_1">%s</xliff:g>."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Kipengele cha usinisumbue kimewashwa na programu (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Kipengele cha Usinisumbue kimewashwa na sheria ya kiotomatiki au programu."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Programu zinatumika chinichini"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Gusa ili upate maelezo kuhusu betri na matumizi ya data"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Ungependa kuzima data ya mtandao wa simu?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(kazini)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Simu"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(kupitia <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"mahali"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"maikrofoni"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(imetenganishwa)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Imeshindwa kubadilisha. Gusa ili ujaribu tena."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Oanisha kifaa kipya"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ili utume kipindi hiki, tafadhali fungua programu."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Programu isiyojulikana"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nambari ya muundo"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nambari ya muundo imewekwa kwenye ubao wa kunakili."</string>
     <string name="basic_status" msgid="2315371112182658176">"Fungua mazungumzo"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Angalia ujumbe wa hivi majuzi, simu ambazo hukujibu na taarifa za hali"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Mazungumzo"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Imesimamishwa na kipengele cha Usinisumbue"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ametuma ujumbe: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ametuma picha"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ana taarifa kuhusu hali: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other">Programu <xliff:g id="COUNT_1">%s</xliff:g> zinatumika</item>
       <item quantity="one">Programu <xliff:g id="COUNT_0">%s</xliff:g> inatumika</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Maelezo mapya"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Programu zinazotumika"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Simamisha"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Imesimamishwa"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Imenakiliwa"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Kutoka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Ondoa kiolesura cha nakala"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Badilisha maandishi yaliyonakiliwa"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Badilisha picha iliyonakiliwa"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Tuma kwenye kifaa kilicho karibu"</string>
+    <string name="add" msgid="81036585205287996">"Weka"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Dhibiti watumiaji"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Arifa hii hairuhusu kuburuta kwenye Skrini iliyogawanyika."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi haipatikani"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Hali ya kipaumbele"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Kengele imewekwa"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Matumizi ya wageni ya Mratibu yamewashwa"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera na maikrofoni zimezimwa"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index 4f95811b..c56ba7b 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -22,6 +22,8 @@
     <dimen name="ambient_indication_margin_bottom">115dp</dimen>
     <dimen name="lock_icon_margin_bottom">60dp</dimen>
 
+    <dimen name="qs_media_session_height_expanded">172dp</dimen>
+
     <!-- margin from keyguard status bar to clock. For split shade it should be
          keyguard_split_shade_top_margin - status_bar_header_height_keyguard = 8dp -->
     <dimen name="keyguard_clock_top_margin">8dp</dimen>
@@ -34,17 +36,47 @@
     <item name="controls_task_view_width_percentage" translatable="false" format="float" type="dimen">0.45</item>
     <dimen name="controls_task_view_right_margin">8dp</dimen>
 
-    <!-- Distance that the full shade transition takes in order for qs to fully transition to the
-         shade -->
-    <dimen name="lockscreen_shade_qs_transition_distance">200dp</dimen>
+    <dimen name="split_shade_header_height">42dp</dimen>
+
+    <!-- Distance that the full shade transition takes in order to complete by tapping on a button
+         like "expand". -->
+    <dimen name="lockscreen_shade_transition_by_tap_distance">200dp</dimen>
+
+    <!-- Distance that the full shade transition takes in order to complete.  -->
+    <dimen name="lockscreen_shade_full_transition_distance">200dp</dimen>
+
+    <!-- Distance that the full shade transition takes in order for media to fully transition to
+         the shade -->
+    <dimen name="lockscreen_shade_media_transition_distance">200dp</dimen>
 
     <!-- Distance that the full shade transition takes in order for scrim to fully transition to
          the shade (in alpha) -->
-    <dimen name="lockscreen_shade_scrim_transition_distance">200dp</dimen>
+    <dimen name="lockscreen_shade_scrim_transition_distance">80dp</dimen>
 
-    <!-- Distance that the full shade transition takes in order for media to fully transition to
-     the shade -->
-    <dimen name="lockscreen_shade_media_transition_distance">200dp</dimen>
+    <!-- Distance that the full shade transition takes in order for the keyguard content on
+         NotificationPanelViewController to fully fade (e.g. Clock & Smartspace) -->
+    <dimen name="lockscreen_shade_npvc_keyguard_content_alpha_transition_distance">80dp</dimen>
 
-    <dimen name="notification_panel_margin_horizontal">12dp</dimen>
+    <!-- Distance that the full shade transition takes in order for the notification shell to fully
+         expand. -->
+    <dimen name="lockscreen_shade_notif_shelf_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+    <!-- Distance that the full shade transition takes in order for the Quick Settings to fully
+         fade and expand. -->
+    <dimen name="lockscreen_shade_qs_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+    <!-- Distance that the full shade transition takes in order for depth of the wallpaper to fully
+         change.
+         On split-shade, there should be no depth effect, so setting the value to 0. -->
+    <dimen name="lockscreen_shade_depth_controller_transition_distance">0dp</dimen>
+
+    <!-- Distance that the full shade transition takes in order for the UDFPS Keyguard View to fully
+         fade. -->
+    <dimen name="lockscreen_shade_udfps_keyguard_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+    <!-- Used for StatusBar to know that a transition is in progress. At the moment it only checks
+         whether the progress is > 0, therefore this value is not very important. -->
+    <dimen name="lockscreen_shade_status_bar_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+    <dimen name="notification_panel_margin_horizontal">24dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp-port/dimens.xml b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
index c990605..f5c0509 100644
--- a/packages/SystemUI/res/values-sw600dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 <resources>
-    <dimen name="notification_panel_margin_horizontal">60dp</dimen>
+    <dimen name="notification_panel_margin_horizontal">48dp</dimen>
     <dimen name="status_view_margin_horizontal">62dp</dimen>
     <dimen name="keyguard_clock_top_margin">40dp</dimen>
     <dimen name="keyguard_status_view_bottom_margin">40dp</dimen>
diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
index 71c1958..f267088 100644
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
@@ -23,5 +23,7 @@
 
     <dimen name="keyguard_split_shade_top_margin">72dp</dimen>
 
-    <dimen name="notification_panel_margin_horizontal">24dp</dimen>
+    <dimen name="split_shade_header_height">56dp</dimen>
+
+    <dimen name="qs_media_session_height_expanded">184dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp-port/dimens.xml b/packages/SystemUI/res/values-sw720dp-port/dimens.xml
index e5f502f..44f8f3a 100644
--- a/packages/SystemUI/res/values-sw720dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-port/dimens.xml
@@ -21,8 +21,11 @@
      for different hardware and product builds. -->
 <resources>
     <dimen name="status_view_margin_horizontal">124dp</dimen>
-    <dimen name="notification_panel_margin_horizontal">120dp</dimen>
     <dimen name="keyguard_clock_top_margin">80dp</dimen>
     <dimen name="keyguard_status_view_bottom_margin">80dp</dimen>
     <dimen name="bouncer_user_switcher_y_trans">90dp</dimen>
+
+    <dimen name="notification_panel_margin_horizontal">96dp</dimen>
+    <dimen name="notification_side_paddings">40dp</dimen>
+    <dimen name="notification_section_divider_height">16dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 094559f..e856294f 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -20,7 +20,12 @@
 <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">"சாதனத்தின் UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"பேட்டரி விரைவில் தீர்ந்துவிடக்கூடும்"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> உள்ளது"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB மூலம், சார்ஜ் செய்ய முடியாது"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"உங்கள் சாதனத்துடன் வழங்கப்பட்ட சார்ஜரைப் பயன்படுத்தவும்"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"முகம் அங்கீகரிக்கப்பட்டது"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"உறுதிப்படுத்தப்பட்டது"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"முடிக்க \'உறுதிப்படுத்துக\' என்பதை தட்டவும்"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"மூடு"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"முழு அமைதி"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"அலாரங்கள் மட்டும்"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"தொந்தரவு செய்ய வேண்டாம்."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"புளூடூத்."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"புளூடூத் இயக்கத்தில்."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> மணிக்கு அலாரம் அமைக்கப்பட்டது."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"இனிப்பு வடிவங்கள்"</string>
     <string name="start_dreams" msgid="9131802557946276718">"ஸ்கிரீன் சேவர்"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ஈதர்நெட்"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"தொந்தரவு செய்ய வேண்டாம்"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"புளூடூத்"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"இணைக்கப்பட்ட சாதனங்கள் இல்லை"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> பேட்டரி"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"அறிவிப்புகள்"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"உரையாடல்கள்"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"சைலன்ட் அறிவிப்புகள் அனைத்தையும் அழிக்கும்"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தின் மூலம் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;நிலை:&lt;/b&gt; முக்கியத்துவம் குறைக்கப்பட்டது"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"உரையாடல் அறிவிப்புகளின் மேற்பகுதியில் காட்டப்படும், திரை பூட்டப்பட்டிருக்கும்போது சுயவிவரப் படமாகக் காட்டப்படும்"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"உரையாடல் அறிவிப்புகளின் மேற்பகுதியில் காட்டப்படும், திரை பூட்டப்பட்டிருக்கும்போது சுயவிவரப் படமாகக் காட்டப்படும், குமிழாகத் தோன்றும்"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"உரையாடல் அறிவிப்புகளின் மேற்பகுதியில் காட்டப்படும், திரை பூட்டப்பட்டிருக்கும்போது சுயவிவரப் படமாகக் காட்டப்படும், தொந்தரவு செய்ய வேண்டாம் அம்சம் இயக்கப்பட்டிருக்கும்போதும் காட்டப்படும்"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"உரையாடல் அறிவிப்புகளின் மேற்பகுதியில் காட்டப்படும், திரை பூட்டப்பட்டிருக்கும்போது சுயவிவரப் படமாகக் காட்டப்படும், குமிழாகத் தோன்றும், தொந்தரவு செய்ய வேண்டாம் அம்சம் இயக்கப்பட்டிருக்கும்போதும் காட்டப்படும்"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"மியூசிக்"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"தொந்தரவு செய்ய வேண்டாம்"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ஒலியளவுப் பொத்தான்களுக்கான ஷார்ட்கட்"</string>
     <string name="battery" msgid="769686279459897127">"பேட்டரி"</string>
     <string name="headset" msgid="4485892374984466437">"ஹெட்செட்"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"வைஃபை முடக்கத்தில் உள்ளது"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"புளூடூத் முடக்கத்தில் உள்ளது"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"\"தொந்தரவு செய்ய வேண்டாம்\" முடக்கத்தில் உள்ளது"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, தானியங்கு விதி (<xliff:g id="ID_1">%s</xliff:g>) இயக்கியுள்ளது."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, ஆப்ஸ் (<xliff:g id="ID_1">%s</xliff:g>) இயக்கியுள்ளது."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\"தொந்தரவு செய்ய வேண்டாம்\" எனும் பயன்முறையை, தானியங்கு விதி அல்லது ஆப்ஸ் இயக்கியுள்ளது."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"பின்னணியில் இயங்கும் ஆப்ஸ்"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"பேட்டரி மற்றும் டேட்டா உபயோக விவரங்களைக் காண, தட்டவும்"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"மொபைல் டேட்டாவை ஆஃப் செய்யவா?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(பணி)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"மொபைல் அழைப்பு"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> மூலம்)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"கேமரா"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"இருப்பிடம்"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"மைக்ரோஃபோன்"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(துண்டிக்கப்பட்டது)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"இணைக்க முடியவில்லை. மீண்டும் முயல தட்டவும்."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"புதிய சாதனத்தை இணைத்தல்"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"இந்த அமர்வை அலைபரப்ப ஆப்ஸைத் திறங்கள்."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"அறியப்படாத ஆப்ஸ்"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"பதிப்பு எண்"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"பதிப்பு எண் கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது."</string>
     <string name="basic_status" msgid="2315371112182658176">"திறந்தநிலை உரையாடல்"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"சமீபத்திய மெசேஜ்களையும் தவறிய அழைப்புகளையும் ஸ்டேட்டஸ் அப்டேட்களையும் பார்க்கலாம்"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"உரையாடல்"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"தொந்தரவு செய்ய வேண்டாம் அம்சத்தால் இடைநிறுத்தப்பட்டது"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ஒரு மெசேஜ் அனுப்பியுள்ளார்: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ஒரு படம் அனுப்பியுள்ளார்"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> புதிய ஸ்டேட்டஸ் வைத்துள்ளார்: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"புதிய தகவல்கள்"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"செயலிலுள்ள ஆப்ஸ்"</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>
@@ -889,8 +910,14 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"நகலெடுத்த வார்த்தைகளைத் திருத்து"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"நகலெடுத்த படத்தைத் திருத்து"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"அருகிலுள்ள சாதனத்திற்கு அனுப்பு"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="add" msgid="81036585205287996">"சேர்"</string>
+    <string name="manage_users" msgid="1823875311934643849">"பயனர்களை நிர்வகித்தல்"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"பிரிக்கப்பட்ட திரைக்குள் இந்த அறிவிப்பை இழுத்துவிட முடியாது."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"வைஃபை கிடைக்கவில்லை"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"முன்னுரிமைப் பயன்முறை"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"அலாரம் அமைக்கப்பட்டுள்ளது"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistant கெஸ்ட் பயன்முறை இயக்கப்பட்டுள்ளது"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"கேமராவும் மைக்கும் ஆஃப் செய்யப்பட்டுள்ளன"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 59e8ef4..6ef8f50 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -20,7 +20,12 @@
 <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">"సిస్టమ్ UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"బ్యాటరీ త్వరలో ఖాళీ అవ్వచ్చు"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> మిగిలి ఉంది"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB ద్వారా ఛార్జ్ చేయలేరు"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"మీ పరికరంతో వచ్చిన ఛార్జర్‌ను ఉపయోగించండి"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ముఖం ప్రామాణీకరించబడింది"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"నిర్ధారించబడింది"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"పూర్తి చేయడానికి \"నిర్ధారించు\" నొక్కండి"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"మూసివేస్తుంది"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"మొత్తం నిశ్శబ్దం"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"అలారాలు మాత్రమే"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"అంతరాయం కలిగించవద్దు."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"బ్లూటూత్."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"బ్లూటూత్ ఆన్‌లో ఉంది."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g>కి అలారం సెట్ చేయబడింది."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"డెజర్ట్ కేస్"</string>
     <string name="start_dreams" msgid="9131802557946276718">"స్క్రీన్ సేవర్"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ఈథర్‌నెట్"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"అంతరాయం కలిగించవద్దు"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"బ్లూటూత్"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"జత చేసిన పరికరాలు ఏవీ అందుబాటులో లేవు"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> బ్యాటరీ"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"నోటిఫికేషన్‌లు"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"సంభాషణలు"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"అన్ని నిశ్శబ్ద నోటిఫికేషన్‌లను క్లియర్ చేస్తుంది"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"అంతరాయం కలిగించవద్దు ద్వారా నోటిఫికేషన్‌లు పాజ్ చేయబడ్డాయి"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;స్టేటస్:&lt;/b&gt; తక్కువ ర్యాంక్‌కు సర్దుబాటు చేయబడింది"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"సంభాషణ నోటిఫికేషన్‌ల ఎగువున, లాక్ స్క్రీన్‌లో ప్రొఫైల్ ఫోటో‌గా చూపిస్తుంది"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"సంభాషణ నోటిఫికేషన్‌ల ఎగువున, లాక్ స్క్రీన్‌లో ప్రొఫైల్ ఫోటో‌గా చూపిస్తుంది, బబుల్‌గా కనిపిస్తుంది"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"సంభాషణ నోటిఫికేషన్‌ల ఎగువున, లాక్ స్క్రీన్‌లో ప్రొఫైల్ ఫోటో‌గా చూపిస్తుంది, \'అంతరాయం కలిగించవద్దు\'ను అంతరాయం కలిగిస్తుంది"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"సంభాషణ నోటిఫికేషన్‌ల ఎగువున, లాక్ స్క్రీన్‌లో ప్రొఫైల్ ఫోటో‌గా చూపిస్తుంది, బబుల్‌గా కనిపిస్తుంది, \'అంతరాయం కలిగించవద్దు\'ను అంతరాయం కలిగిస్తుంది"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"మ్యూజిక్"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"అంతరాయం కలిగించవద్దు"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"వాల్యూమ్ బటన్‌ల షార్ట్‌కట్"</string>
     <string name="battery" msgid="769686279459897127">"బ్యాటరీ"</string>
     <string name="headset" msgid="4485892374984466437">"హెడ్‌సెట్"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ఆఫ్‌లో ఉంది"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"బ్లూటూత్ ఆఫ్‌లో ఉంది"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"అంతరాయం కలిగించవద్దు ఆఫ్‌లో ఉంది"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ఆటోమేటిక్‌ నియమం (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"యాప్ (<xliff:g id="ID_1">%s</xliff:g>) ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"ఆటోమేటిక్‌ నియమం లేదా యాప్ ద్వారా అంతరాయం కలిగించవద్దు ఆన్ చేయబడింది."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"నేపథ్యంలో అమలు అవుతున్న ఆప్‌లు"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"బ్యాటరీ మరియు డేటా వినియోగ వివరాల కోసం నొక్కండి"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"మొబైల్ డేటాను ఆఫ్ చేయాలా?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ఆఫీస్)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"ఫోన్ కాల్"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> ద్వారా)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"కెమెరా"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"లొకేషన్"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"మైక్రోఫోన్"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(డిస్కనెక్ట్ అయ్యింది)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"స్విచ్ చేయడం సాధ్యం కాదు. మళ్ళీ ట్రై చేయడానికి ట్యాప్ చేయండి."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"కొత్త పరికరాన్ని పెయిర్ చేయండి"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ఈ సెషన్‌ను ప్రసారం చేయడానికి, దయచేసి యాప్‌ను తెరవండి."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"తెలియని యాప్"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"బిల్డ్ నంబర్"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"బిల్డ్ నంబర్, క్లిప్‌బోర్డ్‌కు కాపీ చేయబడింది."</string>
     <string name="basic_status" msgid="2315371112182658176">"సంభాషణను తెరవండి"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"ఇటీవలి మెసేజ్‌లు, మిస్స్‌డ్‌ కాల్స్‌, అలాగే స్టేటస్ అప్‌డేట్‌లను చూడండి"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"సంభాషణ"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"అంతరాయం కలిగించవద్దు ద్వారా పాజ్ చేయబడింది"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> మెసేజ్‌ను పంపారు: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ఇమేజ్‌ను పంపారు"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>, స్టేటస్‌ను గురించిన అప్‌డేట్‌ను కలిగి ఉన్నారు: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"కొత్త సమాచారం"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"యాక్టివ్‌గా ఉన్న యాప్‌లు"</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>
@@ -889,8 +910,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"కాపీ చేసిన టెక్స్ట్‌ను ఎడిట్ చేయండి"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"కాపీ చేసిన ఇమేజ్‌లను ఎడిట్ చేయండి"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"సమీపంలోని పరికరానికి పంపండి"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"జోడించండి"</string>
+    <string name="manage_users" msgid="1823875311934643849">"యూజర్‌లను మేనేజ్ చేయండి"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"ఈ నోటిఫికేషన్ స్ప్లిట్‌స్క్రీన్‌కు లాగడానికి సపోర్ట్ చేయదు."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi అందుబాటులో లేదు"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ముఖ్యమైన ఫైల్స్ మోడ్"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"అలారం సెట్ చేశాను"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"అసిస్టెంట్ గెస్ట్ మోడ్ ఎనేబుల్ చేయబడింది"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"కెమెరా, మైక్ ఆఫ్‌లో ఉన్నాయి"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# నోటిఫికేషన్}other{# నోటిఫికేషన్‌లు}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index a207447..9072db4 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"แบตเตอรี่อาจหมดเร็วๆ นี้"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"เหลืออีก <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"ชาร์จผ่าน USB ไม่ได้"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"ใช้ที่ชาร์จที่ให้มาพร้อมกับอุปกรณ์"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ตรวจสอบสิทธิ์ใบหน้าแล้ว"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ยืนยันแล้ว"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"แตะยืนยันเพื่อดำเนินการให้เสร็จสมบูรณ์"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ปิด"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ปิดเสียงทั้งหมด"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"เฉพาะปลุกเท่านั้น"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ห้ามรบกวน"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"บลูทูธ"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"บลูทูธเปิดอยู่"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ตั้งเวลาปลุกไว้ที่ <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"ชั้นแสดงของหวาน"</string>
     <string name="start_dreams" msgid="9131802557946276718">"โปรแกรมรักษาหน้าจอ"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"อีเทอร์เน็ต"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"ห้ามรบกวน"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"บลูทูธ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ไม่มีอุปกรณ์ที่จับคู่ที่สามารถใช้ได้"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"การแจ้งเตือน"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"การสนทนา"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ล้างการแจ้งเตือนแบบไม่มีเสียงทั้งหมด"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"หยุดการแจ้งเตือนชั่วคราวโดย \"ห้ามรบกวน\""</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;สถานะ:&lt;/b&gt; อันดับต่ำลง"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"แสดงที่ด้านบนของการแจ้งเตือนการสนทนาและเป็นรูปโปรไฟล์บนหน้าจอล็อก"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"แสดงที่ด้านบนของการแจ้งเตือนการสนทนาและเป็นรูปโปรไฟล์บนหน้าจอล็อก ปรากฏเป็นบับเบิล"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"แสดงที่ด้านบนของการแจ้งเตือนการสนทนาและเป็นรูปโปรไฟล์บนหน้าจอล็อก แสดงในโหมดห้ามรบกวน"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"แสดงที่ด้านบนของการแจ้งเตือนการสนทนาและเป็นรูปโปรไฟล์บนหน้าจอล็อก ปรากฏเป็นบับเบิล แสดงในโหมดห้ามรบกวน"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"เพลง"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ปฏิทิน"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ห้ามรบกวน"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ทางลัดปุ่มปรับระดับเสียง"</string>
     <string name="battery" msgid="769686279459897127">"แบตเตอรี่"</string>
     <string name="headset" msgid="4485892374984466437">"ชุดหูฟัง"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi ปิดอยู่"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"บลูทูธปิดอยู่"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"\"ห้ามรบกวน\" ปิดอยู่"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"มีการเปิด \"ห้ามรบกวน\" โดยกฎอัตโนมัติ (<xliff:g id="ID_1">%s</xliff:g>)"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"มีการเปิด \"ห้ามรบกวน\" โดยแอป (<xliff:g id="ID_1">%s</xliff:g>)"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"มีการเปิด \"ห้ามรบกวน\" โดยกฎอัตโนมัติหรือแอป"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"แอปที่กำลังทำงานในเบื้องหลัง"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"แตะเพื่อดูรายละเอียดเกี่ยวกับแบตเตอรี่และปริมาณการใช้อินเทอร์เน็ต"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"ปิดอินเทอร์เน็ตมือถือไหม"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ที่ทำงาน)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"การโทร"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(ผ่านทาง <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"กล้องถ่ายรูป"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ตำแหน่ง"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"ไมโครโฟน"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ยกเลิกการเชื่อมต่อแล้ว)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"เปลี่ยนไม่ได้ แตะเพื่อลองอีกครั้ง"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"จับคู่อุปกรณ์ใหม่"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"โปรดเปิดแอปหากต้องการแคสต์เซสชันนี้"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"แอปที่ไม่รู้จัก"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string>
     <string name="basic_status" msgid="2315371112182658176">"เปิดการสนทนา"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"ดูข้อความล่าสุด สายที่ไม่ได้รับ และการอัปเดตสถานะ"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"การสนทนา"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"หยุดชั่วคราวโดยฟีเจอร์ห้ามรบกวน"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ส่งข้อความ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ส่งรูปภาพ"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> มีการอัปเดตสถานะ: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"ข้อมูลใหม่"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ใช้งานอยู่"</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>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"คัดลอกแล้ว"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"จาก <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"ปิด UI การคัดลอก"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"แก้ไขข้อความที่คัดลอก"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"แก้ไขรูปภาพที่คัดลอก"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ส่งไปยังอุปกรณ์ที่อยู่ใกล้เคียง"</string>
+    <string name="add" msgid="81036585205287996">"เพิ่ม"</string>
+    <string name="manage_users" msgid="1823875311934643849">"จัดการผู้ใช้"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"การแจ้งเตือนนี้ไม่รองรับการลากเพื่อแบ่งหน้าจอ"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ใช้ Wi‑Fi ไม่ได้"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"โหมดลำดับความสำคัญ"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ตั้งปลุกแล้ว"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"เปิดใช้โหมดผู้มาเยือนของ Assistant แล้ว"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"กล้องและไมค์ปิดอยู่"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{การแจ้งเตือน # รายการ}other{การแจ้งเตือน # รายการ}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index db9c788..b518c603 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -20,7 +20,12 @@
 <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">"UI ng System"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Malapit nang maubos ang baterya"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> na lang ang natitira"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Hindi makapag-charge sa pamamagitan ng USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Gamitin ang charger na kasama ng iyong device"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Na-authenticate ang mukha"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Nakumpirma"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"I-tap ang Kumpirmahin para kumpletuhin"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Na-authenticate"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gumamit ng PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gumamit ng pattern"</string>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Isara"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ganap na katahimikan"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"mga alarm lang"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Huwag Istorbohin."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Naka-on ang Bluetooth."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Nakatakda ang alarm nang <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Screen saver"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Huwag Istorbohin"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Walang available na mga magkapares na device"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> na baterya"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Mga Notification"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Mga Pag-uusap"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"I-clear ang lahat ng silent na notification"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Mga notification na na-pause ng Huwag Istorbohin"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Magsimula ngayon"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Walang mga notification"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Pinapamahalaan ng magulang mo itong device"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Na-rank nang Mas Mababa"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Makikita sa itaas ng mga notification ng pag-uusap at bilang larawan sa profile sa lock screen"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Makikita sa itaas ng mga notification ng pag-uusap at bilang larawan sa profile sa lock screen, lumalabas bilang bubble"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Makikita sa itaas ng mga notification ng pag-uusap at bilang larawan sa profile sa lock screen, naaabala ang Huwag Istorbohin"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Makikita sa itaas ng mga notification ng pag-uusap at bilang larawan sa profile sa lock screen, lumalabas bilang bubble, naaabala ang Huwag Istorbohin"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priyoridad"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Hindi sinusuportahan ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang mga feature ng pag-uusap"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Hindi puwedeng baguhin ang mga notification na ito."</string>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendaryo"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Huwag Istorbohin"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Shortcut ng mga button ng volume"</string>
     <string name="battery" msgid="769686279459897127">"Baterya"</string>
     <string name="headset" msgid="4485892374984466437">"Headset"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Naka-off ang Wi-Fi"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Naka-off ang Bluetooth"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Naka-off ang Huwag Istorbohin"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Na-on ang Huwag Istorbohin dahil sa isang awtomatikong panuntunan (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Na-on ang Huwag Istorbohin dahil sa isang app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Na-on ang Huwag Istorbohin dahil sa isang awtomatikong panuntunan o app."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Tumatakbo ang mga app sa background"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"I-tap para sa mga detalye tungkol sa paggamit ng baterya at data"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"I-off ang mobile data?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(trabaho)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Tawag sa telepono"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(sa pamamagitan ng <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"lokasyon"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikropono"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nadiskonekta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Hindi makalipat. I-tap para subukan ulit."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Magpares ng bagong device"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para ma-cast ang session na ito, buksan ang app."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Hindi kilalang app"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string>
     <string name="basic_status" msgid="2315371112182658176">"Buksan ang pag-uusap"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Tingnan ang mga kamakailang mensahe, hindi nasagot na tawag, at update sa status"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Pag-uusap"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Na-pause ng Huwag Istorbohin"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"Nagpadala si <xliff:g id="NAME">%1$s</xliff:g> ng mensahe: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"Nagpadala si <xliff:g id="NAME">%1$s</xliff:g> ng larawan"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"May update sa status si <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aktibong app</item>
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> na aktibong app</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Bagong impormasyon"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Mga aktibong app"</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>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Nakopya"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Mula sa <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"I-dismiss ang UI ng pagkopya"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"I-edit ang kinopyang text"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"I-edit ang kinopyang larawan"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Ipadala sa kalapit na device"</string>
+    <string name="add" msgid="81036585205287996">"Magdagdag"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Pamahalaan ang mga user"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Hindi sinusuportahan ng notification na ito ang pag-drag sa Splitscreen."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Hindi available ang Wi‑Fi"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Nakatakda ang alarm"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Naka-enable ang guest mode ng Assistant"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Naka-off ang camera at mikropono"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# na notification}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 308af4f..0f56057 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -20,7 +20,12 @@
 <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">"Sistem Arayüzü"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Pil kısa süre sonra bitebilir"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> kaldı"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB ile şarj edilemiyor"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Cihazınızla birlikte gelen şarj cihazını kullanın"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Yüz kimliği doğrulandı"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Kapat"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"tamamen sessiz"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"yalnızca alarmlar"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Rahatsız Etmeyin."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth açık."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Alarm saati: <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Tatlı Kutusu"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Ekran koruyucu"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Rahatsız Etmeyin"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Kullanılabilir eşlenmiş cihaz yok"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pil düzeyi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirimler"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Görüşmeler"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Sessiz bildirimlerin tümünü temizle"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bildirimler, Rahatsız Etmeyin özelliği tarafından duraklatıldı"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Şimdi başlat"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Bildirim yok"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz ebeveyniniz tarafından yönetiliyor"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Durum:&lt;/b&gt; Daha Düşük Sıralandı"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Görüşme bildirimlerinin üstünde ve kilit ekranında profil resmi olarak gösterilir"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Görüşme bildirimlerinin üstünde ve kilit ekranında profil resmi olarak gösterilir, baloncuk olarak görünür"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Görüşme bildirimlerinin üstünde ve kilit ekranında profil resmi olarak gösterilir, Rahatsız Etmeyin\'i kesintiye uğratır"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Görüşme bildirimlerinin üstünde ve kilit ekranında profil resmi olarak gösterilir, baloncuk olarak görünür, Rahatsız Etmeyin\'i kesintiye uğratır"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Müzik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Takvim"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Rahatsız Etmeyin"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Ses düğmeleri kısayolu"</string>
     <string name="battery" msgid="769686279459897127">"Pil"</string>
     <string name="headset" msgid="4485892374984466437">"Mikrofonlu kulaklık"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>, <xliff:g id="CARRIER_NAME">%1$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Kablosuz bağlantı kapalı"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth kapalı"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Rahatsız Etmeyin kapalı"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Rahatsız Etmeyin ayarı bir otomatik kural (<xliff:g id="ID_1">%s</xliff:g>) tarafından açıldı."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Rahatsız Etmeyin ayarı bir uygulama (<xliff:g id="ID_1">%s</xliff:g>) tarafından açıldı."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Rahatsız Etmeyin ayarı bir otomatik kural veya uygulama tarafından açıldı."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Arka planda çalışan uygulamalar"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Pil ve veri kullanımı ile ilgili ayrıntılar için dokunun"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Mobil veri kapatılsın mı?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(iş)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Sesli arama"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> aracılığıyla)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"konum"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(bağlantı kesildi)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Geçiş yapılamıyor. Tekrar denemek için dokunun."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yeni cihaz eşle"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu oturumu yayınlamak için lütfen uygulamayı açın."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Bilinmeyen uygulama"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Derleme numarası"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Derleme numarası panoya kopyalandı."</string>
     <string name="basic_status" msgid="2315371112182658176">"Görüşmeyi aç"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Yeni mesajları, cevapsız aramaları ve durum güncellemelerini görün"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Görüşme"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Rahatsız Etmeyin özelliği tarafından duraklatıldı"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> bir mesaj gönderdi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> bir resim gönderdi"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>, durumunu güncelledi: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> etkin uygulama</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> etkin uygulama</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Yeni bilgi"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Etkin uygulamalar"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Durdur"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Durduruldu"</string>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Kopyalandı"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasından"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Kopyalanan kullanıcı arayüzünü kapat"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Kopyalanan metni düzenle"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Kopyalanan resmi düzenle"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Yakındaki cihaza gönder"</string>
+    <string name="add" msgid="81036585205287996">"Ekle"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Kullanıcıları yönet"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildirim, bölünmüş ekrana sürüklenmeyi desteklemiyor."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Kablosuz kullanılamıyor"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Öncelik modu"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm kuruldu"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Asistan misafir modu etkinleştirildi"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ve mikrofon kapalı"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 0161060..fa9af2e 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"Акумулятор може невдовзі розрядитися"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Залишилося <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Не вдається зарядити через USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Використовуйте зарядний пристрій, який входить у комплект пристрою"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Обличчя автентифіковано"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Підтверджено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Щоб завершити, натисніть \"Підтвердити\""</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Закрити"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"без сигналів"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"лише будильники"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Не турбувати."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth увімк."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Сигнал установлено на <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -207,6 +215,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Вітрина десертів"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Заставка"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не турбувати"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Немає спарених пристроїв"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> заряду акумулятора"</string>
@@ -354,6 +363,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Сповіщення"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Розмови"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Очистити всі беззвучні сповіщення"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Режим \"Не турбувати\" призупинив сповіщення"</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>
@@ -497,6 +507,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Статус&lt;/b&gt;: пріоритет знижено"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, показується у вигляді спливаючої підказки"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, показується навіть у режимі \"Не турбувати\""</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, відображається як спливаючий чат, перериває режим \"Не турбувати\""</string>
     <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>
@@ -576,6 +588,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не турбувати"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Кнопки гучності на корпусі"</string>
     <string name="battery" msgid="769686279459897127">"Акумулятор"</string>
     <string name="headset" msgid="4485892374984466437">"Гарнітура"</string>
@@ -694,6 +707,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi вимкнено"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth вимкнено"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Режим \"Не турбувати\" вимкнено"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Автоматичне правило ввімкнуло режим \"Не турбувати\" (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Додаток увімкнув режим \"Не турбувати\" (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автоматичне правило або додаток увімкнули режим \"Не турбувати\"."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Додатки, які працюють у фоновому режимі"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Торкніться, щоб перевірити використання акумулятора й трафік"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Вимкнути мобільний Інтернет?"</string>
@@ -718,6 +735,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(робота)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонний дзвінок"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(через <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"місце"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"мікрофон"</string>
@@ -818,6 +837,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(від’єднано)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не вдалося змінити підключення. Натисніть, щоб повторити спробу."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Підключити новий пристрій"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Щоб транслювати цей сеанс, відкрийте додаток."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невідомий додаток"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер складання"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номер складання скопійовано в буфер обміну."</string>
     <string name="basic_status" msgid="2315371112182658176">"Відкрита розмова"</string>
@@ -851,6 +872,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Переглядайте останні повідомлення, пропущені виклики й оновлення статусу"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Розмова"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Призупинено функцією \"Не турбувати\""</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> надсилає повідомлення: \"<xliff:g id="NOTIFICATION">%2$s</xliff:g>\""</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> надсилає зображення"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> публікує новий статус: \"<xliff:g id="STATUS">%2$s</xliff:g>\""</string>
@@ -891,8 +913,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нова інформація"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активні додатки"</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>
@@ -900,14 +921,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Скопійовано"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"З додатка <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Закрити вікно копіювання"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Редагувати скопійований текст"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Редагувати скопійоване зображення"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Надіслати на пристрій поблизу"</string>
+    <string name="add" msgid="81036585205287996">"Додати"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Керувати користувачами"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Це сповіщення не підтримує режим розділеного екрана."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Мережа Wi-Fi недоступна"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Режим пріоритету"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлено"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Увімкнено режим гостя Асистента"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камеру й мікрофон вимкнено"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index ce492dd..3576021 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -20,7 +20,12 @@
 <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">"‏سسٹم UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"بیٹری جلد ہی ختم ہو سکتی ہے"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> باقی ہے"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"‏USB کے ذریعے چارج نہیں کر سکتے"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"اپنے آلہ کے ساتھ ملنے والے چارجر کا استعمال کریں"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"چہرے کی تصدیق ہو گئی"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تصدیق شدہ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"مکمل کرنے کیلئے \'تصدیق کریں\' تھپتھپائیں"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"بند کریں"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"مکمل خاموشی"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"صرف الارمز"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ڈسٹرب نہ کریں۔"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"بلوٹوتھ۔"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"بلوٹوتھ آن ہے۔"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"الارم <xliff:g id="TIME">%s</xliff:g> کیلئے سیٹ ہے۔"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"ڈیزرٹ کیس"</string>
     <string name="start_dreams" msgid="9131802557946276718">"اسکرین سیور"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ایتھرنیٹ"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"ڈسٹرب نہ کریں"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"بلوٹوتھ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"کوئی جوڑا بنائے ہوئے آلات دستیاب نہیں ہیں"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> بیٹری"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"اطلاعات"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"گفتگوئیں"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"سبھی خاموش اطلاعات کو صاف کریں"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ڈسٹرب نہ کریں\' کے ذریعے اطلاعات کو موقوف کیا گیا"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"‏&lt;b&gt;اسٹیٹس:&lt;/b&gt; کو کم درجہ دیا گیا"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"یہ گفتگو کی اطلاعات کے اوپری حصّے پر اور مقفل اسکرین پر پروفائل کی تصویر کے بطور دکھائی دیتا ہے"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"یہ گفتگو کی اطلاعات کے اوپری حصّے پر اور مقفل اسکرین پر پروفائل کی تصویر کے بطور دکھائی دیتا ہے، بلبلے کے بطور ظاہر ہوتا ہے"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"یہ گفتگو کی اطلاعات کے اوپری حصّے پر اور مقفل اسکرین پر پروفائل کی تصویر کے بطور دکھائی دیتا ہے، \'ڈسٹرب نہ کریں\' میں مداخلت کرتا ہے"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"یہ گفتگو کی اطلاعات کے اوپری حصّے پر اور مقفل اسکرین پر پروفائل کی تصویر کے بطور دکھائی دیتا ہے، بلبلے کے بطور ظاہر ہوتا ہے، \'ڈسٹرب نہ کریں\' میں مداخلت کرتا ہے"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"موسیقی"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"کیلنڈر"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ڈسٹرب نہ کریں"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"والیوم بٹنز کے شارٹ کٹ"</string>
     <string name="battery" msgid="769686279459897127">"بیٹری"</string>
     <string name="headset" msgid="4485892374984466437">"ہیڈ سیٹ"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>، <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"‏Wi-Fi آف ہے"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"بلوٹوتھ آف ہے"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"\'ڈسٹرب نہ کریں\' آف ہے"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"\'ڈسٹرب نہ کریں\' کسی خودکار اصول (<xliff:g id="ID_1">%s</xliff:g>) کے ذریعہ آن ہو گیا تھا۔"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"\'ڈسٹرب نہ کریں\' کسی ایپ (<xliff:g id="ID_1">%s</xliff:g>) کے ذریعہ آن ہو گیا تھا۔"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"\'ڈسٹرب نہ کریں\' کسی خودکار اصول یا ایپ کے ذریعے آن ہو گیا تھا۔"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"ایپس پس منظر میں چل رہی ہیں"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"بیٹری اور ڈیٹا استعمال کے بارے میں تفصیلات کے لیے تھپتھپائیں"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"موبائل ڈیٹا آف کریں؟"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(دفتر)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"فون کال"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> کے ذریعے)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"کیمرا"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"مقام"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"مائیکروفون"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(غیر منسلک ہے)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"سوئچ نہیں کر سکتے۔ دوبارہ کوشش کرنے کے لیے تھپتھپائیں۔"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"نئے آلہ کا جوڑا بنائیں"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"اس سیشن کو کاسٹ کرنے کیلئے، براہ کرم ایپ کھولیں۔"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"نامعلوم ایپ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"بلڈ نمبر"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"بلڈ نمبر کلپ بورڈ میں کاپی ہو گیا۔"</string>
     <string name="basic_status" msgid="2315371112182658176">"گفتگو کھولیں"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+<xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"حالیہ پیغامات، چھوٹی ہوئی کالز اور اسٹیٹس اپ ڈیٹس دیکھیں"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"گفتگو"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"\'ڈسٹرب نہ کریں\' کے ذریعے موقوف کیا گیا"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> نے ایک پیغام بھیجا: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> نے ایک تصویر بھیجی"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> نے اسٹیٹس کو اپ ڈیٹ کر دیا ہے: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"نئی معلومات"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"فعال ایپس"</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>
@@ -889,8 +910,13 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"کاپی کردہ ٹیکسٹ میں ترمیم کریں"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"کاپی کردہ تصویر میں ترمیم کریں"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"قریبی آلے کو بھیجیں"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="add" msgid="81036585205287996">"شامل کریں"</string>
+    <string name="manage_users" msgid="1823875311934643849">"صارفین کا نظم کریں"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"یہ اطلاع اسپلٹ اسکرین کو گھسیٹنے کو سپورٹ نہیں کرتا ہے۔"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"‏Wi-Fi دستیاب نہیں ہے"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ترجیحی وضع"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"الارم سیٹ ہوگیا"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"اسسٹنٹ مہمان وضع فعال ہے"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"کیمرا اور مائیک آف ہیں"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اطلاع}other{# اطلاعات}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 6d6c371..0cead71 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -20,7 +20,12 @@
 <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">"Tizim interfeysi"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Batareya tez orada tugaydi"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> qoldi"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"USB orqali quvvatlash imkonsiz"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Qurilmangiz bilan kelgan quvvatlash moslamasidan foydalaning"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Yuzingiz aniqlandi"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Tasdiqlangan"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tasdiqlash uchun tegining"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Yopish"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"jimjitlik"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"faqat signallar"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Bezovta qilinmasin."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth yoqilgan."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Signal <xliff:g id="TIME">%s</xliff:g> da chalinadi."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Ekran lavhasi"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Bezovta qilinmasin"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Ulangan qurilmalar topilmadi"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirishnomalar"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Suhbatlar"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Barcha sokin bildirishnomalarni tozalash"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bezovta qilinmasin rejimida bildirishnomalar pauza qilinadi"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Boshlash"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Bildirishnomalar yo‘q"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu qurilmani ota-onangiz boshqaradi"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Holati:&lt;/b&gt; Quyi darajaga tushirildi"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Suhbat bildirishnomalari tepasida va ekran qulfida profil rasmi sifatida chiqariladi"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Suhbat bildirishnomalari tepasida va ekran qulfida profil rasmi sifatida chiqariladi, bulutcha sifatida chiqadi"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Suhbat bildirishnomalari tepasida va ekran qulfida profil rasmi sifatida chiqariladi, Bezovta qilinmasin rejimini bekor qiladi"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Suhbat bildirishnomalari tepasida va ekran qulfida profil rasmi sifatida chiqariladi, bulutcha sifatida chiqadi, Bezovta qilinmasin rejimini bekor qiladi"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiqa"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Taqvim"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Bezovta qilinmasin"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Ovoz balandligini boshqarish tugmalari"</string>
     <string name="battery" msgid="769686279459897127">"Batareya"</string>
     <string name="headset" msgid="4485892374984466437">"Audio moslama"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi o‘chiq"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth o‘chiq"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Bezovta qilinmasin rejimi o‘chiq"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Bezovta qilinmasin rejimi avtomatik qoida (<xliff:g id="ID_1">%s</xliff:g>) tomonidan yoqilgan."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Bezovta qilinmasin rejimi ilova (<xliff:g id="ID_1">%s</xliff:g>) tomonidan yoqilgan."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Bezovta qilinmasin rejimi ilova yoki avtomatik qoida tomonidan yoqilgan."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Fonda ishlayotgan ilovalar"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Batareya va trafik sarfi tafsilotlari uchun ustiga bosing"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Mobil internet uzilsinmi?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(ish)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefon chaqiruvi"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> orqali)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"joylashuv"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
@@ -806,6 +825,8 @@
     <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_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="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string>
     <string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Oxirgi xabarlar, javobsiz chaqiruvlar va holat yangilanishlari"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Suhbat"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Bezovta qilinmasin rejimi pauza qildi"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> xabar yubordi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> rasm yubordi"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ahvolini yangiladi: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ta faol ilova</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ta faol ilova</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Yangi axborot"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Faol ilovalar"</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">"Toʻxtatildi"</string>
@@ -886,14 +907,16 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Nusxa olindi"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Manba: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"UI nusxasini bekor qilish"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
-    <skip />
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Nusxa olingan matnni tahrirlash"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Nusxa olingan rasmni tahrirlash"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Yaqin-atrofdagi qurilmaga yuborish"</string>
+    <string name="add" msgid="81036585205287996">"Kiritish"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Foydalanuvchilarni boshqarish"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildirishnoma ikkiga ajratilgan ekranda ishlamaydi."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ishlamayapti"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Imtiyozli rejim"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signal oʻrnatildi"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Assistentli mehmon rejimi yoqildi"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera va mikrofon yoqilmagan"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ta bildirishnoma}other{# ta bildirishnoma}}"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 5d69e03..a5609eb8 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -20,7 +20,12 @@
 <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">"Giao diện người dùng hệ thống"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Có thể sắp hết pin"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"Còn lại <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Không thể sạc qua USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Sử dụng bộ sạc đi kèm với thiết bị"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Đã xác thực khuôn mặt"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Đóng"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"hoàn toàn tắt tiếng"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"chỉ chuông báo"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Không làm phiền."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"Bluetooth bật."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"Báo thức được đặt cho <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Tủ trưng bày bánh ngọt"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Trình bảo vệ m.hình"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Không làm phiền"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Không có thiết bị nào được ghép nối"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> pin"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Thông báo"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Cuộc trò chuyện"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Xóa tất cả thông báo im lặng"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Chế độ Không làm phiền đã tạm dừng thông báo"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Bắt đầu ngay"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Không có thông báo nào"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Thiết bị này do cha mẹ của bạn quản lý"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Trạng thái:&lt;/b&gt; Đã giảm mức độ quan trọng"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Hiện ở đầu phần thông báo cuộc trò chuyện và ở dạng ảnh hồ sơ trên màn hình khóa"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Hiện ở đầu phần thông báo cuộc trò chuyện và ở dạng ảnh hồ sơ trên màn hình khóa, xuất hiện ở dạng bong bóng"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Hiện ở đầu phần thông báo cuộc trò chuyện và ở dạng ảnh hồ sơ trên màn hình khóa, làm gián đoạn chế độ Không làm phiền"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Hiện ở đầu phần thông báo cuộc trò chuyện và ở dạng ảnh hồ sơ trên màn hình khóa, xuất hiện ở dạng bong bóng, làm gián đoạn chế độ Không làm phiền"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Âm nhạc"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Lịch"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Không làm phiền"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Phím tắt các nút âm lượng"</string>
     <string name="battery" msgid="769686279459897127">"Pin"</string>
     <string name="headset" msgid="4485892374984466437">"Tai nghe"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi tắt"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth tắt"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Không làm phiền tắt"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Không làm phiền đã được một quy tắc tự động (<xliff:g id="ID_1">%s</xliff:g>) bật."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Không làm phiền đã được một ứng dụng (<xliff:g id="ID_1">%s</xliff:g>) bật."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Không làm phiền đã được một quy tắc tự động hoặc ứng dụng bật."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Ứng dụng đang chạy trong nền"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Nhấn để biết chi tiết về mức sử dụng dữ liệu và pin"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Tắt dữ liệu di động?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(công việc)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Cuộc gọi điện thoại"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(thông qua <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"máy ảnh"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"vị trí"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"micrô"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(đã ngắt kết nối)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Không thể chuyển đổi. Hãy nhấn để thử lại."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Ghép nối thiết bị mới"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Vui lòng mở ứng dụng để truyền phiên này."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ứng dụng không xác định"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Số bản dựng"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Đã sao chép số bản dựng vào bảng nhớ tạm."</string>
     <string name="basic_status" msgid="2315371112182658176">"Mở cuộc trò chuyện"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Hơn <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Xem các tin nhắn, cuộc gọi nhỡ và thông tin cập nhật trạng thái gần đây"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Cuộc trò chuyện"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Đã tạm dừng do chế độ Không làm phiền"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> đã gửi một tin nhắn: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> đã gửi một hình ảnh"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> đã cập nhật trạng thái: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ứng dụng đang hoạt động</item>
       <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ứng dụng đang hoạt động</item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <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>
     <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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Đã sao chép"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"Từ <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"Đóng giao diện người dùng sao chép"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"Chỉnh sửa văn bản đã sao chép"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Chỉnh sửa hình ảnh đã sao chép"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Gửi đến thiết bị ở gần"</string>
+    <string name="add" msgid="81036585205287996">"Thêm"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Quản lý người dùng"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Thông báo này không hỗ trợ thao tác kéo để Chia đôi màn hình."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Không có Wi‑Fi"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Chế độ ưu tiên"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Đã đặt chuông báo"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Đã bật chế độ khách cho Trợ lý"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Máy ảnh và micrô đang tắt"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index f032907..0610b59 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"电池电量可能很快就要耗尽"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"剩余<xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"无法通过 USB 充电"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"使用设备随附的充电器"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"面孔身份验证成功"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"已确认"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"点按“确认”即可完成"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"关闭"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"完全静音"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"仅限闹钟"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"勿扰。"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"蓝牙。"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"蓝牙开启。"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"闹钟已设置为:<xliff:g id="TIME">%s</xliff:g>。"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"甜品盒"</string>
     <string name="start_dreams" msgid="9131802557946276718">"屏保"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"有线网络"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"勿扰"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"蓝牙"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"没有可用的配对设备"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> 的电量"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"对话"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有无声通知"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"勿扰模式暂停的通知"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;状态&lt;/b&gt;:已调低顺序"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"显示在对话通知顶部(屏幕锁定时显示为个人资料照片)"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"以气泡形式显示在对话通知顶部(屏幕锁定时显示为个人资料照片)"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"显示在对话通知顶部(屏幕锁定时显示为个人资料照片),并且会中断勿扰模式"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以气泡形式显示在对话通知顶部(屏幕锁定时显示为个人资料照片),并且会中断勿扰模式"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"短信"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音乐"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日历"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"勿扰"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"音量按钮快捷键"</string>
     <string name="battery" msgid="769686279459897127">"电池"</string>
     <string name="headset" msgid="4485892374984466437">"耳机"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>,<xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"WLAN 已关闭"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"蓝牙已关闭"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"“勿扰”模式已关闭"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"某个自动规则(<xliff:g id="ID_1">%s</xliff:g>)已开启勿扰模式。"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"某个应用(<xliff:g id="ID_1">%s</xliff:g>)已开启勿扰模式。"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某个自动规则或应用已开启勿扰模式。"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"在后台运行的应用"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"点按即可详细了解电量和流量消耗情况"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"要关闭移动数据网络吗?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(工作)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"电话"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(通过“<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>”)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"相机"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"位置信息"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"麦克风"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(已断开连接)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"无法切换。点按即可重试。"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"与新设备配对"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如需投射此会话,请打开相关应用。"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"未知应用"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本号"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"已将版本号复制到剪贴板。"</string>
     <string name="basic_status" msgid="2315371112182658176">"开放式对话"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"查看近期的消息、未接电话和状态更新"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"对话"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"勿扰模式已暂停通知"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>发送了一条消息:<xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>发送了一张图片"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>更新了状态:<xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"新信息"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的应用"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"已复制"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"来自<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"关闭复制界面"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"修改所复制的文字"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"编辑所复制的图片"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"发送到附近的设备"</string>
+    <string name="add" msgid="81036585205287996">"添加"</string>
+    <string name="manage_users" msgid="1823875311934643849">"管理用户"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"此通知不支持拖动到分屏中。"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WLAN 已关闭"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"优先模式"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"闹钟已设置"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Google 助理访客模式已启用"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"摄像头和麦克风已关闭"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index dbb4ffc..8600859 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -20,7 +20,12 @@
 <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="battery_low_title" msgid="6891106956328275225">"電池電量可能即將耗盡"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"剩餘 <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"無法透過 USB 充電"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"使用裝置隨附的充電器"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"臉孔已經驗證"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"已確認"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"輕按 [確定] 以完成"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"關閉"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"完全靜音"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"只限鬧鐘"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"請勿騷擾。"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"藍牙。"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"藍牙已開啟。"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"鬧鐘已設定為:<xliff:g id="TIME">%s</xliff:g>。"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"螢幕保護程式"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"以太網"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"請勿騷擾"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"藍牙"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"找不到配對的裝置"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"對話"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有靜音通知"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"「請勿騷擾」模式已將通知暫停"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;狀態:&lt;/b&gt;已調低次序"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"顯示在對話通知頂部 (在上鎖畫面會顯示為個人檔案相片)"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"以對話氣泡形式顯示在對話通知頂部 (在上鎖畫面會顯示為個人檔案相片)"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"顯示在對話通知頂部 (在上鎖畫面會顯示為個人檔案相片),並會中斷「請勿打擾」模式"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以對話氣泡形式顯示在對話通知頂部 (在上鎖畫面會顯示為個人檔案相片),並會中斷「請勿打擾」模式"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"短訊"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音樂"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日曆"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"請勿騷擾"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"音量按鈕快速鍵"</string>
     <string name="battery" msgid="769686279459897127">"電池"</string>
     <string name="headset" msgid="4485892374984466437">"耳機"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>,<xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi 已關閉"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"藍牙已關閉"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"「請勿騷擾」已關閉"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"「<xliff:g id="ID_1">%s</xliff:g>」自動規則已開啟「請勿騷擾」功能。"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"「<xliff:g id="ID_1">%s</xliff:g>」應用程式已開啟「請勿騷擾」功能。"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某個自動規則或應用程式已開啟「請勿騷擾」功能。"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"正在背景中執行的應用程式"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"輕按即可查看電池和數據用量詳情"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"要關閉流動數據嗎?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(公司)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"電話"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(透過「<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>」)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"相機"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"位置"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"麥克風"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(已中斷連線)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"無法切換,輕按即可重試。"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放此工作階段,請開啟應用程式。"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明應用程式"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"版本號碼已複製到剪貼簿。"</string>
     <string name="basic_status" msgid="2315371112182658176">"開啟對話"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"查看最近的訊息、未接來電和狀態更新"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"對話"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"「請勿騷擾」已暫停通知"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>傳送了訊息:<xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>傳送了圖片"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>有狀態更新:<xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"新資料"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的應用程式"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"已複製"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"來自「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"關閉剪貼簿使用者介面"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"編輯已複製的文字"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"編輯已複製的圖片"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"傳送至附近的裝置"</string>
+    <string name="add" msgid="81036585205287996">"新增"</string>
+    <string name="manage_users" msgid="1823875311934643849">"管理使用者"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"此通知無法拖曳到分割螢幕中。"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi 已關閉"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先模式"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"已設定鬧鐘"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"已啟用「Google 助理」訪客模式"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"相機和麥克風已關閉"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index d7185a4..0206a9e 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -20,7 +20,12 @@
 <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">"系統 UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"電池電力可能很快就會耗盡"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"僅剩 <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"無法透過 USB 充電"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"使用裝置隨附的充電器"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"臉孔驗證成功"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"確認完畢"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"輕觸 [確認] 完成驗證設定"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"關閉"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"完全靜音"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"僅限鬧鐘"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"零打擾。"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"藍牙。"</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"藍牙已開啟。"</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"鬧鐘已設定為:<xliff:g id="TIME">%s</xliff:g>。"</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
     <string name="start_dreams" msgid="9131802557946276718">"螢幕保護程式"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"乙太網路"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"零打擾"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"藍牙"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"找不到配對的裝置"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"對話"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有靜音通知"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"「零打擾」模式已將通知設為暫停"</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>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;狀態:&lt;/b&gt;已調降順序"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"顯示在對話通知頂端 (螢幕鎖定時會顯示為個人資料相片)"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"以對話框的形式顯示在對話通知頂端 (螢幕鎖定時會顯示為個人資料相片)"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"顯示在對話通知頂端 (螢幕鎖定時會顯示為個人資料相片),並會中斷「零打擾」模式"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以對話框的形式顯示在對話通知頂端 (螢幕鎖定時會顯示為個人資料相片),並會中斷「零打擾」模式"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"簡訊"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音樂"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日曆"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"零打擾"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"音量按鈕快速鍵"</string>
     <string name="battery" msgid="769686279459897127">"電池"</string>
     <string name="headset" msgid="4485892374984466437">"耳機"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>,<xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi 已關閉"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"藍牙已關閉"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"零打擾模式已關閉"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"「<xliff:g id="ID_1">%s</xliff:g>」自動規則已將零打擾模式開啟。"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"「<xliff:g id="ID_1">%s</xliff:g>」應用程式已將零打擾模式開啟。"</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"某個自動規則或應用程式已將零打擾模式開啟。"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"在背景執行的應用程式"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"輕觸即可查看電池和數據用量詳情"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"要關閉行動數據嗎?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(工作)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"電話"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(透過「<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>」)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"相機"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"位置"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"麥克風"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(連線中斷)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"無法切換,輕觸即可重試。"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放這個工作階段,請開啟應用程式。"</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明的應用程式"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"已將版本號碼複製到剪貼簿。"</string>
     <string name="basic_status" msgid="2315371112182658176">"開放式對話"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"查看最近的訊息、未接來電和狀態更新"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"對話"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"零打擾模式已將通知暫停"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>傳送了一則訊息:<xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>傳送了一張圖片"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>更新了狀態:<xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <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>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"新資訊"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的應用程式"</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>
@@ -886,14 +907,17 @@
     <string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"已複製"</string>
     <string name="clipboard_edit_source" msgid="9156488177277788029">"來自「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
     <string name="clipboard_dismiss_description" msgid="7544573092766945657">"關閉剪貼簿 UI"</string>
-    <!-- no translation found for clipboard_edit_text_description (805254383912962103) -->
-    <skip />
-    <!-- no translation found for clipboard_edit_image_description (8904857948976041306) -->
-    <skip />
-    <!-- no translation found for clipboard_send_nearby_description (4629769637846717650) -->
-    <skip />
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="clipboard_edit_text_description" msgid="805254383912962103">"編輯複製的文字"</string>
+    <string name="clipboard_edit_image_description" msgid="8904857948976041306">"編輯複製的圖片"</string>
+    <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"傳送到鄰近裝置"</string>
+    <string name="add" msgid="81036585205287996">"新增"</string>
+    <string name="manage_users" msgid="1823875311934643849">"管理使用者"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"這項通知無法拖曳到分割畫面中。"</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi 已關閉"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先模式"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"鬧鐘設定成功"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"已啟用 Google 助理訪客模式"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"已關閉相機和麥克風"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 5425b26..98e7fc4 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -20,7 +20,12 @@
 <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">"Uhlelo lwe-UI"</string>
-    <string name="battery_low_title" msgid="6891106956328275225">"Ibhethri lingaphela maduze"</string>
+    <!-- no translation found for battery_low_title (5319680173344341779) -->
+    <skip />
+    <!-- no translation found for battery_low_description (3282977755476423966) -->
+    <skip />
+    <!-- no translation found for battery_low_intro (5148725009653088790) -->
+    <skip />
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> okusele"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"Ayikwazi ukushaja nge-USB"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"Sebenzisa ishaja eze nedivayisi yakho"</string>
@@ -128,6 +133,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ubuso bufakazelwe ubuqiniso"</string>
     <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>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (1597899891472340950) -->
+    <skip />
     <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>
@@ -181,6 +188,7 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Vala"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ukuthula okuphelele"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ama-alamu kuphela"</string>
+    <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"Ungaphazamisi"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"I-Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"I-Bluetooth ivuliwe."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"I-alamu isethiwe ngo-<xliff:g id="TIME">%s</xliff:g>."</string>
@@ -205,6 +213,7 @@
     <string name="dessert_case" msgid="9104973640704357717">"Isikhwama soswidi"</string>
     <string name="start_dreams" msgid="9131802557946276718">"Isigcini sihenqo"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"I-Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ungaphazamisi"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"I-Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Awekho amadivayisi abhanqiwe atholakalayo"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ibhethri"</string>
@@ -348,6 +357,7 @@
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Izaziso"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Izingxoxo"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Sula zonke izaziso ezithulile"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Izaziso zimiswe okwesikhashana ukungaphazamisi"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Qala manje"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Azikho izaziso"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Le divayisi iphethwe ngumzali wakho"</string>
@@ -491,6 +501,8 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Isimo:&lt;/b&gt; Silinganiselwe phansi"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Ivela phezu kwezaziso zengxoxo nanjengesithombe sephrofayela esikrinini sokukhiya"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Ivela phezu kwezaziso zengxoxo futhi njengesithombe sephrofayela esikrinini sokukhiya, ivela njengebhamuza"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Ivela phezu kwezaziso zengxoxo futhi njengesithombe sephrofayela esikrinini sokukhiya, ukuphazamisa okuthi Ungaphazamisi"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ivela phezu kwezaziso zengxoxo futhi njengesithombe sephrofayela esikrinini sokukhiya, ivela njengebhamuza, ukuphazamisa okuthi Ungaphazamisi"</string>
     <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>
@@ -566,6 +578,7 @@
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"I-SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Umculo"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Ikhalenda"</string>
+    <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ungaphazamisi"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Izinqamuleli zezinkinobho zevolomu"</string>
     <string name="battery" msgid="769686279459897127">"Ibhethri"</string>
     <string name="headset" msgid="4485892374984466437">"Ama-earphone"</string>
@@ -684,6 +697,10 @@
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"I-<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"I-Wi-Fi ivaliwe"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"I-Bluetooth ivaliwe"</string>
+    <string name="dnd_is_off" msgid="3185706903793094463">"Ungaphazamisi kuvaliwe"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Okuthi ungaphazamisi kuvulwe umthetho ozenzakalelayo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Okuthi ungaphazamisi kuvulwe uhlelo lokusebenza (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Okuthi ungaphazamisi kuvulwe umthetho ozenzakalelayo noma uhlelo lokusebenza."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Izinhlelo zokusebenza zisebenza ngasemuva"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Thepha ngemininingwane ekusetshenzisweni kwebhethri nedatha"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Vala idatha yeselula?"</string>
@@ -708,6 +725,8 @@
     <string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(umsebenzi)"</string>
     <string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Ikholi yefoni"</string>
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(kuya ku-<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
+    <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"ikhamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"indawo"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"imakrofoni"</string>
@@ -806,6 +825,8 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(inqamukile)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Akukwazi ukushintsha. Thepha ukuze uzame futhi."</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bhangqa idivayisi entsha"</string>
+    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ukuze usakaze le seshini, sicela uvule i-app."</string>
+    <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"I-app engaziwa"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Yakha inombolo"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Yakha inombolo ekopishelwe kubhodi yokunamathisela."</string>
     <string name="basic_status" msgid="2315371112182658176">"Vula ingxoxo"</string>
@@ -839,6 +860,7 @@
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Bona imiyalezo yakamuva, amakholi akuphuthile, nezibuyekezo zesimo"</string>
     <string name="people_tile_title" msgid="6589377493334871272">"Ingxoxo"</string>
+    <string name="paused_by_dnd" msgid="7856941866433556428">"Kumiswe okuthi Ungaphazamisi"</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"U-<xliff:g id="NAME">%1$s</xliff:g> uthumele umlayezo: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"U-<xliff:g id="NAME">%1$s</xliff:g> uthumele isithombe"</string>
     <string name="new_status_content_description" msgid="6046637888641308327">"U-<xliff:g id="NAME">%1$s</xliff:g> unesibuyekezo sesimo: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
@@ -877,8 +899,7 @@
       <item quantity="one">ama-app asebenzayo angu-<xliff:g id="COUNT_1">%s</xliff:g></item>
       <item quantity="other">ama-app asebenzayo angu-<xliff:g id="COUNT_1">%s</xliff:g></item>
     </plurals>
-    <!-- no translation found for fgs_dot_content_description (2865071539464777240) -->
-    <skip />
+    <string name="fgs_dot_content_description" msgid="2865071539464777240">"Ulwazi olusha"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ama-app asebenzayo"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Misa"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Imisiwe"</string>
@@ -889,8 +910,14 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"Hlela umbhalo okopishiwe"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Hlela umfanekiso okopishiwe"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Thumela kudivayisi eseduze"</string>
-    <!-- no translation found for add (81036585205287996) -->
-    <skip />
-    <!-- no translation found for manage_users (1823875311934643849) -->
+    <string name="add" msgid="81036585205287996">"Faka"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Phatha abasebenzisi"</string>
+    <string name="drag_split_not_supported" msgid="4326847447699729722">"Lesi saziso asikusekeli ukuhudulela ku-Splitscreen."</string>
+    <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"I-Wi-Fi ayitholakali"</string>
+    <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Imodi ebalulekile"</string>
+    <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"I-alamu isethiwe"</string>
+    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled" msgid="3715897096012469615">"Imodi yesivakashi somsizi inikwe amandla"</string>
+    <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Ikhamera nemakrofoni kuvaliwe"</string>
+    <!-- no translation found for dream_overlay_status_bar_notification_indicator (8091389255691081711) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index dc74700..1edaaad 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -52,7 +52,7 @@
          (e.g. cannot be switched to) -->
     <color name="kg_user_switcher_restricted_avatar_icon_color">@color/GM2_grey_600</color>
     <!-- Color of background circle of user avatars in keyguard user switcher -->
-    <color name="kg_user_switcher_avatar_background">?android:attr/colorBackgroundFloating</color>
+    <color name="user_avatar_color_bg">?android:attr/colorBackgroundFloating</color>
 
     <!-- Icon color for user avatars in user switcher quick settings -->
     <color name="qs_user_switcher_avatar_icon_color">#3C4043</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 5a7efca..ffae601 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -139,7 +139,7 @@
     <!-- Height of a heads up notification in the status bar -->
     <dimen name="notification_max_heads_up_height_increased">188dp</dimen>
 
-    <!-- Side padding on the lockscreen on the side of notifications -->
+    <!-- Side padding on the side of notifications -->
     <dimen name="notification_side_paddings">16dp</dimen>
 
     <!-- padding between the heads up and the statusbar -->
@@ -979,6 +979,11 @@
     <dimen name="qs_media_session_disabled_seekbar_vertical_padding">16dp</dimen>
     <dimen name="qs_media_session_height_expanded">184dp</dimen>
     <dimen name="qs_media_session_height_collapsed">128dp</dimen>
+    <dimen name="qs_media_seekbar_progress_wavelength">20dp</dimen>
+    <dimen name="qs_media_seekbar_progress_amplitude">1.5dp</dimen>
+    <dimen name="qs_media_seekbar_progress_phase">8dp</dimen>
+    <dimen name="qs_media_seekbar_progress_stroke_width">2dp</dimen>
+    <dimen name="qs_media_session_collapsed_guideline">144dp</dimen>
 
     <!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
     <dimen name="qs_aa_media_rec_album_size_collapsed">72dp</dimen>
@@ -1122,13 +1127,40 @@
     <dimen name="media_output_dialog_title_anim_y_delta">12.5dp</dimen>
     <dimen name="media_output_dialog_app_tier_icon_size">20dp</dimen>
 
-    <!-- Distance that the full shade transition takes in order for qs to fully transition to the
-         shade -->
-    <dimen name="lockscreen_shade_qs_transition_distance">200dp</dimen>
+    <!-- Distance that the full shade transition takes in order to complete by tapping on a button
+         like "expand". -->
+    <dimen name="lockscreen_shade_transition_by_tap_distance">200dp</dimen>
+
+    <!-- Distance that the full shade transition takes in order to complete.  -->
+    <dimen name="lockscreen_shade_full_transition_distance">80dp</dimen>
 
     <!-- Distance that the full shade transition takes in order for scrim to fully transition to
          the shade (in alpha) -->
-    <dimen name="lockscreen_shade_scrim_transition_distance">80dp</dimen>
+    <dimen name="lockscreen_shade_scrim_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+    <!-- Distance that the full shade transition takes in order for the keyguard content on
+         NotificationPanelViewController to fully fade (e.g. Clock & Smartspace) -->
+    <dimen name="lockscreen_shade_npvc_keyguard_content_alpha_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+    <!-- Distance that the full shade transition takes in order for the notification shelf to fully
+         expand. -->
+    <dimen name="lockscreen_shade_notif_shelf_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+    <!-- Distance that the full shade transition takes in order for the Quick Settings to fully
+         fade and expand. -->
+    <dimen name="lockscreen_shade_qs_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+    <!-- Distance that the full shade transition takes in order for depth of the wallpaper to fully
+         change.  -->
+    <dimen name="lockscreen_shade_depth_controller_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+    <!-- Distance that the full shade transition takes in order for the UDFPS Keyguard View to fully
+         fade. -->
+    <dimen name="lockscreen_shade_udfps_keyguard_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+
+    <!-- Used for StatusBar to know that a transition is in progress. At the moment it only checks
+         whether the progress is > 0, therefore this value is not very important. -->
+    <dimen name="lockscreen_shade_status_bar_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
 
     <!-- Distance that the full shade transition takes in order for media to fully transition to
          the shade -->
@@ -1335,9 +1367,6 @@
     <dimen name="dream_overlay_status_icon_margin">8dp</dimen>
     <dimen name="dream_overlay_status_bar_icon_size">
         @*android:dimen/status_bar_system_icon_size</dimen>
-    <!-- Height of the area at the top of the dream overlay to allow dragging down the notifications
-         shade. -->
-    <dimen name="dream_overlay_notifications_drag_area_height">100dp</dimen>
     <dimen name="dream_overlay_camera_mic_off_indicator_size">8dp</dimen>
     <dimen name="dream_overlay_notification_indicator_size">6dp</dimen>
 
@@ -1347,6 +1376,7 @@
     <dimen name="dream_overlay_complication_weather_text_size">18sp</dimen>
     <dimen name="dream_overlay_complication_preview_text_size">36sp</dimen>
     <dimen name="dream_overlay_complication_preview_icon_padding">28dp</dimen>
+    <dimen name="dream_overlay_complication_shadow_padding">2dp</dimen>
 
     <!-- The position of the end guide, which dream overlay complications can align their start with
          if their end is aligned with the parent end. Represented as the percentage over from the
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 9e1f57b..d230f33 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -66,7 +66,10 @@
     <string name="battery_saver_confirmation_ok">Turn on</string>
 
     <!-- Battery saver notification action [CHAR LIMIT=NONE]-->
-    <string name="battery_saver_start_action">Turn on Battery Saver</string>
+    <string name="battery_saver_start_action">Turn on</string>
+
+    <!-- Battery saver notification dismiss action: Do not turn on battery saver. [CHAR LIMIT=NONE]-->
+    <string name="battery_saver_dismiss_action">No thanks</string>
 
     <!-- Name of the button that links to the Settings app. [CHAR LIMIT=NONE] -->
 
@@ -1190,10 +1193,7 @@
     <string name="wallet_lockscreen_settings_label">Lock screen settings</string>
 
     <!-- QR Code Scanner label, title [CHAR LIMIT=32] -->
-    <string name="qr_code_scanner_title">QR code</string>
-
-    <!-- QR Code Scanner description [CHAR LIMIT=NONE] -->
-    <string name="qr_code_scanner_description">Tap to scan</string>
+    <string name="qr_code_scanner_title">Scan QR code</string>
 
     <!-- Name of the work status bar icon. -->
     <string name="status_bar_work">Work profile</string>
@@ -2223,6 +2223,8 @@
     <string name="media_output_dialog_launch_app_text">To cast this session, please open the app.</string>
     <!-- App name when can't get app name [CHAR LIMIT=60] -->
     <string name="media_output_dialog_unknown_launch_app_name">Unknown app</string>
+    <!-- Button text for stopping casting [CHAR LIMIT=60] -->
+    <string name="media_output_dialog_button_stop_casting">Stop casting</string>
 
 
     <!-- Label for clip data when copying the build number off QS [CHAR LIMIT=NONE]-->
@@ -2425,8 +2427,6 @@
     <string name="dream_overlay_status_bar_priority_mode">Priority mode</string>
     <!-- Content description for the alarm set icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
     <string name="dream_overlay_status_bar_alarm_set">Alarm set</string>
-    <!-- Content description for the assistant guest mode enabled icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
-    <string name="dream_overlay_status_bar_assistant_guest_mode_enabled">Assistant guest mode enabled</string>
     <!-- Content description for the camera and mic off icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
     <string name="dream_overlay_status_bar_camera_mic_off">Camera and mic are off</string>
     <!-- Content description for the notifications indicator icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index f2eaa75..3ae21e0 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -590,6 +590,7 @@
 
     <style name="MediaPlayer.ProgressBar" parent="@android:style/Widget.ProgressBar.Horizontal">
         <item name="android:thumbTint">?android:attr/textColorPrimary</item>
+        <item name="android:progressDrawable">@drawable/media_squiggly_progress</item>
         <item name="android:progressTint">?android:attr/textColorPrimary</item>
         <item name="android:progressBackgroundTint">?android:attr/textColorTertiary</item>
         <item name="android:clickable">true</item>
diff --git a/packages/SystemUI/res/xml/media_session_collapsed.xml b/packages/SystemUI/res/xml/media_session_collapsed.xml
index c6e18a6..f00e031 100644
--- a/packages/SystemUI/res/xml/media_session_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_session_collapsed.xml
@@ -19,6 +19,13 @@
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
     <Constraint
+        android:id="@+id/media_action_barrier"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layout_constraintTop_toBottomOf="@id/media_seamless"
+        app:layout_constraintStart_toEndOf="@id/action_button_guideline" />
+
+    <Constraint
         android:id="@+id/album_art"
         android:layout_width="match_parent"
         android:layout_height="@dimen/qs_media_session_height_collapsed"
@@ -28,33 +35,73 @@
         app:layout_constraintBottom_toBottomOf="parent" />
 
     <Constraint
+        android:id="@+id/header_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dp"
+        android:layout_marginStart="@dimen/qs_media_padding"
+        android:layout_marginEnd="@dimen/qs_media_padding"
+        app:layout_constraintEnd_toStartOf="@id/action_button_guideline"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintTop_toBottomOf="@id/icon"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintHorizontal_bias="0" />
+    <Constraint
+        android:id="@+id/header_artist"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/qs_media_padding"
+        android:layout_marginTop="0dp"
+        app:layout_constraintEnd_toStartOf="@id/action_button_guideline"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintTop_toBottomOf="@id/header_title"
+        app:layout_constraintStart_toStartOf="@id/header_title"
+        app:layout_constraintVertical_bias="0"
+        app:layout_constraintHorizontal_bias="0" />
+
+    <Constraint
         android:id="@+id/actionPlayPause"
         android:layout_width="48dp"
         android:layout_height="48dp"
         android:layout_marginEnd="@dimen/qs_media_padding"
-        app:layout_constraintStart_toEndOf="@id/actionEnd"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        app:layout_constraintVertical_bias="1"
         app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintTop_toBottomOf="@id/media_seamless"
-        app:layout_constraintBottom_toBottomOf="parent" />
+        app:layout_constraintStart_toEndOf="@id/media_action_barrier_end" />
 
+    <!--
+    There will only be 3 action buttons shown at most in this layout (controlled in code).
+    Play/Pause should always be at the end, but the other buttons should remain in the same order
+    when in RTL.
+    This is accomplished by setting two barriers at the start and end of the small buttons,
+    anchored to a guideline set at 3x button width from the end. The text and play/pause button are
+    positioned relative to the barriers, and the small buttons use right/left constraints to stay
+    in the correct order inside the barriers.
+    -->
     <Constraint
         android:id="@+id/actionPrev"
         android:layout_width="48dp"
         android:layout_height="48dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
         app:layout_constraintHorizontal_bias="1"
+        app:layout_constraintVertical_bias="1"
         app:layout_constraintHorizontal_chainStyle="packed"
-        app:layout_constraintStart_toEndOf="@id/header_artist"
-        app:layout_constraintEnd_toStartOf="@id/media_progress_bar"
+        app:layout_constraintRight_toLeftOf="@id/media_progress_bar"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/media_seamless" />
+        app:layout_constraintTop_toBottomOf="@id/media_seamless"
+        app:layout_constraintLeft_toRightOf="@id/media_action_barrier" />
 
     <Constraint
         android:id="@+id/media_progress_bar"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/qs_media_padding"
         android:visibility="gone"
-        app:layout_constraintStart_toEndOf="@id/actionPrev"
-        app:layout_constraintEnd_toStartOf="@id/actionNext"
+        app:layout_constraintVertical_bias="1"
+        app:layout_constraintLeft_toRightOf="@id/actionPrev"
+        app:layout_constraintRight_toLeftOf="@id/actionNext"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintTop_toBottomOf="@id/media_seamless" />
 
@@ -62,29 +109,70 @@
         android:id="@+id/actionNext"
         android:layout_width="48dp"
         android:layout_height="48dp"
-        app:layout_constraintStart_toEndOf="@id/media_progress_bar"
-        app:layout_constraintEnd_toStartOf="@id/actionStart"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        app:layout_constraintVertical_bias="1"
+        app:layout_constraintLeft_toRightOf="@id/media_progress_bar"
+        app:layout_constraintRight_toLeftOf="@id/action0"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintTop_toBottomOf="@id/media_seamless" />
 
     <Constraint
-        android:id="@+id/actionStart"
+        android:id="@+id/action0"
         android:layout_width="48dp"
         android:layout_height="48dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
         android:visibility="gone"
-        app:layout_constraintStart_toEndOf="@id/actionNext"
-        app:layout_constraintEnd_toStartOf="@id/actionEnd"
+        app:layout_constraintVertical_bias="1"
+        app:layout_constraintLeft_toRightOf="@id/actionNext"
+        app:layout_constraintRight_toLeftOf="@id/action1"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintTop_toBottomOf="@id/media_seamless" />
 
     <Constraint
-        android:id="@+id/actionEnd"
+        android:id="@+id/action1"
         android:layout_width="48dp"
         android:layout_height="48dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
         android:visibility="gone"
-        app:layout_constraintStart_toEndOf="@id/actionStart"
-        app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
+        app:layout_constraintVertical_bias="1"
+        app:layout_constraintLeft_toRightOf="@id/action0"
+        app:layout_constraintRight_toLeftOf="@id/action2"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintTop_toBottomOf="@id/media_seamless" />
 
-</ConstraintSet>
\ No newline at end of file
+    <Constraint
+        android:id="@+id/action2"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        android:visibility="gone"
+        app:layout_constraintVertical_bias="1"
+        app:layout_constraintLeft_toRightOf="@id/action1"
+        app:layout_constraintRight_toLeftOf="@id/action3"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/media_seamless" />
+
+    <Constraint
+        android:id="@+id/action3"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        android:visibility="gone"
+        app:layout_constraintVertical_bias="1"
+        app:layout_constraintLeft_toRightOf="@id/action2"
+        app:layout_constraintRight_toLeftOf="@id/action4"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/media_seamless" />
+
+    <Constraint
+        android:id="@+id/action4"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginBottom="@dimen/qs_media_padding"
+        android:visibility="gone"
+        app:layout_constraintVertical_bias="1"
+        app:layout_constraintLeft_toRightOf="@id/action3"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/media_seamless"
+        app:layout_constraintRight_toLeftOf="@id/media_action_barrier_end" />
+</ConstraintSet>
diff --git a/packages/SystemUI/res/xml/media_session_expanded.xml b/packages/SystemUI/res/xml/media_session_expanded.xml
index 18ec7aa..10da704 100644
--- a/packages/SystemUI/res/xml/media_session_expanded.xml
+++ b/packages/SystemUI/res/xml/media_session_expanded.xml
@@ -28,57 +28,118 @@
         app:layout_constraintBottom_toBottomOf="parent" />
 
     <Constraint
+        android:id="@+id/header_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dp"
+        android:layout_marginStart="@dimen/qs_media_padding"
+        android:layout_marginEnd="@dimen/qs_media_padding"
+        app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintTop_toBottomOf="@id/icon"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintHorizontal_bias="0" />
+    <Constraint
+        android:id="@+id/header_artist"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/qs_media_padding"
+        android:layout_marginTop="0dp"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
+        app:layout_constraintBottom_toTopOf="@id/media_action_barrier"
+        app:layout_constraintTop_toBottomOf="@id/header_title"
+        app:layout_constraintStart_toStartOf="@id/header_title"
+        app:layout_constraintVertical_bias="0"
+        app:layout_constraintHorizontal_bias="0" />
+
+    <Constraint
         android:id="@+id/actionPlayPause"
         android:layout_width="48dp"
         android:layout_height="48dp"
+        android:layout_marginStart="@dimen/qs_media_padding"
         android:layout_marginEnd="@dimen/qs_media_padding"
+        android:layout_marginBottom="0dp"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintTop_toBottomOf="@id/media_seamless"
-        app:layout_constraintBottom_toTopOf="@id/actionEnd" />
+        app:layout_constraintBottom_toBottomOf="@id/header_artist" />
 
+    <!--
+    The bottom row of action buttons should remain in the same order when RTL, so their constraints
+    are set with right/left instead of start/end.
+    The chain is set to "spread" so that the progress bar can be weighted to fill any empty space.
+     -->
     <Constraint
         android:id="@+id/actionPrev"
         android:layout_width="48dp"
         android:layout_height="48dp"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/media_progress_bar"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@id/media_progress_bar"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/actionPlayPause" />
+        app:layout_constraintTop_toBottomOf="@id/header_artist"
+        app:layout_constraintHorizontal_chainStyle="spread" />
 
     <Constraint
         android:id="@+id/media_progress_bar"
         android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        app:layout_constraintStart_toEndOf="@id/actionPrev"
-        app:layout_constraintEnd_toStartOf="@id/actionNext"
+        android:layout_height="48dp"
+        app:layout_constraintLeft_toRightOf="@id/actionPrev"
+        app:layout_constraintRight_toLeftOf="@id/actionNext"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/actionPlayPause" />
+        app:layout_constraintTop_toBottomOf="@id/header_artist"
+        app:layout_constraintHorizontal_weight="1" />
 
     <Constraint
         android:id="@+id/actionNext"
         android:layout_width="48dp"
         android:layout_height="48dp"
-        app:layout_constraintStart_toEndOf="@id/media_progress_bar"
-        app:layout_constraintEnd_toStartOf="@id/actionStart"
+        app:layout_constraintLeft_toRightOf="@id/media_progress_bar"
+        app:layout_constraintRight_toLeftOf="@id/action0"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/actionPlayPause" />
+        app:layout_constraintTop_toBottomOf="@id/header_artist" />
 
     <Constraint
-        android:id="@+id/actionStart"
+        android:id="@+id/action0"
         android:layout_width="48dp"
         android:layout_height="48dp"
-        app:layout_constraintStart_toEndOf="@id/actionNext"
-        app:layout_constraintEnd_toStartOf="@id/actionEnd"
+        app:layout_constraintLeft_toRightOf="@id/actionNext"
+        app:layout_constraintRight_toLeftOf="@id/action1"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/actionPlayPause" />
+        app:layout_constraintTop_toBottomOf="@id/header_artist" />
 
     <Constraint
-        android:id="@+id/actionEnd"
+        android:id="@+id/action1"
         android:layout_width="48dp"
         android:layout_height="48dp"
-        app:layout_constraintStart_toEndOf="@id/actionStart"
-        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintLeft_toRightOf="@id/action0"
+        app:layout_constraintRight_toLeftOf="@id/action2"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/actionPlayPause" />
+        app:layout_constraintTop_toBottomOf="@id/header_artist" />
 
-</ConstraintSet>
\ No newline at end of file
+    <Constraint
+        android:id="@+id/action2"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        app:layout_constraintLeft_toRightOf="@id/action1"
+        app:layout_constraintRight_toLeftOf="@id/action3"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/header_artist" />
+
+    <Constraint
+        android:id="@+id/action3"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        app:layout_constraintLeft_toRightOf="@id/action2"
+        app:layout_constraintRight_toLeftOf="@id/action4"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/header_artist" />
+
+    <Constraint
+        android:id="@+id/action4"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        app:layout_constraintLeft_toRightOf="@id/action3"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/header_artist" />
+</ConstraintSet>
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/UiBackground.java b/packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/UiBackground.java
similarity index 100%
rename from packages/SystemUI/src/com/android/systemui/dagger/qualifiers/UiBackground.java
rename to packages/SystemUI/shared/src/com/android/systemui/dagger/qualifiers/UiBackground.java
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/BitmapUtil.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/BitmapUtil.java
deleted file mode 100644
index 325bcfc..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/BitmapUtil.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.shared.recents.utilities;
-
-import android.graphics.Bitmap;
-import android.graphics.ColorSpace;
-import android.graphics.ParcelableColorSpace;
-import android.hardware.HardwareBuffer;
-import android.os.Bundle;
-
-import java.util.Objects;
-
-/**
- * Utils for working with Bitmaps.
- */
-public final class BitmapUtil {
-    private static final String KEY_BUFFER = "bitmap_util_buffer";
-    private static final String KEY_COLOR_SPACE = "bitmap_util_color_space";
-
-    private BitmapUtil(){ }
-
-    /**
-     * Creates a Bundle that represents the given Bitmap.
-     * <p>The Bundle will contain a wrapped version of the Bitmaps HardwareBuffer, so will avoid
-     * copies when passing across processes, only pass to processes you trust.
-     *
-     * <p>Returns a new Bundle rather than modifying an exiting one to avoid key collisions, the
-     * returned Bundle should be treated as a standalone object.
-     *
-     * @param bitmap to convert to bundle
-     * @return a Bundle representing the bitmap, should only be parsed by
-     *         {@link #bundleToHardwareBitmap(Bundle)}
-     */
-    public static Bundle hardwareBitmapToBundle(Bitmap bitmap) {
-        if (bitmap.getConfig() != Bitmap.Config.HARDWARE) {
-            throw new IllegalArgumentException(
-                    "Passed bitmap must have hardware config, found: " + bitmap.getConfig());
-        }
-
-        // Bitmap assumes SRGB for null color space
-        ParcelableColorSpace colorSpace =
-                bitmap.getColorSpace() == null
-                        ? new ParcelableColorSpace(ColorSpace.get(ColorSpace.Named.SRGB))
-                        : new ParcelableColorSpace(bitmap.getColorSpace());
-
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(KEY_BUFFER, bitmap.getHardwareBuffer());
-        bundle.putParcelable(KEY_COLOR_SPACE, colorSpace);
-
-        return bundle;
-    }
-
-    /**
-     * Extracts the Bitmap added to a Bundle with {@link #hardwareBitmapToBundle(Bitmap)} .}
-     *
-     * <p>This Bitmap contains the HardwareBuffer from the original caller, be careful passing this
-     * Bitmap on to any other source.
-     *
-     * @param bundle containing the bitmap
-     * @return a hardware Bitmap
-     */
-    public static Bitmap bundleToHardwareBitmap(Bundle bundle) {
-        if (!bundle.containsKey(KEY_BUFFER) || !bundle.containsKey(KEY_COLOR_SPACE)) {
-            throw new IllegalArgumentException("Bundle does not contain a hardware bitmap");
-        }
-
-        HardwareBuffer buffer = bundle.getParcelable(KEY_BUFFER);
-        ParcelableColorSpace colorSpace = bundle.getParcelable(KEY_COLOR_SPACE);
-
-        return Bitmap.wrapHardwareBuffer(Objects.requireNonNull(buffer),
-                colorSpace.getColorSpace());
-    }
-}
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 db62f88..e38d2ba 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
@@ -17,36 +17,22 @@
 package com.android.systemui.shared.system;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 
 import android.app.ActivityOptions;
 import android.content.Context;
 import android.os.Handler;
 
-import com.android.systemui.shared.recents.model.Task;
-
 /**
  * Wrapper around internal ActivityOptions creation.
  */
 public abstract class ActivityOptionsCompat {
 
     /**
+     * @Deprecated
      * @return ActivityOptions for starting a task in split screen as the primary window.
      */
     public static ActivityOptions makeSplitScreenOptions(boolean dockTopLeft) {
-        return makeSplitScreenOptions(dockTopLeft, true);
-    }
-
-    /**
-     * @return ActivityOptions for starting a task in split screen.
-     */
-    public static ActivityOptions makeSplitScreenOptions(boolean dockTopLeft, boolean isPrimary) {
-        final ActivityOptions options = ActivityOptions.makeBasic();
-        options.setLaunchWindowingMode(isPrimary
-                ? WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                : WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
-        return options;
+        return ActivityOptions.makeBasic();
     }
 
     /**
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index 85d5de0..32299f5 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -78,10 +78,6 @@
     public static final int WINDOWING_MODE_MULTI_WINDOW =
             WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 
-    public static final int WINDOWING_MODE_SPLIT_SCREEN_PRIMARY =
-            WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-    public static final int WINDOWING_MODE_SPLIT_SCREEN_SECONDARY =
-            WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
     public static final int WINDOWING_MODE_FREEFORM = WindowConfiguration.WINDOWING_MODE_FREEFORM;
 
     public static final int ITYPE_EXTRA_NAVIGATION_BAR = InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
index ac62cf9..15593ea 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
@@ -22,6 +22,7 @@
 import android.hardware.devicestate.DeviceStateManager
 import android.os.Handler
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
 import com.android.systemui.unfold.util.UnfoldTransitionATracePrefix
@@ -53,6 +54,7 @@
             @BindsInstance sensorManager: SensorManager,
             @BindsInstance @Main handler: Handler,
             @BindsInstance @Main executor: Executor,
+            @BindsInstance @UiBackground backgroundExecutor: Executor,
             @BindsInstance @UnfoldTransitionATracePrefix tracingTagPrefix: String,
             @BindsInstance contentResolver: ContentResolver = context.contentResolver
         ): UnfoldSharedComponent
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt
index 23e4c97..c612995 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.unfold
 
 import android.hardware.SensorManager
+import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
 import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
 import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
@@ -30,6 +31,7 @@
 import dagger.Module
 import dagger.Provides
 import java.util.Optional
+import java.util.concurrent.Executor
 import javax.inject.Singleton
 
 @Module
@@ -67,10 +69,11 @@
     @Provides
     fun hingeAngleProvider(
         config: UnfoldTransitionConfig,
-        sensorManager: SensorManager
+        sensorManager: SensorManager,
+        @UiBackground executor: Executor
     ): HingeAngleProvider =
         if (config.isHingeAngleEnabled) {
-            HingeSensorAngleProvider(sensorManager)
+            HingeSensorAngleProvider(sensorManager, executor)
         } else {
             EmptyHingeAngleProvider
         }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
index d5d6362..8e4ff9b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
@@ -42,6 +42,7 @@
     sensorManager: SensorManager,
     mainHandler: Handler,
     mainExecutor: Executor,
+    backgroundExecutor: Executor,
     tracingTagPrefix: String
 ): UnfoldTransitionProgressProvider =
     DaggerUnfoldSharedComponent.factory()
@@ -53,6 +54,7 @@
             sensorManager,
             mainHandler,
             mainExecutor,
+            backgroundExecutor,
             tracingTagPrefix)
         .unfoldTransitionProvider
         .orElse(null)
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
index a50d852..c93412b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
@@ -6,21 +6,29 @@
 import android.hardware.SensorManager
 import android.os.Trace
 import androidx.core.util.Consumer
+import java.util.concurrent.Executor
 
-internal class HingeSensorAngleProvider(private val sensorManager: SensorManager) :
+internal class HingeSensorAngleProvider(
+    private val sensorManager: SensorManager,
+    private val executor: Executor
+) :
     HingeAngleProvider {
 
     private val sensorListener = HingeAngleSensorListener()
     private val listeners: MutableList<Consumer<Float>> = arrayListOf()
 
-    override fun start() {
+    override fun start() = executor.execute {
         Trace.beginSection("HingeSensorAngleProvider#start")
         val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_HINGE_ANGLE)
-        sensorManager.registerListener(sensorListener, sensor, SensorManager.SENSOR_DELAY_FASTEST)
+        sensorManager.registerListener(
+            sensorListener,
+            sensor,
+            SensorManager.SENSOR_DELAY_FASTEST
+        )
         Trace.endSection()
     }
 
-    override fun stop() {
+    override fun stop() = executor.execute {
         sensorManager.unregisterListener(sensorListener)
     }
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt
index 7b67917..8491f83 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt
@@ -28,7 +28,7 @@
  * If the transition has already started by the moment when the clients are ready to play the
  * transition then it will report transition started callback and current animation progress.
  */
-class ScopedUnfoldTransitionProgressProvider
+open class ScopedUnfoldTransitionProgressProvider
 @JvmOverloads
 constructor(source: UnfoldTransitionProgressProvider? = null) :
     UnfoldTransitionProgressProvider, TransitionProgressListener {
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
index c4b02f6..458d22e 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
@@ -96,7 +96,7 @@
      **/
     public void reloadColors() {
         int color = Utils.getColorAttrDefaultColor(getContext(),
-                android.R.attr.textColorPrimaryInverse);
+                com.android.internal.R.attr.textColorOnAccent);
         setTextColor(color);
         setBackground(getContext()
                 .getDrawable(com.android.systemui.R.drawable.kg_emergency_button_background));
@@ -107,10 +107,10 @@
         return super.performLongClick();
     }
 
-    void updateEmergencyCallButton(boolean isInCall, boolean isVoiceCapable, boolean simLocked) {
+    void updateEmergencyCallButton(boolean isInCall, boolean hasTelephonyRadio, boolean simLocked) {
         boolean visible = false;
-        if (isVoiceCapable) {
-            // Emergency calling requires voice capability.
+        if (hasTelephonyRadio) {
+            // Emergency calling requires a telephony radio.
             if (isInCall) {
                 visible = true; // always show "return to call" if phone is off-hook
             } else {
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
index e7215b8..f289105 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
@@ -21,6 +21,7 @@
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.os.PowerManager;
 import android.os.SystemClock;
@@ -116,7 +117,8 @@
         if (mView != null) {
             mView.updateEmergencyCallButton(
                     mTelecomManager != null && mTelecomManager.isInCall(),
-                    mTelephonyManager.isVoiceCapable(),
+                    getContext().getPackageManager().hasSystemFeature(
+                            PackageManager.FEATURE_TELEPHONY),
                     mKeyguardUpdateMonitor.isSimPinVoiceSecure());
         }
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
index 7f456db..eb418ff 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
@@ -194,9 +194,12 @@
                 mMessageAreaController.setMessage(mView.getWrongPasswordStringId());
             }
             mView.resetPasswordText(true /* animate */, false /* announce deletion if no match */);
+            startErrorAnimation();
         }
     }
 
+    protected void startErrorAnimation() { /* no-op */ }
+
     protected void verifyPasswordAndUnlock() {
         if (mDismissing) return; // already verified but haven't been dismissed; don't do it again.
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index 1efda7e..77044ed 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -188,14 +188,13 @@
 
         enableClipping(false);
         setTranslationY(0);
-        AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 280 /* duration */,
-                mDisappearYTranslation, mDisappearAnimationUtils.getInterpolator(),
-                getAnimationListener(InteractionJankMonitor.CUJ_LOCKSCREEN_PIN_DISAPPEAR));
         DisappearAnimationUtils disappearAnimationUtils = needsSlowUnlockTransition
                         ? mDisappearAnimationUtilsLocked
                         : mDisappearAnimationUtils;
-        disappearAnimationUtils.startAnimation2d(mViews,
-                () -> {
+        disappearAnimationUtils.createAnimation(
+                this, 0, 200, mDisappearYTranslation, false,
+                mDisappearAnimationUtils.getInterpolator(), () -> {
+                    getAnimationListener(InteractionJankMonitor.CUJ_LOCKSCREEN_PIN_DISAPPEAR);
                     enableClipping(true);
                     if (finishRunnable != null) {
                         finishRunnable.run();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index 4723af2..c46e33d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -24,6 +24,9 @@
 import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
 import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
 
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
@@ -32,6 +35,10 @@
 
 import com.android.internal.widget.LockscreenCredential;
 import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * A Pin based Keyguard input view
@@ -188,4 +195,48 @@
         return getContext().getString(
                 com.android.internal.R.string.keyguard_accessibility_pin_unlock);
     }
+
+    /**
+     * Begins an error animation for this view.
+     **/
+    public void startErrorAnimation() {
+        AnimatorSet animatorSet = new AnimatorSet();
+        List<Animator> animators = new ArrayList();
+        List<View> buttons = new ArrayList<>();
+        for (int i = 1; i <= 9; i++) {
+            buttons.add(mButtons[i]);
+        }
+        buttons.add(mDeleteButton);
+        buttons.add(mButtons[0]);
+        buttons.add(mOkButton);
+
+        int delay = 0;
+        for (int i = 0; i < buttons.size(); i++) {
+            final View button = buttons.get(i);
+            AnimatorSet animateWrapper = new AnimatorSet();
+            animateWrapper.setStartDelay(delay);
+
+            ValueAnimator scaleDownAnimator =  ValueAnimator.ofFloat(1f, 0.8f);
+            scaleDownAnimator.setInterpolator(Interpolators.STANDARD);
+            scaleDownAnimator.addUpdateListener(valueAnimator -> {
+                button.setScaleX((float) valueAnimator.getAnimatedValue());
+                button.setScaleY((float) valueAnimator.getAnimatedValue());
+            });
+            scaleDownAnimator.setDuration(50);
+
+            ValueAnimator scaleUpAnimator =  ValueAnimator.ofFloat(0.8f, 1f);
+            scaleUpAnimator.setInterpolator(Interpolators.STANDARD);
+            scaleUpAnimator.addUpdateListener(valueAnimator -> {
+                button.setScaleX((float) valueAnimator.getAnimatedValue());
+                button.setScaleY((float) valueAnimator.getAnimatedValue());
+            });
+            scaleUpAnimator.setDuration(617);
+
+            animateWrapper.playSequentially(scaleDownAnimator, scaleUpAnimator);
+            animators.add(animateWrapper);
+            delay += 33;
+        }
+        animatorSet.playTogether(animators);
+        animatorSet.start();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
index 8de4e7b..f7423ed 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
@@ -133,4 +133,10 @@
     void resetState() {
         mView.setPasswordEntryEnabled(true);
     }
+
+    @Override
+    protected void startErrorAnimation() {
+        super.startErrorAnimation();
+        mView.startErrorAnimation();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index af7cf86..362fbed 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -918,7 +918,7 @@
                     }
                     drawable.setTint(iconColor);
 
-                    Drawable bg = context.getDrawable(R.drawable.kg_bg_avatar);
+                    Drawable bg = context.getDrawable(R.drawable.user_avatar_bg);
                     bg.setTintBlendMode(BlendMode.DST);
                     bg.setTint(Utils.getColorAttrDefaultColor(context,
                                 com.android.internal.R.attr.colorSurfaceVariant));
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 31f466f..087817f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -113,6 +113,22 @@
         }
     }
 
+    /** Sets a translationY value on every child view except for the media view. */
+    public void setChildrenTranslationYExcludingMediaView(float translationY) {
+        setChildrenTranslationYExcluding(translationY, Set.of(mMediaHostContainer));
+    }
+
+    /** Sets a translationY value on every view except for the views in the provided set. */
+    private void setChildrenTranslationYExcluding(float translationY, Set<View> excludedViews) {
+        for (int i = 0; i < mStatusViewContainer.getChildCount(); i++) {
+            final View child = mStatusViewContainer.getChildAt(i);
+
+            if (!excludedViews.contains(child)) {
+                child.setTranslationY(translationY);
+            }
+        }
+    }
+
     public float getChildrenAlphaExcludingSmartSpace() {
         return mChildrenAlphaExcludingSmartSpace;
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index a5fe0ef..14c9cb2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -20,7 +20,6 @@
 import android.util.Slog;
 
 import com.android.keyguard.KeyguardClockSwitch.ClockSize;
-import com.android.systemui.communal.CommunalStateController;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.statusbar.notification.AnimatableProperty;
 import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -63,7 +62,6 @@
             KeyguardClockSwitchController keyguardClockSwitchController,
             KeyguardStateController keyguardStateController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
-            CommunalStateController communalStateController,
             ConfigurationController configurationController,
             DozeParameters dozeParameters,
             KeyguardUnlockAnimationController keyguardUnlockAnimationController,
@@ -75,9 +73,8 @@
         mConfigurationController = configurationController;
         mDozeParameters = dozeParameters;
         mKeyguardStateController = keyguardStateController;
-        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
-                keyguardStateController, dozeParameters, screenOffAnimationController,
-                /* animateYPos= */ true, /* visibleOnCommunal= */ false);
+        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
+                dozeParameters, screenOffAnimationController, /* animateYPos= */ true);
         mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
     }
 
@@ -140,6 +137,13 @@
     }
 
     /**
+     * Sets a translationY on the views on the keyguard, except on the media view.
+     */
+    public void setTranslationYExcludingMedia(float translationY) {
+        mView.setChildrenTranslationYExcludingMediaView(translationY);
+    }
+
+    /**
      * Set keyguard status view alpha.
      */
     public void setAlpha(float alpha) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 37f4564..3858f9c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -52,6 +52,7 @@
 import android.content.pm.UserInfo;
 import android.database.ContentObserver;
 import android.hardware.SensorPrivacyManager;
+import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricSourceType;
 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
@@ -325,7 +326,6 @@
     private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     private final Executor mBackgroundExecutor;
     private SensorPrivacyManager mSensorPrivacyManager;
-    private int mFaceAuthUserId;
 
     /**
      * Short delay before restarting fingerprint authentication after a successful try. This should
@@ -752,15 +752,13 @@
         }
     }
 
-    private void handleFingerprintAcquired(int acquireInfo) {
+    private void handleFingerprintAcquired(
+            @BiometricFingerprintConstants.FingerprintAcquired int acquireInfo) {
         Assert.isMainThread();
-        if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
-            return;
-        }
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
-                cb.onBiometricAcquired(BiometricSourceType.FINGERPRINT);
+                cb.onBiometricAcquired(BiometricSourceType.FINGERPRINT, acquireInfo);
             }
         }
     }
@@ -960,14 +958,11 @@
 
     private void handleFaceAcquired(int acquireInfo) {
         Assert.isMainThread();
-        if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
-            return;
-        }
-        if (DEBUG_FACE) Log.d(TAG, "Face acquired");
+        if (DEBUG_FACE) Log.d(TAG, "Face acquired acquireInfo=" + acquireInfo);
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
-                cb.onBiometricAcquired(BiometricSourceType.FACE);
+                cb.onBiometricAcquired(BiometricSourceType.FACE, acquireInfo);
             }
         }
     }
@@ -1034,8 +1029,8 @@
         boolean cameraPrivacyEnabled = false;
         if (mSensorPrivacyManager != null) {
             cameraPrivacyEnabled = mSensorPrivacyManager
-                    .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA,
-                    mFaceAuthUserId);
+                    .isSensorPrivacyEnabled(SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
+                    SensorPrivacyManager.Sensors.CAMERA);
         }
 
         if (msgId == FaceManager.FACE_ERROR_CANCELED
@@ -2603,7 +2598,6 @@
             // This would need to be updated for multi-sensor devices
             final boolean supportsFaceDetection = !mFaceSensorProperties.isEmpty()
                     && mFaceSensorProperties.get(0).supportsFaceDetection;
-            mFaceAuthUserId = userId;
             if (isEncryptedOrLockdown(userId) && supportsFaceDetection) {
                 mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
             } else {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 8d5603d..ad2053c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -206,8 +206,10 @@
      * It is guaranteed that either {@link #onBiometricAuthenticated} or
      * {@link #onBiometricAuthFailed(BiometricSourceType)} is called after this method eventually.
      * @param biometricSourceType
+     * @param acquireInfo see {@link android.hardware.biometrics.BiometricFaceConstants} and
+     *                    {@link android.hardware.biometrics.BiometricFingerprintConstants}
      */
-    public void onBiometricAcquired(BiometricSourceType biometricSourceType) { }
+    public void onBiometricAcquired(BiometricSourceType biometricSourceType, int acquireInfo) { }
 
     /**
      * Called when a biometric couldn't be authenticated.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
index bb608c7..498304b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
@@ -22,7 +22,6 @@
 import android.view.ViewPropertyAnimator;
 
 import com.android.systemui.animation.Interpolators;
-import com.android.systemui.communal.CommunalStateController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.AnimatableProperty;
 import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -39,30 +38,24 @@
 public class KeyguardVisibilityHelper {
 
     private View mView;
-    private final CommunalStateController mCommunalStateController;
     private final KeyguardStateController mKeyguardStateController;
     private final DozeParameters mDozeParameters;
     private final ScreenOffAnimationController mScreenOffAnimationController;
-    private final boolean mVisibleOnCommunal;
     private boolean mAnimateYPos;
     private boolean mKeyguardViewVisibilityAnimating;
     private boolean mLastOccludedState = false;
     private final AnimationProperties mAnimationProperties = new AnimationProperties();
 
     public KeyguardVisibilityHelper(View view,
-            CommunalStateController communalStateController,
             KeyguardStateController keyguardStateController,
             DozeParameters dozeParameters,
             ScreenOffAnimationController screenOffAnimationController,
-            boolean animateYPos,
-            boolean visibleOnCommunal) {
+            boolean animateYPos) {
         mView = view;
-        mCommunalStateController = communalStateController;
         mKeyguardStateController = keyguardStateController;
         mDozeParameters = dozeParameters;
         mScreenOffAnimationController = screenOffAnimationController;
         mAnimateYPos = animateYPos;
-        mVisibleOnCommunal = visibleOnCommunal;
     }
 
     public boolean isVisibilityAnimating() {
@@ -81,13 +74,6 @@
         boolean isOccluded = mKeyguardStateController.isOccluded();
         mKeyguardViewVisibilityAnimating = false;
 
-        // If the communal view is showing, hide immediately
-        if (!mVisibleOnCommunal && mCommunalStateController.getCommunalViewShowing()) {
-            mView.setVisibility(View.GONE);
-            mView.setAlpha(1f);
-            return;
-        }
-
         if ((!keyguardFadingAway && oldStatusBarState == KEYGUARD
                 && statusBarState != KEYGUARD) || goingToFullShade) {
             mKeyguardViewVisibilityAnimating = true;
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 370686a..74659f7 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -558,7 +558,7 @@
         switch(event.getActionMasked()) {
             case MotionEvent.ACTION_DOWN:
             case MotionEvent.ACTION_HOVER_ENTER:
-                if (!mDownDetected) {
+                if (!mDownDetected && mAccessibilityManager.isTouchExplorationEnabled()) {
                     mVibrator.vibrate(
                             Process.myUid(),
                             getContext().getOpPackageName(),
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
index 00470c0..f925eaa 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
@@ -73,12 +73,14 @@
         ValueAnimator expandBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(),
                 mNormalColor, mHighlightColor);
         expandBackgroundColorAnimator.setDuration(EXPAND_COLOR_ANIMATION_MS);
+        expandBackgroundColorAnimator.setInterpolator(Interpolators.LINEAR);
         expandBackgroundColorAnimator.addUpdateListener(
                 animator -> mBackground.setColor((int) animator.getAnimatedValue()));
 
         ValueAnimator expandTextColorAnimator =
                 ValueAnimator.ofObject(new ArgbEvaluator(),
                 textColorPrimary, textColorPrimaryInverse);
+        expandTextColorAnimator.setInterpolator(Interpolators.LINEAR);
         expandTextColorAnimator.setDuration(EXPAND_COLOR_ANIMATION_MS);
         expandTextColorAnimator.addUpdateListener(valueAnimator -> {
             if (digitTextView != null) {
@@ -98,6 +100,7 @@
                 anim -> mBackground.setCornerRadius((float) anim.getAnimatedValue()));
         ValueAnimator contractBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(),
                 mHighlightColor, mNormalColor);
+        contractBackgroundColorAnimator.setInterpolator(Interpolators.LINEAR);
         contractBackgroundColorAnimator.setStartDelay(CONTRACT_ANIMATION_DELAY_MS);
         contractBackgroundColorAnimator.setDuration(CONTRACT_ANIMATION_MS);
         contractBackgroundColorAnimator.addUpdateListener(
@@ -106,6 +109,7 @@
         ValueAnimator contractTextColorAnimator =
                 ValueAnimator.ofObject(new ArgbEvaluator(), textColorPrimaryInverse,
                 textColorPrimary);
+        contractTextColorAnimator.setInterpolator(Interpolators.LINEAR);
         contractTextColorAnimator.setStartDelay(CONTRACT_ANIMATION_DELAY_MS);
         contractTextColorAnimator.setDuration(CONTRACT_ANIMATION_MS);
         contractTextColorAnimator.addUpdateListener(valueAnimator -> {
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index e0d0fc2..7b98f27 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -19,6 +19,8 @@
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
 import android.graphics.drawable.VectorDrawable;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
@@ -37,8 +39,14 @@
     public NumPadButton(Context context, AttributeSet attrs) {
         super(context, attrs);
 
-        mAnimator = new NumPadAnimator(context, getBackground().mutate(),
-                attrs.getStyleAttribute());
+        Drawable background = getBackground();
+        if (background instanceof GradientDrawable) {
+            mAnimator = new NumPadAnimator(context, background.mutate(),
+                    attrs.getStyleAttribute());
+        } else {
+            mAnimator = null;
+        }
+
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 88a0bce..5cab547 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -18,6 +18,8 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.util.AttributeSet;
@@ -129,8 +131,13 @@
 
         setContentDescription(mDigitText.getText().toString());
 
-        mAnimator = new NumPadAnimator(context, getBackground().mutate(),
-                R.style.NumPadKey, mDigitText);
+        Drawable background = getBackground();
+        if (background instanceof GradientDrawable) {
+            mAnimator = new NumPadAnimator(context, background.mutate(),
+                    R.style.NumPadKey, mDigitText);
+        } else {
+            mAnimator = null;
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/LatencyTester.java b/packages/SystemUI/src/com/android/systemui/LatencyTester.java
index bc2a1ff..7afd43d 100644
--- a/packages/SystemUI/src/com/android/systemui/LatencyTester.java
+++ b/packages/SystemUI/src/com/android/systemui/LatencyTester.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricSourceType;
 import android.os.Build;
 
@@ -78,7 +79,8 @@
     }
 
     private void fakeWakeAndUnlock(BiometricSourceType type) {
-        mBiometricUnlockController.onBiometricAcquired(type);
+        mBiometricUnlockController.onBiometricAcquired(type,
+                BiometricConstants.BIOMETRIC_ACQUIRED_GOOD);
         mBiometricUnlockController.onBiometricAuthenticated(
                 KeyguardUpdateMonitor.getCurrentUser(), type, true /* isStrongBiometric */);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 6a60afa..ff5715c 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -71,7 +71,9 @@
             Key.HAS_SEEN_REVERSE_BOTTOM_SHEET,
             Key.CONTROLS_STRUCTURE_SWIPE_TOOLTIP_COUNT,
             Key.HAS_SEEN_ACCESSIBILITY_FLOATING_MENU_DOCK_TOOLTIP,
-            Key.ACCESSIBILITY_FLOATING_MENU_POSITION
+            Key.ACCESSIBILITY_FLOATING_MENU_POSITION,
+            Key.HAS_CLICKED_NUDGE_TO_SETUP_DREAM,
+            Key.HAS_DISMISSED_NUDGE_TO_SETUP_DREAM
     })
     // TODO: annotate these with their types so {@link PrefsCommandLine} can know how to set them
     public @interface Key {
@@ -115,6 +117,8 @@
         String HAS_SEEN_ACCESSIBILITY_FLOATING_MENU_DOCK_TOOLTIP =
                 "HasSeenAccessibilityFloatingMenuDockTooltip";
         String ACCESSIBILITY_FLOATING_MENU_POSITION = "AccessibilityFloatingMenuPosition";
+        String HAS_CLICKED_NUDGE_TO_SETUP_DREAM = "HasClickedNudgeToSetupDream";
+        String HAS_DISMISSED_NUDGE_TO_SETUP_DREAM = "HasDismissedNudgeToSetupDream";
     }
 
     public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
index 4b86862..498e715 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
@@ -119,9 +119,13 @@
         if (useInvertedAlphaColor) {
             canvas.drawColor(bgColor)
         }
+
+        // We may clear the color(if useInvertedAlphaColor is true) of the rounded corner rects
+        // before drawing rounded corners. If the cutout happens to be inside one of these rects, it
+        // will be cleared, so we have to draw rounded corners before cutout.
+        drawRoundedCorners(canvas)
         // Cutouts are drawn in DisplayCutoutBaseView.onDraw()
         super.onDraw(canvas)
-        drawRoundedCorners(canvas)
 
         debugTransparentRegionPaint?.let {
             calculateTransparentRect()
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 3a6165c..031e378 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -27,6 +27,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.res.Configuration;
 import android.os.Bundle;
+import android.os.Looper;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemProperties;
@@ -105,6 +106,10 @@
         mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();
         log.traceEnd();
 
+        // Enable Looper trace points.
+        // This allows us to see Handler callbacks on traces.
+        Looper.getMainLooper().setTraceTag(Trace.TRACE_TAG_APP);
+
         // Set the application theme that is inherited by all services. Note that setting the
         // application theme in the manifest does only work for activities. Keep this in sync with
         // the theme set there.
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 50ca447..7e1a026 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -1072,6 +1072,7 @@
         pw.println("WindowMagnificationController (displayId=" + mDisplayId + "):");
         pw.println("      mOverlapWithGestureInsets:" + mOverlapWithGestureInsets);
         pw.println("      mScale:" + mScale);
+        pw.println("      mWindowBounds:" + mWindowBounds);
         pw.println("      mMirrorViewBounds:" + (isWindowVisible() ? mMirrorViewBounds : "empty"));
         pw.println("      mMagnificationFrameBoundary:"
                 + (isWindowVisible() ? mMagnificationFrameBoundary : "empty"));
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index 99f27d7..a27b9cd 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -21,6 +21,7 @@
 import android.animation.ValueAnimator
 import android.content.Context
 import android.graphics.PointF
+import android.hardware.biometrics.BiometricFingerprintConstants
 import android.hardware.biometrics.BiometricSourceType
 import android.util.DisplayMetrics
 import android.util.Log
@@ -39,8 +40,8 @@
 import com.android.systemui.statusbar.commandline.Command
 import com.android.systemui.statusbar.commandline.CommandRegistry
 import com.android.systemui.statusbar.phone.BiometricUnlockController
-import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.CentralSurfaces
+import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -257,6 +258,16 @@
         override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType?) {
             mView.retractRipple()
         }
+
+        override fun onBiometricAcquired(
+            biometricSourceType: BiometricSourceType?,
+            acquireInfo: Int
+        ) {
+            if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
+                    acquireInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_PARTIAL) {
+                mView.retractRipple()
+            }
+        }
     }
 
     private val configurationChangedListener =
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 8052c20..bc7a3f6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.biometrics;
 
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD;
 import static android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD;
 
 import static com.android.internal.util.Preconditions.checkArgument;
@@ -30,6 +31,7 @@
 import android.content.IntentFilter;
 import android.graphics.Point;
 import android.graphics.RectF;
+import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.SensorLocationInternal;
 import android.hardware.display.DisplayManager;
 import android.hardware.fingerprint.FingerprintManager;
@@ -141,11 +143,11 @@
     private int mActivePointerId = -1;
     // The timestamp of the most recent touch log.
     private long mTouchLogTime;
-    // Sensor has a good capture for this touch. Do not need to illuminate for this particular
-    // touch event anymore. In other words, do not illuminate until user lifts and touches the
-    // sensor area again.
+    // Sensor has a capture (good or bad) for this touch. Do not need to illuminate for this
+    // particular touch event anymore. In other words, do not illuminate until user lifts and
+    // touches the sensor area again.
     // TODO: We should probably try to make touch/illumination things more of a FSM
-    private boolean mGoodCaptureReceived;
+    private boolean mAcquiredReceived;
 
     // The current request from FingerprintService. Null if no current request.
     @Nullable UdfpsControllerOverlay mOverlay;
@@ -221,19 +223,28 @@
         }
 
         @Override
-        public void onAcquiredGood(int sensorId) {
-            mFgExecutor.execute(() -> {
-                if (mOverlay == null) {
-                    Log.e(TAG, "Null request when onAcquiredGood for sensorId: " + sensorId);
-                    return;
-                }
-                mGoodCaptureReceived = true;
-                final UdfpsView view = mOverlay.getOverlayView();
-                if (view != null) {
-                    view.stopIllumination();
-                }
-                mOverlay.onAcquiredGood();
-            });
+        public void onAcquired(
+                int sensorId,
+                @BiometricFingerprintConstants.FingerprintAcquired int acquiredInfo
+        ) {
+            if (BiometricFingerprintConstants.shouldTurnOffHbm(acquiredInfo)) {
+                boolean acquiredGood = acquiredInfo == FINGERPRINT_ACQUIRED_GOOD;
+                mFgExecutor.execute(() -> {
+                    if (mOverlay == null) {
+                        Log.e(TAG, "Null request when onAcquired for sensorId: " + sensorId
+                                + " acquiredInfo=" + acquiredInfo);
+                        return;
+                    }
+                    mAcquiredReceived = true;
+                    final UdfpsView view = mOverlay.getOverlayView();
+                    if (view != null) {
+                        view.stopIllumination(); // turn off HBM
+                    }
+                    if (acquiredGood) {
+                        mOverlay.onAcquiredGood();
+                    }
+                });
+            }
         }
 
         @Override
@@ -414,8 +425,8 @@
                                 "minor: %.1f, major: %.1f, v: %.1f, exceedsVelocityThreshold: %b",
                                 minor, major, v, exceedsVelocityThreshold);
                         final long sinceLastLog = mSystemClock.elapsedRealtime() - mTouchLogTime;
-                        if (!isIlluminationRequested && !mGoodCaptureReceived &&
-                                !exceedsVelocityThreshold) {
+                        if (!isIlluminationRequested && !mAcquiredReceived
+                                && !exceedsVelocityThreshold) {
                             final int rawX = (int) event.getRawX();
                             final int rawY = (int) event.getRawY();
                             // Default coordinates assume portrait mode.
@@ -573,16 +584,18 @@
     }
 
     /**
-     * Play haptic to signal udfps scanning started.
+     * If a11y touchExplorationEnabled, play haptic to signal UDFPS scanning started.
      */
     @VisibleForTesting
     public void playStartHaptic() {
-        mVibrator.vibrate(
-                Process.myUid(),
-                mContext.getOpPackageName(),
-                EFFECT_CLICK,
-                "udfps-onStart-click",
-                VIBRATION_ATTRIBUTES);
+        if (mAccessibilityManager.isTouchExplorationEnabled()) {
+            mVibrator.vibrate(
+                    Process.myUid(),
+                    mContext.getOpPackageName(),
+                    EFFECT_CLICK,
+                    "udfps-onStart-click",
+                    VIBRATION_ATTRIBUTES);
+        }
     }
 
     @Nullable
@@ -799,7 +812,7 @@
     private void onFingerUp(@NonNull UdfpsView view) {
         mExecution.assertIsMainThread();
         mActivePointerId = -1;
-        mGoodCaptureReceived = false;
+        mAcquiredReceived = false;
         if (mOnFingerDown) {
             mFingerprintManager.onPointerUp(mSensorProps.sensorId);
             for (Callback cb : mCallbacks) {
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt
new file mode 100644
index 0000000..6615f6b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt
@@ -0,0 +1,132 @@
+package com.android.systemui.broadcast
+
+import android.annotation.AnyThread
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.os.UserHandle
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.util.wakelock.WakeLock
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+/**
+ * SystemUI master Broadcast sender
+ *
+ * This class dispatches broadcasts on background thread to avoid synchronous call to binder. Use
+ * this class instead of calling [Context.sendBroadcast] directly.
+ */
+@SysUISingleton
+class BroadcastSender @Inject constructor(
+    private val context: Context,
+    private val wakeLockBuilder: WakeLock.Builder,
+    @Background private val bgExecutor: Executor
+) {
+
+    private val WAKE_LOCK_TAG = "SysUI:BroadcastSender"
+    private val WAKE_LOCK_SEND_REASON = "sendInBackground"
+
+    /**
+     * Sends broadcast via [Context.sendBroadcast] on background thread to avoid blocking
+     * synchronous binder call.
+     */
+    @AnyThread
+    fun sendBroadcast(intent: Intent) {
+        sendInBackground {
+            context.sendBroadcast(intent)
+        }
+    }
+
+    /**
+     * Sends broadcast via [Context.sendBroadcast] on background thread to avoid blocking
+     * synchronous binder call.
+     */
+    @AnyThread
+    fun sendBroadcast(intent: Intent, receiverPermission: String?) {
+        sendInBackground {
+            context.sendBroadcast(intent, receiverPermission)
+        }
+    }
+
+    /**
+     * Sends broadcast via [Context.sendBroadcastAsUser] on background thread to avoid blocking
+     * synchronous binder call.
+     */
+    @AnyThread
+    fun sendBroadcastAsUser(intent: Intent, userHandle: UserHandle) {
+        sendInBackground {
+            context.sendBroadcastAsUser(intent, userHandle)
+        }
+    }
+
+    /**
+     * Sends broadcast via [Context.sendBroadcastAsUser] on background thread to avoid blocking
+     * synchronous binder call.
+     */
+    @AnyThread
+    fun sendBroadcastAsUser(intent: Intent, userHandle: UserHandle, receiverPermission: String?) {
+        sendInBackground {
+            context.sendBroadcastAsUser(intent, userHandle, receiverPermission)
+        }
+    }
+
+    /**
+     * Sends broadcast via [Context.sendBroadcastAsUser] on background thread to avoid blocking
+     * synchronous binder call.
+     */
+    @AnyThread
+    fun sendBroadcastAsUser(
+        intent: Intent,
+        userHandle: UserHandle,
+        receiverPermission: String?,
+        options: Bundle?
+    ) {
+        sendInBackground {
+            context.sendBroadcastAsUser(intent, userHandle, receiverPermission, options)
+        }
+    }
+
+    /**
+     * Sends broadcast via [Context.sendBroadcastAsUser] on background thread to avoid blocking
+     * synchronous binder call.
+     */
+    @AnyThread
+    fun sendBroadcastAsUser(
+        intent: Intent,
+        userHandle: UserHandle,
+        receiverPermission: String?,
+        appOp: Int
+    ) {
+        sendInBackground {
+            context.sendBroadcastAsUser(intent, userHandle, receiverPermission, appOp)
+        }
+    }
+
+    /**
+     * Sends [Intent.ACTION_CLOSE_SYSTEM_DIALOGS] broadcast to the system.
+     */
+    @AnyThread
+    fun closeSystemDialogs() {
+        sendInBackground {
+            context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
+        }
+    }
+
+    /**
+     * Dispatches parameter on background executor while holding a wakelock.
+     */
+    private fun sendInBackground(callable: () -> Unit) {
+        val broadcastWakelock = wakeLockBuilder.setTag(WAKE_LOCK_TAG)
+                                .setMaxTimeout(5000)
+                                .build()
+        broadcastWakelock.acquire(WAKE_LOCK_SEND_REASON)
+        bgExecutor.execute {
+            try {
+                callable.invoke()
+            } finally {
+                broadcastWakelock.release(WAKE_LOCK_SEND_REASON)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
index 508262d..835025b 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.charging;
 
+import static com.android.systemui.charging.WirelessChargingLayout.UNKNOWN_BATTERY_LEVEL;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -76,6 +78,16 @@
     }
 
     /**
+     * Creates a charging animation object using mostly default values for non-dozing and unknown
+     * battery level without charging number shown.
+     */
+    public static WirelessChargingAnimation makeChargingAnimationWithNoBatteryLevel(
+            @NonNull Context context, UiEventLogger uiEventLogger) {
+        return makeWirelessChargingAnimation(context, null,
+                UNKNOWN_BATTERY_LEVEL, UNKNOWN_BATTERY_LEVEL, null, false, uiEventLogger);
+    }
+
+    /**
      * Show the view for the specified duration.
      */
     public void show(long delay) {
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index 56e4d7e..0f937d1 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -73,6 +73,7 @@
 
 import com.android.internal.policy.PhoneWindow;
 import com.android.systemui.R;
+import com.android.systemui.screenshot.DraggableConstraintLayout;
 import com.android.systemui.screenshot.FloatingWindowUtil;
 import com.android.systemui.screenshot.OverlayActionChip;
 import com.android.systemui.screenshot.TimeoutHandler;
@@ -166,8 +167,28 @@
         mRemoteCopyChip = requireNonNull(mView.findViewById(R.id.remote_copy_chip));
         mDismissButton = requireNonNull(mView.findViewById(R.id.dismiss_button));
 
-        mView.setOnDismissEndCallback(this::hideImmediate);
-        mView.setOnInteractionCallback(mTimeoutHandler::resetTimeout);
+        mView.setCallbacks(new DraggableConstraintLayout.SwipeDismissCallbacks() {
+            @Override
+            public void onInteraction() {
+                mTimeoutHandler.resetTimeout();
+            }
+
+            @Override
+            public void onSwipeDismissInitiated(Animator animator) {
+                animator.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationStart(Animator animation) {
+                        super.onAnimationStart(animation);
+                        mContainer.animate().alpha(0).start();
+                    }
+                });
+            }
+
+            @Override
+            public void onDismissComplete() {
+                hideImmediate();
+            }
+        });
 
         mDismissButton.setOnClickListener(view -> animateOut());
 
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DraggableConstraintLayout.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DraggableConstraintLayout.java
deleted file mode 100644
index a327809..0000000
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DraggableConstraintLayout.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.clipboardoverlay;
-
-import android.animation.Animator;
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.constraintlayout.widget.ConstraintLayout;
-
-import com.android.systemui.R;
-import com.android.systemui.screenshot.SwipeDismissHandler;
-
-import java.util.function.Consumer;
-
-/**
- * ConstraintLayout that is draggable when touched in a specific region
- */
-public class DraggableConstraintLayout extends ConstraintLayout {
-    private final SwipeDismissHandler mSwipeDismissHandler;
-    private final GestureDetector mSwipeDetector;
-    private Consumer<Animator> mOnDismissInitiated;
-    private Runnable mOnDismissComplete;
-    private Runnable mOnInteraction;
-
-    public DraggableConstraintLayout(Context context) {
-        this(context, null);
-    }
-
-    public DraggableConstraintLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public DraggableConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-
-        mSwipeDismissHandler = new SwipeDismissHandler(mContext, this,
-                new SwipeDismissHandler.SwipeDismissCallbacks() {
-                    @Override
-                    public void onInteraction() {
-                        if (mOnInteraction != null) {
-                            mOnInteraction.run();
-                        }
-                    }
-
-                    @Override
-                    public void onSwipeDismissInitiated(Animator animator) {
-                        if (mOnDismissInitiated != null) {
-                            mOnDismissInitiated.accept(animator);
-                        }
-                    }
-
-                    @Override
-                    public void onDismissComplete() {
-                        if (mOnDismissComplete != null) {
-                            mOnDismissComplete.run();
-                        }
-                    }
-                });
-        setOnTouchListener(mSwipeDismissHandler);
-
-        mSwipeDetector = new GestureDetector(mContext,
-                new GestureDetector.SimpleOnGestureListener() {
-                    final Rect mActionsRect = new Rect();
-
-                    @Override
-                    public boolean onScroll(
-                            MotionEvent ev1, MotionEvent ev2, float distanceX, float distanceY) {
-                        View actionsContainer = findViewById(R.id.actions_container);
-                        actionsContainer.getBoundsOnScreen(mActionsRect);
-                        // return true if we aren't in the actions bar, or if we are but it isn't
-                        // scrollable in the direction of movement
-                        return !mActionsRect.contains((int) ev2.getRawX(), (int) ev2.getRawY())
-                                || !actionsContainer.canScrollHorizontally((int) distanceX);
-                    }
-                });
-        mSwipeDetector.setIsLongpressEnabled(false);
-    }
-
-    @Override // View
-    protected void onFinishInflate() {
-
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
-            mSwipeDismissHandler.onTouch(this, ev);
-        }
-
-        return mSwipeDetector.onTouchEvent(ev);
-    }
-
-    /**
-     * Dismiss the view, with animation controlled by SwipeDismissHandler
-     */
-    public void dismiss() {
-        mSwipeDismissHandler.dismiss();
-    }
-
-    /**
-     * Set the callback to be run after view is dismissed (before animation; receives animator as
-     * input)
-     */
-    public void setOnDismissStartCallback(Consumer<Animator> callback) {
-        mOnDismissInitiated = callback;
-    }
-
-    /**
-     * Set the callback to be run after view is dismissed
-     */
-    public void setOnDismissEndCallback(Runnable callback) {
-        mOnDismissComplete = callback;
-    }
-
-    /**
-     * Set the callback to be run when the view is interacted with (e.g. tapped)
-     */
-    public void setOnInteractionCallback(Runnable callback) {
-        mOnInteraction = callback;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostView.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalHostView.java
deleted file mode 100644
index 6e2fcd1..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostView.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Container for communal presentation. Containing communal-related view to this parent view allows
- * for aggregate measurement/layout adjustments and capturing said values before the communal views
- * might be available.
- */
-public class CommunalHostView extends FrameLayout {
-    public CommunalHostView(@NonNull Context context) {
-        this(context, null, 0);
-    }
-
-    public CommunalHostView(@NonNull Context context,
-            @Nullable AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public CommunalHostView(@NonNull Context context, @Nullable AttributeSet attrs,
-            int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewController.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewController.java
deleted file mode 100644
index b428380..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewController.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.annotation.IntDef;
-import android.content.Context;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.keyguard.KeyguardVisibilityHelper;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.AnimatableProperty;
-import com.android.systemui.statusbar.notification.PropertyAnimator;
-import com.android.systemui.statusbar.notification.stack.AnimationProperties;
-import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
-import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.ViewController;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-
-/**
- * Injectable controller for {@link CommunalHostView}.
- */
-public class CommunalHostViewController extends ViewController<CommunalHostView> {
-    private static final String TAG = "CommunalController";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final String STATE_LIST_FORMAT = "[%s]";
-    private static final AnimationProperties COMMUNAL_ANIMATION_PROPERTIES =
-            new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
-
-    private final Executor mMainExecutor;
-    private final CommunalStateController mCommunalStateController;
-    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    private final KeyguardStateController mKeyguardStateController;
-    private final StatusBarStateController mStatusBarStateController;
-    private WeakReference<CommunalSource> mCurrentSource;
-    private Optional<ShowRequest> mLastRequest = Optional.empty();
-    private int mState;
-    private float mQsExpansion;
-    private float mShadeExpansion;
-
-    @Retention(RetentionPolicy.RUNTIME)
-    @IntDef({STATE_KEYGUARD_SHOWING, STATE_DOZING, STATE_BOUNCER_SHOWING, STATE_KEYGUARD_OCCLUDED})
-    public @interface State {}
-
-    private static final int STATE_KEYGUARD_SHOWING = 1 << 0;
-    private static final int STATE_DOZING = 1 << 1;
-    private static final int STATE_BOUNCER_SHOWING = 1 << 2;
-    private static final int STATE_KEYGUARD_OCCLUDED = 1 << 3;
-
-    // Only show communal view when keyguard is showing and not dozing.
-    private static final int SHOW_COMMUNAL_VIEW_REQUIRED_STATES = STATE_KEYGUARD_SHOWING;
-    private static final int SHOW_COMMUNAL_VIEW_INVALID_STATES =
-            STATE_DOZING | STATE_KEYGUARD_OCCLUDED;
-
-    private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
-
-    private ViewController<? extends View> mCommunalViewController;
-
-    private static class ShowRequest {
-        private boolean mShouldShow;
-        private WeakReference<CommunalSource> mSource;
-
-        ShowRequest(boolean shouldShow, WeakReference<CommunalSource> source) {
-            mShouldShow = shouldShow;
-            mSource = source;
-        }
-
-        CommunalSource getSource() {
-            return mSource != null ? mSource.get() : null;
-        }
-
-        boolean shouldShow() {
-            return mShouldShow;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof ShowRequest)) return false;
-            ShowRequest that = (ShowRequest) o;
-            return mShouldShow == that.mShouldShow && Objects.equals(getSource(), that.getSource());
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mShouldShow, mSource);
-        }
-    }
-
-    private KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
-            new KeyguardUpdateMonitorCallback() {
-                @Override
-                public void onKeyguardBouncerChanged(boolean bouncer) {
-                    if (DEBUG) {
-                        Log.d(TAG, "onKeyguardBouncerChanged:" + bouncer);
-                    }
-
-                    setState(STATE_BOUNCER_SHOWING, bouncer);
-                }
-
-                @Override
-                public void onKeyguardOccludedChanged(boolean occluded) {
-                    if (DEBUG) {
-                        Log.d(TAG, "onKeyguardOccludedChanged" + occluded);
-                    }
-
-                    setState(STATE_KEYGUARD_OCCLUDED, occluded);
-                }
-            };
-
-    private KeyguardStateController.Callback mKeyguardCallback =
-            new KeyguardStateController.Callback() {
-                @Override
-                public void onKeyguardShowingChanged() {
-                    final boolean isShowing = mKeyguardStateController.isShowing();
-                    if (DEBUG) {
-                        Log.d(TAG, "setKeyguardShowing:" + isShowing);
-                    }
-
-                    setState(STATE_KEYGUARD_SHOWING, isShowing);
-                }
-            };
-
-    private StatusBarStateController.StateListener mDozeCallback =
-            new StatusBarStateController.StateListener() {
-                @Override
-                public void onDozingChanged(boolean isDozing) {
-                    if (DEBUG) {
-                        Log.d(TAG, "setDozing:" + isDozing);
-                    }
-
-                    setState(STATE_DOZING, isDozing);
-                }
-
-                @Override
-                public void onStateChanged(int newState) {
-                    updateCommunalViewOccluded();
-                }
-            };
-
-    @Inject
-    protected CommunalHostViewController(@Main Executor mainExecutor,
-            CommunalStateController communalStateController,
-            KeyguardUpdateMonitor keyguardUpdateMonitor,
-            KeyguardStateController keyguardStateController,
-            DozeParameters dozeParameters,
-            ScreenOffAnimationController screenOffAnimationController,
-            StatusBarStateController statusBarStateController, CommunalHostView view) {
-        super(view);
-        mCommunalStateController = communalStateController;
-        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
-        mMainExecutor = mainExecutor;
-        mKeyguardStateController = keyguardStateController;
-        mStatusBarStateController = statusBarStateController;
-        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
-                keyguardStateController, dozeParameters, screenOffAnimationController,
-                /* animateYPos= */ false, /* visibleOnCommunal= */ true);
-    }
-
-    /**
-     * Set the visibility of the keyguard status view based on some new state.
-     */
-    public void setKeyguardStatusViewVisibility(
-            int statusBarState,
-            boolean keyguardFadingAway,
-            boolean goingToFullShade,
-            int oldStatusBarState) {
-        mKeyguardVisibilityHelper.setViewVisibility(
-                statusBarState, keyguardFadingAway, goingToFullShade, oldStatusBarState);
-    }
-
-    /**
-     * Set keyguard status view alpha.
-     */
-    public void setAlpha(float alpha) {
-        if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
-            mView.setAlpha(alpha);
-
-            // Some communal view implementations, such as SurfaceViews, do not behave correctly
-            // inheriting the alpha of their parent. Directly set child alpha here to work around
-            // this.
-            for (int i = mView.getChildCount() - 1; i >= 0; --i) {
-                mView.getChildAt(i).setAlpha(alpha);
-            }
-        }
-    }
-    @Override
-    public void onInit() {
-        setState(STATE_KEYGUARD_SHOWING, mKeyguardStateController.isShowing());
-        setState(STATE_DOZING, mStatusBarStateController.isDozing());
-    }
-
-    @Override
-    protected void onViewAttached() {
-        mKeyguardStateController.addCallback(mKeyguardCallback);
-        mStatusBarStateController.addCallback(mDozeCallback);
-        mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
-    }
-
-    @Override
-    protected void onViewDetached() {
-        mKeyguardStateController.removeCallback(mKeyguardCallback);
-        mStatusBarStateController.removeCallback(mDozeCallback);
-        mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback);
-    }
-
-    private void setState(@State int stateFlag, boolean enabled) {
-        final int existingState = mState;
-        if (DEBUG) {
-            Log.d(TAG, "setState flag:" + describeState(stateFlag) + " enabled:" + enabled);
-        }
-
-        if (enabled) {
-            mState |= stateFlag;
-        } else {
-            mState &= ~stateFlag;
-        }
-
-        if (DEBUG) {
-            Log.d(TAG, "updated state:" + describeState());
-        }
-
-        if (existingState != mState) {
-            showSource();
-        }
-
-        updateCommunalViewOccluded();
-    }
-
-    private String describeState(@State int stateFlag) {
-        switch(stateFlag) {
-            case STATE_DOZING:
-                return "dozing";
-            case STATE_BOUNCER_SHOWING:
-                return "bouncer_showing";
-            case STATE_KEYGUARD_SHOWING:
-                return "keyguard_showing";
-            default:
-                return "UNDEFINED_STATE";
-        }
-    }
-
-    private String describeState() {
-        StringBuilder stringBuilder = new StringBuilder();
-
-        if ((mState & STATE_KEYGUARD_SHOWING) == STATE_KEYGUARD_SHOWING) {
-            stringBuilder.append(String.format(STATE_LIST_FORMAT,
-                    describeState(STATE_KEYGUARD_SHOWING)));
-        }
-        if ((mState & STATE_DOZING) == STATE_DOZING) {
-            stringBuilder.append(String.format(STATE_LIST_FORMAT,
-                    describeState(STATE_DOZING)));
-        }
-        if ((mState & STATE_BOUNCER_SHOWING) == STATE_BOUNCER_SHOWING) {
-            stringBuilder.append(String.format(STATE_LIST_FORMAT,
-                    describeState(STATE_BOUNCER_SHOWING)));
-        }
-
-        return stringBuilder.toString();
-    }
-
-    private void showSource() {
-        final ShowRequest request = new ShowRequest(
-                (mState & SHOW_COMMUNAL_VIEW_REQUIRED_STATES) == SHOW_COMMUNAL_VIEW_REQUIRED_STATES
-                    && (mState & SHOW_COMMUNAL_VIEW_INVALID_STATES) == 0
-                    && mCurrentSource != null,
-                mCurrentSource);
-
-        if (mLastRequest.isPresent() && Objects.equals(mLastRequest.get(), request)) {
-            return;
-        }
-
-        mLastRequest = Optional.of(request);
-
-        // Make sure all necessary states are present for showing communal and all invalid states
-        // are absent
-        mMainExecutor.execute(() -> {
-            if (DEBUG) {
-                Log.d(TAG, "showSource. currentSource:" + request.getSource());
-            }
-
-            if (request.shouldShow()) {
-                mView.removeAllViews();
-
-                // Make view visible.
-                mView.setVisibility(View.VISIBLE);
-
-                final Context context = mView.getContext();
-
-                final ListenableFuture<CommunalSource.CommunalViewResult> listenableFuture =
-                        request.getSource().requestCommunalView(context);
-
-                if (listenableFuture == null) {
-                    Log.e(TAG, "could not request communal view");
-                    return;
-                }
-
-                listenableFuture.addListener(() -> {
-                    try {
-                        final CommunalSource.CommunalViewResult result = listenableFuture.get();
-                        result.view.setLayoutParams(new ViewGroup.LayoutParams(
-                                ViewGroup.LayoutParams.MATCH_PARENT,
-                                ViewGroup.LayoutParams.MATCH_PARENT));
-                        mView.addView(result.view);
-
-                        mCommunalViewController = result.viewController;
-                        mCommunalViewController.init();
-                    } catch (Exception e) {
-                        Log.e(TAG, "could not obtain communal view through callback:" + e);
-                    }
-                }, mMainExecutor);
-            } else {
-                mView.removeAllViews();
-                mView.setVisibility(View.INVISIBLE);
-                mCommunalStateController.setCommunalViewShowing(false);
-            }
-        });
-    }
-
-    /**
-     * Instructs {@link CommunalHostViewController} to display provided source.
-     *
-     * @param source The new {@link CommunalSource}, {@code null} if not set.
-     */
-    public void show(WeakReference<CommunalSource> source) {
-        mCurrentSource = source;
-        showSource();
-    }
-
-    /**
-     * Update position of the view with an optional animation
-     */
-    public void updatePosition(int y, boolean animate) {
-        PropertyAnimator.setProperty(mView, AnimatableProperty.Y, y, COMMUNAL_ANIMATION_PROPERTIES,
-                animate);
-    }
-
-    /**
-     * Invoked when the quick settings is expanded.
-     * @param expansionFraction the percentage the QS shade has been expanded.
-     */
-    public void updateQsExpansion(float expansionFraction) {
-        mQsExpansion = expansionFraction;
-        updateCommunalViewOccluded();
-    }
-
-    /**
-     * Invoked when the main shade is expanded.
-     * @param shadeExpansion the percentage the main shade has expanded.
-     */
-    public void updateShadeExpansion(float shadeExpansion) {
-        mShadeExpansion = shadeExpansion;
-        updateCommunalViewOccluded();
-    }
-
-    private void updateCommunalViewOccluded() {
-        final boolean bouncerShowing = (mState & STATE_BOUNCER_SHOWING) == STATE_BOUNCER_SHOWING;
-        final int statusBarState = mStatusBarStateController.getState();
-        final boolean shadeExpanded = statusBarState == StatusBarState.SHADE
-                || statusBarState == StatusBarState.SHADE_LOCKED;
-
-        mCommunalStateController.setCommunalViewOccluded(
-                bouncerShowing || shadeExpanded || mQsExpansion > 0.0f || mShadeExpansion > 0.0f);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithm.java
deleted file mode 100644
index 424da0b..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithm.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.util.Log;
-
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-
-/**
- * {@link CommunalHostViewPositionAlgorithm} calculates the position of the communal view given
- * input such as the notification panel position.
- */
-public class CommunalHostViewPositionAlgorithm {
-    private static final String TAG = "CommunalPositionAlg";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    /**
-     * @see NotificationPanelViewController#getExpandedFraction()
-     */
-    private float mPanelExpansion;
-
-    /**
-     * Height of {@link CommunalHostView}.
-     */
-    private int mCommunalHeight;
-
-    /**
-     * A data container for the result of the position algorithm.
-     */
-    public static class Result {
-        /**
-         * The y translation of the clock.
-         */
-        public int communalY;
-    }
-
-    /**
-     * Sets the conditions under which the result should be calculated from.
-     * @param panelExpansion The percentage the keyguard panel has been moved upwards.
-     * @param communalHeight The height of the communal panel.
-     */
-    public void setup(float panelExpansion, int communalHeight) {
-        if (DEBUG) {
-            Log.d(TAG, "setup. panelExpansion:" + panelExpansion);
-        }
-        mPanelExpansion = panelExpansion;
-        mCommunalHeight = communalHeight;
-    }
-
-    /**
-     * Calculates the position based on factors input through {link {@link #setup(float, int)}}.
-     * @param result The resulting calculations.
-     */
-    public void run(Result result) {
-        // The panel expansion relates to the keyguard expansion. At full expansion, the communal
-        // view should be aligned at the top (0). Otherwise, it should be shifted offscreen by the
-        // unexpanded amount.
-        result.communalY = (int) ((1 - mPanelExpansion) * -mCommunalHeight);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSource.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalSource.java
deleted file mode 100644
index 42ecd5c..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSource.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.content.Context;
-import android.view.View;
-
-import com.android.systemui.util.ViewController;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-import java.util.Optional;
-
-/**
- * {@link CommunalSource} defines an interface for working with a source for communal data. Clients
- * may request a communal surface that can be shown within a {@link android.view.SurfaceView}.
- * Callbacks may also be registered to listen to state changes.
- */
-public interface CommunalSource {
-    /**
-     * {@link Connector} defines an interface for {@link CommunalSource} instances to be generated.
-     */
-    interface Connector {
-        Connection connect(Connection.Callback callback);
-    }
-
-    /**
-     * {@link Connection} defines an interface for an entity which holds the necessary components
-     * for establishing and maintaining a connection to the communal source.
-     */
-    interface Connection {
-        /**
-         * {@link Callback} defines an interface for clients to be notified when a source is ready
-         */
-        interface Callback {
-            void onSourceEstablished(Optional<CommunalSource> source);
-            void onDisconnected();
-        }
-
-        void disconnect();
-    }
-
-    /**
-     * The {@link Observer} interface specifies an entity which {@link CommunalSource} listeners
-     * can be informed of changes to the source, which will require updating. Note that this deals
-     * with changes to the source itself, not content which will be updated through the
-     * {@link CommunalSource} interface.
-     */
-    interface Observer {
-        interface Callback {
-            void onSourceChanged();
-        }
-
-        void addCallback(Callback callback);
-        void removeCallback(Callback callback);
-    }
-
-    /**
-     * {@link CommunalViewResult} is handed back from {@link #requestCommunalView(Context)} and
-     * contains the view to be displayed and its associated controller.
-     */
-    class CommunalViewResult {
-        /**
-         * The resulting communal view.
-         */
-        public final View view;
-        /**
-         * The controller for the communal view.
-         */
-        public final ViewController<? extends View> viewController;
-
-        /**
-         * The default constructor for {@link CommunalViewResult}.
-         * @param view The communal view.
-         * @param viewController The communal view's controller.
-         */
-        public CommunalViewResult(View view, ViewController<? extends View> viewController) {
-            this.view = view;
-            this.viewController = viewController;
-        }
-    }
-
-    /**
-     * Requests a communal surface that can be displayed inside {@link CommunalHostView}.
-     *
-     * @param context The {@link View} {@link Context} to build the resulting view from
-     * @return A future that can be listened upon for the resulting {@link CommunalViewResult}. The
-     * value will be {@code null} in case of a failure.
-     */
-    ListenableFuture<CommunalViewResult> requestCommunalView(Context context);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSourceMonitor.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalSourceMonitor.java
deleted file mode 100644
index 58cf35f..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSourceMonitor.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static com.android.systemui.communal.dagger.CommunalModule.COMMUNAL_CONDITIONS;
-
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.util.condition.Monitor;
-
-import com.google.android.collect.Lists;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-/**
- * A Monitor for reporting a {@link CommunalSource} presence.
- */
-@SysUISingleton
-public class CommunalSourceMonitor {
-    private static final String TAG = "CommunalSourceMonitor";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    // A list of {@link Callback} that have registered to receive updates.
-    private final ArrayList<WeakReference<Callback>> mCallbacks = Lists.newArrayList();
-    private final Monitor mConditionsMonitor;
-    private final Executor mExecutor;
-
-    private CommunalSource mCurrentSource;
-
-    // Whether all conditions for communal mode to show have been met.
-    private boolean mAllCommunalConditionsMet = false;
-
-    // Whether the class is currently listening for condition changes.
-    private boolean mListeningForConditions = false;
-
-    private final Monitor.Callback mConditionsCallback =
-            allConditionsMet -> {
-                if (mAllCommunalConditionsMet != allConditionsMet) {
-                    if (DEBUG) Log.d(TAG, "communal conditions changed: " + allConditionsMet);
-
-                    mAllCommunalConditionsMet = allConditionsMet;
-                    executeOnSourceAvailableCallbacks();
-                }
-            };
-
-    @VisibleForTesting
-    @Inject
-    public CommunalSourceMonitor(@Main Executor executor,
-            @Named(COMMUNAL_CONDITIONS) Monitor communalConditionsMonitor) {
-        mExecutor = executor;
-        mConditionsMonitor = communalConditionsMonitor;
-    }
-
-    /**
-     * Sets the current {@link CommunalSource}, informing any callbacks. Any existing
-     * {@link CommunalSource} will be disconnected.
-     *
-     * @param source The new {@link CommunalSource}.
-     */
-    public void setSource(CommunalSource source) {
-        mCurrentSource = source;
-
-        if (mAllCommunalConditionsMet) {
-            executeOnSourceAvailableCallbacks();
-        }
-    }
-
-    private void executeOnSourceAvailableCallbacks() {
-        mExecutor.execute(() -> {
-            // If the new source is valid, inform registered Callbacks of its presence.
-            Iterator<WeakReference<Callback>> itr = mCallbacks.iterator();
-            while (itr.hasNext()) {
-                Callback cb = itr.next().get();
-                if (cb == null) {
-                    itr.remove();
-                } else {
-                    cb.onSourceAvailable(
-                            (mAllCommunalConditionsMet && mCurrentSource != null)
-                                    ? new WeakReference<>(mCurrentSource) : null);
-                }
-            }
-        });
-    }
-
-    /**
-     * Adds a {@link Callback} to receive {@link CommunalSource} updates.
-     *
-     * @param callback The {@link Callback} to add.
-     */
-    public void addCallback(Callback callback) {
-        mExecutor.execute(() -> {
-            mCallbacks.add(new WeakReference<>(callback));
-
-            // Inform the callback of any already present CommunalSource.
-            if (mAllCommunalConditionsMet && mCurrentSource != null) {
-                callback.onSourceAvailable(new WeakReference<>(mCurrentSource));
-            }
-
-            if (!mListeningForConditions) {
-                mConditionsMonitor.addCallback(mConditionsCallback);
-                mListeningForConditions = true;
-            }
-        });
-    }
-
-    /**
-     * Removes the specified {@link Callback} from receive future updates if present.
-     *
-     * @param callback The {@link Callback} to add.
-     */
-    public void removeCallback(Callback callback) {
-        mExecutor.execute(() -> {
-            mCallbacks.removeIf(el -> el.get() == callback);
-
-            if (mCallbacks.isEmpty() && mListeningForConditions) {
-                mConditionsMonitor.removeCallback(mConditionsCallback);
-                mListeningForConditions = false;
-            }
-        });
-    }
-
-    /**
-     * Interface implemented to be notified when new {@link CommunalSource} become available.
-     */
-    public interface Callback {
-        /**
-         * Called when a new {@link CommunalSource} has been registered. This will also be invoked
-         * when a {@link Callback} is first registered and a {@link CommunalSource} is already
-         * registered.
-         *
-         * @param source The new {@link CommunalSource}.
-         */
-        void onSourceAvailable(WeakReference<CommunalSource> source);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSourcePrimer.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalSourcePrimer.java
deleted file mode 100644
index f965431..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSourcePrimer.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.util.concurrency.DelayableExecutor;
-import com.android.systemui.util.time.SystemClock;
-
-import java.util.Optional;
-
-import javax.inject.Inject;
-
-/**
- * The {@link CommunalSourcePrimer} is responsible for priming SystemUI with a pre-configured
- * Communal source. The SystemUI service binds to the component to retrieve the
- * {@link CommunalSource}. {@link CommunalSourcePrimer} has no effect
- * if there is no pre-defined value.
- */
-@SysUISingleton
-public class CommunalSourcePrimer extends CoreStartable {
-    private static final String TAG = "CommunalSourcePrimer";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final SystemClock mSystemClock;
-    private final DelayableExecutor mMainExecutor;
-    private final CommunalSourceMonitor mMonitor;
-    private final int mBaseReconnectDelayMs;
-    private final int mMaxReconnectAttempts;
-    private final int mMinConnectionDuration;
-
-    private int mReconnectAttempts = 0;
-    private Runnable mCurrentReconnectCancelable;
-
-    private final Optional<CommunalSource.Observer> mObserver;
-    private final Optional<CommunalSource.Connector> mConnector;
-
-    private CommunalSource.Connection mCurrentConnection;
-
-    private final Runnable mConnectRunnable = new Runnable() {
-        @Override
-        public void run() {
-            mCurrentReconnectCancelable = null;
-            connect();
-        }
-    };
-
-    private final CommunalSource.Observer.Callback mObserverCallback = () -> {
-        initiateConnectionAttempt();
-    };
-
-    @Inject
-    public CommunalSourcePrimer(Context context, @Main Resources resources,
-            SystemClock clock,
-            DelayableExecutor mainExecutor,
-            CommunalSourceMonitor monitor,
-            Optional<CommunalSource.Connector> connector,
-            Optional<CommunalSource.Observer> observer) {
-        super(context);
-        mSystemClock = clock;
-        mMainExecutor = mainExecutor;
-        mMonitor = monitor;
-        mConnector = connector;
-        mObserver = observer;
-
-        mMaxReconnectAttempts = resources.getInteger(
-                R.integer.config_communalSourceMaxReconnectAttempts);
-        mBaseReconnectDelayMs = resources.getInteger(
-                R.integer.config_communalSourceReconnectBaseDelay);
-        mMinConnectionDuration = resources.getInteger(
-                R.integer.config_connectionMinDuration);
-    }
-
-    @Override
-    public void start() {
-    }
-
-    private void initiateConnectionAttempt() {
-        // Reset attempts
-        mReconnectAttempts = 0;
-        mMonitor.setSource(null);
-
-        // The first attempt is always a direct invocation rather than delayed.
-        connect();
-    }
-
-    private void scheduleConnectionAttempt() {
-        // always clear cancelable if present.
-        if (mCurrentReconnectCancelable != null) {
-            mCurrentReconnectCancelable.run();
-            mCurrentReconnectCancelable = null;
-        }
-
-        if (mReconnectAttempts >= mMaxReconnectAttempts) {
-            if (DEBUG) {
-                Log.d(TAG, "exceeded max connection attempts.");
-            }
-            return;
-        }
-
-        final long reconnectDelayMs =
-                (long) Math.scalb(mBaseReconnectDelayMs, mReconnectAttempts);
-
-        if (DEBUG) {
-            Log.d(TAG,
-                    "scheduling connection attempt in " + reconnectDelayMs + "milliseconds");
-        }
-
-        mCurrentReconnectCancelable = mMainExecutor.executeDelayed(mConnectRunnable,
-                reconnectDelayMs);
-
-        mReconnectAttempts++;
-    }
-
-    @Override
-    protected void onBootCompleted() {
-        if (mObserver.isPresent()) {
-            mObserver.get().addCallback(mObserverCallback);
-        }
-        initiateConnectionAttempt();
-    }
-
-    private void connect() {
-        if (DEBUG) {
-            Log.d(TAG, "attempting to connect to communal source");
-        }
-
-        if (mCurrentConnection != null) {
-            if (DEBUG) {
-                Log.d(TAG, "canceling in-flight connection");
-            }
-            mCurrentConnection.disconnect();
-        }
-
-        mCurrentConnection = mConnector.get().connect(new CommunalSource.Connection.Callback() {
-            private long mStartTime;
-
-            @Override
-            public void onSourceEstablished(Optional<CommunalSource> optionalSource) {
-                mStartTime = mSystemClock.currentTimeMillis();
-
-                if (optionalSource.isPresent()) {
-                    final CommunalSource source = optionalSource.get();
-                    mMonitor.setSource(source);
-                } else {
-                    scheduleConnectionAttempt();
-                }
-            }
-
-            @Override
-            public void onDisconnected() {
-                if (mSystemClock.currentTimeMillis() - mStartTime > mMinConnectionDuration) {
-                    initiateConnectionAttempt();
-                } else {
-                    scheduleConnectionAttempt();
-                }
-            }
-        });
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalStateController.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalStateController.java
deleted file mode 100644
index c72f542..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalStateController.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.statusbar.policy.CallbackController;
-
-import java.util.ArrayList;
-import java.util.Objects;
-
-import javax.inject.Inject;
-
-/**
- * CommunalStateController enables publishing and listening to communal-related state changes.
- */
-@SysUISingleton
-public class CommunalStateController implements
-        CallbackController<CommunalStateController.Callback> {
-    private final ArrayList<Callback> mCallbacks = new ArrayList<>();
-    private boolean mCommunalViewOccluded;
-    private boolean mCommunalViewShowing;
-
-    /**
-     * Callback for communal events.
-     */
-    public interface Callback {
-        /**
-         * Called when the visibility of the communal view changes.
-         */
-        default void onCommunalViewShowingChanged() {
-        }
-
-        /**
-         * Called when the occlusion of the communal view changes.
-         */
-        default void onCommunalViewOccludedChanged() {
-        }
-    }
-
-    @VisibleForTesting
-    @Inject
-    public CommunalStateController() {
-    }
-
-    /**
-     * Sets whether the communal view is showing.
-     * @param communalViewShowing {@code true} if the view is showing, {@code false} otherwise.
-     */
-    public void setCommunalViewShowing(boolean communalViewShowing) {
-        if (mCommunalViewShowing == communalViewShowing) {
-            return;
-        }
-
-        mCommunalViewShowing = communalViewShowing;
-
-        final ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks);
-        for (Callback callback : callbacks) {
-            callback.onCommunalViewShowingChanged();
-        }
-    }
-
-    /**
-     * Sets whether the communal view is occluded (but otherwise still showing).
-     * @param communalViewOccluded {@code true} if the view is occluded, {@code false} otherwise.
-     */
-    public void setCommunalViewOccluded(boolean communalViewOccluded) {
-        if (mCommunalViewOccluded == communalViewOccluded) {
-            return;
-        }
-
-        mCommunalViewOccluded = communalViewOccluded;
-
-        ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks);
-        for (int i = 0; i < callbacks.size(); i++) {
-            callbacks.get(i).onCommunalViewOccludedChanged();
-        }
-    }
-
-    /**
-     * Returns whether the communal view is showing.
-     * @return {@code true} if the view is showing, {@code false} otherwise.
-     */
-    public boolean getCommunalViewShowing() {
-        return mCommunalViewShowing;
-    }
-
-    /**
-     * Returns whether the communal view is occluded.
-     * @return {@code true} if the view is occluded, {@code false} otherwise.
-     */
-    public boolean getCommunalViewOccluded() {
-        return mCommunalViewOccluded;
-    }
-
-    @Override
-    public void addCallback(@NonNull Callback callback) {
-        Objects.requireNonNull(callback, "Callback must not be null. b/128895449");
-        if (!mCallbacks.contains(callback)) {
-            mCallbacks.add(callback);
-        }
-    }
-
-    @Override
-    public void removeCallback(@NonNull Callback callback) {
-        Objects.requireNonNull(callback, "Callback must not be null. b/128895449");
-        mCallbacks.remove(callback);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/PackageObserver.java b/packages/SystemUI/src/com/android/systemui/communal/PackageObserver.java
deleted file mode 100644
index 3d25d12..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/PackageObserver.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.PatternMatcher;
-import android.util.Log;
-
-import com.google.android.collect.Lists;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * {@link PackageObserver} allows for monitoring the system for changes relating to a particular
- * package. This can be used by {@link CommunalSource} clients to detect when a related package
- * has changed and reloading is necessary.
- */
-public class PackageObserver implements CommunalSource.Observer {
-    private static final String TAG = "PackageObserver";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final ArrayList<WeakReference<Callback>> mCallbacks = Lists.newArrayList();
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (DEBUG) {
-                Log.d(TAG, "package added receiver - onReceive");
-            }
-
-            final Iterator<WeakReference<Callback>> iter = mCallbacks.iterator();
-            while (iter.hasNext()) {
-                final Callback callback = iter.next().get();
-                if (callback != null) {
-                    callback.onSourceChanged();
-                } else {
-                    iter.remove();
-                }
-            }
-        }
-    };
-
-    private final String mPackageName;
-    private final Context mContext;
-
-    public PackageObserver(Context context, String packageName) {
-        mContext = context;
-        mPackageName = packageName;
-    }
-
-    @Override
-    public void addCallback(Callback callback) {
-        if (DEBUG) {
-            Log.d(TAG, "addCallback:" + callback);
-        }
-        mCallbacks.add(new WeakReference<>(callback));
-
-        // Only register for listening to package additions on first callback.
-        if (mCallbacks.size() > 1) {
-            return;
-        }
-
-        final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
-        filter.addDataScheme("package");
-        filter.addDataSchemeSpecificPart(mPackageName, PatternMatcher.PATTERN_LITERAL);
-        // Note that we directly register the receiver here as data schemes are not supported by
-        // BroadcastDispatcher.
-        mContext.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED);
-    }
-
-    @Override
-    public void removeCallback(Callback callback) {
-        if (DEBUG) {
-            Log.d(TAG, "removeCallback:" + callback);
-        }
-        final boolean removed = mCallbacks.removeIf(el -> el.get() == callback);
-
-        if (removed && mCallbacks.isEmpty()) {
-            mContext.unregisterReceiver(mReceiver);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/conditions/CommunalSettingCondition.java b/packages/SystemUI/src/com/android/systemui/communal/conditions/CommunalSettingCondition.java
deleted file mode 100644
index 25519d0..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/conditions/CommunalSettingCondition.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal.conditions;
-
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.annotation.MainThread;
-
-import com.android.systemui.util.condition.Condition;
-import com.android.systemui.util.settings.SecureSettings;
-
-import javax.inject.Inject;
-
-/**
- * Monitors the communal setting, and informs any listeners with updates.
- */
-public class CommunalSettingCondition extends Condition {
-    private final SecureSettings mSecureSettings;
-    private final ContentObserver mCommunalSettingContentObserver;
-
-    @Inject
-    public CommunalSettingCondition(@MainThread Handler mainHandler,
-            SecureSettings secureSettings) {
-        mSecureSettings = secureSettings;
-
-        mCommunalSettingContentObserver = new ContentObserver(mainHandler) {
-            @Override
-            public void onChange(boolean selfChange) {
-                final boolean communalSettingEnabled = mSecureSettings.getIntForUser(
-                        Settings.Secure.COMMUNAL_MODE_ENABLED, 0, UserHandle.USER_SYSTEM) == 1;
-                updateCondition(communalSettingEnabled);
-            }
-        };
-    }
-
-    @Override
-    protected void start() {
-        mSecureSettings.registerContentObserverForUser(Settings.Secure.COMMUNAL_MODE_ENABLED,
-                false /*notifyForDescendants*/, mCommunalSettingContentObserver,
-                UserHandle.USER_SYSTEM);
-
-        // Fetches setting immediately.
-        mCommunalSettingContentObserver.onChange(false);
-    }
-
-    @Override
-    protected void stop() {
-        mSecureSettings.unregisterContentObserver(mCommunalSettingContentObserver);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java
deleted file mode 100644
index 814b251..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal.dagger;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.res.Resources;
-import android.text.TextUtils;
-
-import androidx.annotation.Nullable;
-
-import com.android.systemui.R;
-import com.android.systemui.communal.CommunalSource;
-import com.android.systemui.communal.PackageObserver;
-import com.android.systemui.communal.conditions.CommunalSettingCondition;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.util.condition.Condition;
-import com.android.systemui.util.condition.Monitor;
-import com.android.systemui.util.condition.dagger.MonitorComponent;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-import javax.inject.Named;
-import javax.inject.Provider;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoMap;
-import dagger.multibindings.StringKey;
-
-/**
- * Dagger Module providing Communal-related functionality.
- */
-@Module(subcomponents = {
-        CommunalViewComponent.class,
-})
-public interface CommunalModule {
-    String COMMUNAL_CONDITIONS = "communal_conditions";
-
-    /** */
-    @Provides
-    static Optional<CommunalSource.Observer> provideCommunalSourcePackageObserver(
-            Context context, @Main Resources resources) {
-        final String componentName = resources.getString(R.string.config_communalSourceComponent);
-
-        if (TextUtils.isEmpty(componentName)) {
-            return Optional.empty();
-        }
-
-        return Optional.of(new PackageObserver(context,
-                ComponentName.unflattenFromString(componentName).getPackageName()));
-    }
-
-    /**
-     * Provides a set of conditions that need to be fulfilled in order for Communal Mode to display.
-     */
-    @Provides
-    @ElementsIntoSet
-    @Named(COMMUNAL_CONDITIONS)
-    static Set<Condition> provideCommunalConditions(
-            CommunalSettingCondition communalSettingCondition) {
-        return new HashSet<>(Collections.singletonList(communalSettingCondition));
-    }
-
-    /**
-     * TODO(b/205638389): Remove when there is a base implementation of
-     * {@link CommunalSource.Connector}. Currently a place holder to allow a map to be present.
-     */
-    @Provides
-    @IntoMap
-    @Nullable
-    @StringKey("empty")
-    static CommunalSource.Connector provideEmptyCommunalSourceConnector() {
-        return null;
-    }
-
-    /** */
-    @Provides
-    static Optional<CommunalSource.Connector> provideCommunalSourceConnector(
-            @Main Resources resources,
-            Map<Class<?>, Provider<CommunalSource.Connector>> connectorCreators) {
-        final String className = resources.getString(R.string.config_communalSourceConnector);
-
-        if (TextUtils.isEmpty(className)) {
-            return Optional.empty();
-        }
-
-        try {
-            Class<?> clazz = Class.forName(className);
-            Provider<CommunalSource.Connector> provider = connectorCreators.get(clazz);
-            return provider != null ? Optional.of(provider.get()) : Optional.empty();
-        } catch (ClassNotFoundException e) {
-            return Optional.empty();
-        }
-    }
-
-    /** */
-    @Provides
-    @Named(COMMUNAL_CONDITIONS)
-    static Monitor provideCommunalSourceMonitor(
-            @Named(COMMUNAL_CONDITIONS) Set<Condition> communalConditions,
-            MonitorComponent.Factory factory) {
-        final MonitorComponent component = factory.create(communalConditions, new HashSet<>());
-        return component.getMonitor();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalViewComponent.java b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalViewComponent.java
deleted file mode 100644
index 3a80a03..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalViewComponent.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal.dagger;
-
-import com.android.systemui.communal.CommunalHostView;
-import com.android.systemui.communal.CommunalHostViewController;
-
-import dagger.BindsInstance;
-import dagger.Subcomponent;
-
-/**
- * Subcomponent for working with {@link CommunalHostView}.
- */
-@Subcomponent
-public interface CommunalViewComponent {
-    /** Simple factory for {@link CommunalViewComponent}. */
-    @Subcomponent.Factory
-    interface Factory {
-        CommunalViewComponent build(@BindsInstance CommunalHostView view);
-    }
-
-    /** Builds a {@link CommunalHostViewController}. */
-    CommunalHostViewController getCommunalHostViewController();
-}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index 40662536..f9115b2 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -17,10 +17,13 @@
 package com.android.systemui.controls.management
 
 import android.content.ComponentName
+import android.content.res.Configuration
+import android.content.res.Resources
 import android.graphics.Rect
 import android.os.Bundle
 import android.service.controls.Control
 import android.service.controls.DeviceTypes
+import android.util.TypedValue
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
@@ -32,7 +35,6 @@
 import androidx.core.view.AccessibilityDelegateCompat
 import androidx.core.view.ViewCompat
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
-import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import com.android.systemui.R
 import com.android.systemui.controls.ControlInterface
@@ -56,11 +58,32 @@
         const val TYPE_ZONE = 0
         const val TYPE_CONTROL = 1
         const val TYPE_DIVIDER = 2
-    }
 
-    val spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
-        override fun getSpanSize(position: Int): Int {
-            return if (getItemViewType(position) != TYPE_CONTROL) 2 else 1
+        /**
+         * For low-dp width screens that also employ an increased font scale, adjust the
+         * number of columns. This helps prevent text truncation on these devices.
+         *
+         */
+        @JvmStatic
+        fun findMaxColumns(res: Resources): Int {
+            var maxColumns = res.getInteger(R.integer.controls_max_columns)
+            val maxColumnsAdjustWidth =
+                    res.getInteger(R.integer.controls_max_columns_adjust_below_width_dp)
+
+            val outValue = TypedValue()
+            res.getValue(R.dimen.controls_max_columns_adjust_above_font_scale, outValue, true)
+            val maxColumnsAdjustFontScale = outValue.getFloat()
+
+            val config = res.configuration
+            val isPortrait = config.orientation == Configuration.ORIENTATION_PORTRAIT
+            if (isPortrait &&
+                    config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED &&
+                    config.screenWidthDp <= maxColumnsAdjustWidth &&
+                    config.fontScale >= maxColumnsAdjustFontScale) {
+                maxColumns--
+            }
+
+            return maxColumns
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
index 6f94943..f611c3e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
@@ -195,10 +195,11 @@
         val margin = resources
                 .getDimensionPixelSize(R.dimen.controls_card_margin)
         val itemDecorator = MarginItemDecorator(margin, margin)
+        val spanCount = ControlAdapter.findMaxColumns(resources)
 
         recyclerView.apply {
             this.adapter = adapter
-            layoutManager = object : GridLayoutManager(recyclerView.context, 2) {
+            layoutManager = object : GridLayoutManager(recyclerView.context, spanCount) {
 
                 // This will remove from the announcement the row corresponding to the divider,
                 // as it's not something that should be announced.
@@ -210,7 +211,12 @@
                     return if (initial > 0) initial - 1 else initial
                 }
             }.apply {
-                spanSizeLookup = adapter.spanSizeLookup
+                spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
+                    override fun getSpanSize(position: Int): Int {
+                        return if (adapter?.getItemViewType(position)
+                                != ControlAdapter.TYPE_CONTROL) spanCount else 1
+                    }
+                }
             }
             addItemDecoration(itemDecorator)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt
index cb67454..747bcbe 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt
@@ -60,11 +60,17 @@
             val margin = itemView.context.resources
                 .getDimensionPixelSize(R.dimen.controls_card_margin)
             val itemDecorator = MarginItemDecorator(margin, margin)
+            val spanCount = ControlAdapter.findMaxColumns(itemView.resources)
 
             recyclerView.apply {
                 this.adapter = controlAdapter
-                layoutManager = GridLayoutManager(recyclerView.context, 2).apply {
-                    spanSizeLookup = controlAdapter.spanSizeLookup
+                layoutManager = GridLayoutManager(recyclerView.context, spanCount).apply {
+                    spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
+                        override fun getSpanSize(position: Int): Int {
+                            return if (adapter?.getItemViewType(position)
+                                    != ControlAdapter.TYPE_CONTROL) spanCount else 1
+                        }
+                    }
                 }
                 addItemDecoration(itemDecorator)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
index 5c1d8c3..e53f267 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
@@ -16,11 +16,11 @@
 
 package com.android.systemui.controls.ui
 
+import android.annotation.AnyThread
 import android.annotation.MainThread
 import android.app.Dialog
 import android.app.PendingIntent
 import android.content.Context
-import android.content.Intent
 import android.content.pm.PackageManager
 import android.content.pm.ResolveInfo
 import android.database.ContentObserver
@@ -35,6 +35,7 @@
 import android.util.Log
 import android.view.HapticFeedbackConstants
 import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.controls.ControlsMetricsLogger
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
@@ -53,6 +54,7 @@
     private val bgExecutor: DelayableExecutor,
     @Main private val uiExecutor: DelayableExecutor,
     private val activityStarter: ActivityStarter,
+    private val broadcastSender: BroadcastSender,
     private val keyguardStateController: KeyguardStateController,
     private val taskViewFactory: Optional<TaskViewFactory>,
     private val controlsMetricsLogger: ControlsMetricsLogger,
@@ -199,11 +201,12 @@
             false
         }
 
+    @AnyThread
     @VisibleForTesting
     fun bouncerOrRun(action: Action, authRequired: Boolean) {
         if (keyguardStateController.isShowing() && authRequired) {
             if (isLocked) {
-                context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
+                broadcastSender.closeSystemDialogs()
 
                 // pending actions will only run after the control state has been refreshed
                 pendingAction = action
@@ -233,7 +236,10 @@
                 // make sure the intent is valid before attempting to open the dialog
                 if (activities.isNotEmpty() && taskViewFactory.isPresent) {
                     taskViewFactory.get().create(context, uiExecutor, {
-                        dialog = DetailDialog(activityContext, it, pendingIntent, cvh).also {
+                        dialog = DetailDialog(
+                            activityContext, broadcastSender,
+                            it, pendingIntent, cvh
+                        ).also {
                             it.setOnDismissListener { _ -> dialog = null }
                             it.show()
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 59c291c..1268250 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -25,12 +25,10 @@
 import android.content.Context
 import android.content.Intent
 import android.content.SharedPreferences
-import android.content.res.Configuration
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.LayerDrawable
 import android.service.controls.Control
 import android.util.Log
-import android.util.TypedValue
 import android.view.ContextThemeWrapper
 import android.view.LayoutInflater
 import android.view.View
@@ -51,6 +49,7 @@
 import com.android.systemui.controls.controller.ControlInfo
 import com.android.systemui.controls.controller.ControlsController
 import com.android.systemui.controls.controller.StructureInfo
+import com.android.systemui.controls.management.ControlAdapter
 import com.android.systemui.controls.management.ControlsEditingActivity
 import com.android.systemui.controls.management.ControlsFavoritingActivity
 import com.android.systemui.controls.management.ControlsListingController
@@ -386,7 +385,7 @@
             visibility = View.VISIBLE
         }
 
-        val maxColumns = findMaxColumns()
+        val maxColumns = ControlAdapter.findMaxColumns(activityContext.resources)
 
         val listView = parent.requireViewById(R.id.global_actions_controls_list) as ViewGroup
         var lastRow: ViewGroup = createRow(inflater, listView)
@@ -432,32 +431,6 @@
         }
     }
 
-    /**
-     * For low-dp width screens that also employ an increased font scale, adjust the
-     * number of columns. This helps prevent text truncation on these devices.
-     */
-    private fun findMaxColumns(): Int {
-        val res = activityContext.resources
-        var maxColumns = res.getInteger(R.integer.controls_max_columns)
-        val maxColumnsAdjustWidth =
-            res.getInteger(R.integer.controls_max_columns_adjust_below_width_dp)
-
-        val outValue = TypedValue()
-        res.getValue(R.dimen.controls_max_columns_adjust_above_font_scale, outValue, true)
-        val maxColumnsAdjustFontScale = outValue.getFloat()
-
-        val config = res.configuration
-        val isPortrait = config.orientation == Configuration.ORIENTATION_PORTRAIT
-        if (isPortrait &&
-            config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED &&
-            config.screenWidthDp <= maxColumnsAdjustWidth &&
-            config.fontScale >= maxColumnsAdjustFontScale) {
-            maxColumns--
-        }
-
-        return maxColumns
-    }
-
     override fun getPreferredStructure(structures: List<StructureInfo>): StructureInfo {
         if (structures.isEmpty()) return EMPTY_STRUCTURE
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
index dc3d1b5..80589a2 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -33,6 +33,7 @@
 import android.widget.ImageView
 import com.android.internal.policy.ScreenDecorationsUtils
 import com.android.systemui.R
+import com.android.systemui.broadcast.BroadcastSender
 import com.android.wm.shell.TaskView
 
 /**
@@ -42,6 +43,7 @@
  */
 class DetailDialog(
     val activityContext: Context,
+    val broadcastSender: BroadcastSender,
     val taskView: TaskView,
     val pendingIntent: PendingIntent,
     val cvh: ControlViewHolder
@@ -147,7 +149,7 @@
                 // startActivity() below is called.
                 removeDetailTask()
                 dismiss()
-                context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
+                broadcastSender.closeSystemDialogs()
                 pendingIntent.send()
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
index 18f8519..620feec 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
@@ -23,10 +23,14 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.UiEventLoggerImpl;
 import com.android.systemui.dagger.qualifiers.TestHarness;
+import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.plugins.PluginsModule;
 import com.android.systemui.unfold.UnfoldTransitionModule;
 import com.android.systemui.util.concurrency.GlobalConcurrencyModule;
 
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
 import javax.inject.Singleton;
 
 import dagger.Module;
@@ -75,4 +79,16 @@
     static boolean provideIsTestHarness() {
         return ActivityManager.isRunningInUserTestHarness();
     }
+
+    /**
+     * Provide an Executor specifically for running UI operations on a separate thread.
+     *
+     * Keep submitted runnables short and to the point, just as with any other UI code.
+     */
+    @Provides
+    @Singleton
+    @UiBackground
+    public static Executor provideUiBackgroundExecutor() {
+        return Executors.newSingleThreadExecutor();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
index a3a45fe..4f55ba4 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
@@ -27,10 +27,7 @@
  * Root component for Dagger injection.
  */
 @Singleton
-@Component(modules = {
-        GlobalModule.class,
-        SysUISubcomponentModule.class,
-        WMModule.class})
+@Component(modules = {GlobalModule.class})
 public interface GlobalRootComponent {
 
     /**
@@ -45,12 +42,12 @@
     }
 
     /**
-     * Builder for a WMComponent.
+     * Builder for a {@link WMComponent}, which makes it a subcomponent of this class.
      */
     WMComponent.Builder getWMComponentBuilder();
 
     /**
-     * Builder for a SysUIComponent.
+     * Builder for a {@link SysUIComponent}, which makes it a subcomponent of this class.
      */
     SysUIComponent.Builder getSysUIComponent();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUISubcomponentModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUISubcomponentModule.java
deleted file mode 100644
index aacc693..0000000
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUISubcomponentModule.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dagger;
-
-import dagger.Module;
-
-/**
- * Dagger module for including the WMComponent.
- */
-@Module(subcomponents = {SysUIComponent.class})
-public abstract class SysUISubcomponentModule {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 2799301..166c265 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -32,7 +32,6 @@
 import com.android.systemui.biometrics.UdfpsHbmProvider;
 import com.android.systemui.biometrics.dagger.BiometricsModule;
 import com.android.systemui.classifier.FalsingModule;
-import com.android.systemui.communal.dagger.CommunalModule;
 import com.android.systemui.controls.dagger.ControlsModule;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.demomode.dagger.DemoModeModule;
@@ -49,6 +48,7 @@
 import com.android.systemui.recents.Recents;
 import com.android.systemui.screenshot.dagger.ScreenshotModule;
 import com.android.systemui.settings.dagger.SettingsModule;
+import com.android.systemui.smartspace.dagger.SmartspaceModule;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -66,8 +66,8 @@
 import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
 import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
 import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
-import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -106,7 +106,6 @@
             AssistModule.class,
             BiometricsModule.class,
             ClockModule.class,
-            CommunalModule.class,
             DreamModule.class,
             ControlsModule.class,
             DemoModeModule.class,
@@ -121,6 +120,7 @@
             SettingsModule.class,
             SettingsUtilModule.class,
             SmartRepliesInflationModule.class,
+            SmartspaceModule.class,
             StatusBarPolicyModule.class,
             StatusBarWindowModule.class,
             SysUIConcurrencyModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index b8b4092..dfb27ef 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -89,6 +89,7 @@
     private boolean mPaused = false;
     private boolean mScreenOff = false;
     private int mLastSensorValue = -1;
+    private DozeMachine.State mState = DozeMachine.State.UNINITIALIZED;
 
     /**
      * Debug value used for emulating various display brightness buckets:
@@ -135,6 +136,7 @@
 
     @Override
     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        mState = newState;
         switch (newState) {
             case INITIALIZED:
                 resetBrightnessToDefault();
@@ -262,8 +264,9 @@
      */
     private int clampToDimBrightnessForScreenOff(int brightness) {
         final boolean screenTurningOff =
-                mDozeParameters.shouldClampToDimBrightness()
-                        || mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_GOING_TO_SLEEP;
+                (mDozeParameters.shouldClampToDimBrightness()
+                        || mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_GOING_TO_SLEEP)
+                && mState == DozeMachine.State.INITIALIZED;
         if (screenTurningOff
                 && mWakefulnessLifecycle.getLastSleepReason() == GO_TO_SLEEP_REASON_TIMEOUT) {
             return Math.max(
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index 69f15e6..995df19 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -23,8 +23,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.complication.ComplicationHostViewController;
 import com.android.systemui.dreams.dagger.DreamOverlayComponent;
@@ -39,9 +37,6 @@
  */
 @DreamOverlayComponent.DreamOverlayScope
 public class DreamOverlayContainerViewController extends ViewController<DreamOverlayContainerView> {
-    // The height of the area at the top of the dream overlay to allow dragging down the
-    // notifications shade.
-    private final int mDreamOverlayNotificationsDragAreaHeight;
     private final DreamOverlayStatusBarViewController mStatusBarViewController;
 
     private final ComplicationHostViewController mComplicationHostViewController;
@@ -79,9 +74,6 @@
         super(containerView);
         mDreamOverlayContentView = contentView;
         mStatusBarViewController = statusBarViewController;
-        mDreamOverlayNotificationsDragAreaHeight =
-                mView.getResources().getDimensionPixelSize(
-                        R.dimen.dream_overlay_notifications_drag_area_height);
 
         mComplicationHostViewController = complicationHostViewController;
         final View view = mComplicationHostViewController.getView();
@@ -117,11 +109,6 @@
         return mView;
     }
 
-    @VisibleForTesting
-    int getDreamOverlayNotificationsDragAreaHeight() {
-        return mDreamOverlayNotificationsDragAreaHeight;
-    }
-
     private void updateBurnInOffsets() {
         int burnInOffset = mMaxBurnInOffset;
 
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index ebc7666..dfbb0c7 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -65,6 +65,9 @@
     // A reference to the {@link Window} used to hold the dream overlay.
     private Window mWindow;
 
+    // True if the service has been destroyed.
+    private boolean mDestroyed;
+
     private final Complication.Host mHost = new Complication.Host() {
         @Override
         public void requestExitDream() {
@@ -134,6 +137,7 @@
         mPreviewComplication.setDreamLabel(null);
         mStateController.removeComplication(mPreviewComplication);
         mStateController.setPreviewMode(false);
+        mDestroyed = true;
         super.onDestroy();
     }
 
@@ -141,6 +145,11 @@
     public void onStartDream(@NonNull WindowManager.LayoutParams layoutParams) {
         setCurrentState(Lifecycle.State.STARTED);
         mExecutor.execute(() -> {
+            if (mDestroyed) {
+                // The task could still be executed after the service has been destroyed. Bail if
+                // that is the case.
+                return;
+            }
             mStateController.setShouldShowComplications(shouldShowComplications());
             mStateController.setPreviewMode(isPreviewMode());
             if (isPreviewMode()) {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
index a5dcd39..a83e006 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
@@ -17,6 +17,7 @@
 package com.android.systemui.dreams;
 
 import android.content.Context;
+import android.os.Parcelable;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
@@ -25,7 +26,10 @@
 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.statusbar.lockscreen.LockscreenSmartspaceController;
+import com.android.systemui.dreams.smartspace.DreamsSmartspaceController;
+import com.android.systemui.plugins.BcSmartspaceDataPlugin;
+
+import java.util.List;
 
 import javax.inject.Inject;
 
@@ -39,10 +43,22 @@
      * SystemUI.
      */
     public static class Registrant extends CoreStartable {
-        private final LockscreenSmartspaceController mSmartSpaceController;
+        private final DreamsSmartspaceController mSmartSpaceController;
         private final DreamOverlayStateController mDreamOverlayStateController;
         private final SmartSpaceComplication mComplication;
 
+        private final BcSmartspaceDataPlugin.SmartspaceTargetListener mSmartspaceListener =
+                new BcSmartspaceDataPlugin.SmartspaceTargetListener() {
+            @Override
+            public void onSmartspaceTargetsUpdated(List<? extends Parcelable> targets) {
+                if (!targets.isEmpty()) {
+                    mDreamOverlayStateController.addComplication(mComplication);
+                } else {
+                    mDreamOverlayStateController.removeComplication(mComplication);
+                }
+            }
+        };
+
         /**
          * Default constructor for {@link SmartSpaceComplication}.
          */
@@ -50,7 +66,7 @@
         public Registrant(Context context,
                 DreamOverlayStateController dreamOverlayStateController,
                 SmartSpaceComplication smartSpaceComplication,
-                LockscreenSmartspaceController smartSpaceController) {
+                DreamsSmartspaceController smartSpaceController) {
             super(context);
             mDreamOverlayStateController = dreamOverlayStateController;
             mComplication = smartSpaceComplication;
@@ -59,32 +75,27 @@
 
         @Override
         public void start() {
-            addOrRemoveOverlay();
             mDreamOverlayStateController.addCallback(new DreamOverlayStateController.Callback() {
                 @Override
                 public void onStateChanged() {
-                    addOrRemoveOverlay();
+                    if (mDreamOverlayStateController.isOverlayActive()) {
+                        mSmartSpaceController.addListener(mSmartspaceListener);
+                    } else {
+                        mSmartSpaceController.removeListener(mSmartspaceListener);
+                    }
                 }
             });
         }
-
-        private void addOrRemoveOverlay() {
-            if (mDreamOverlayStateController.isPreviewMode()) {
-                mDreamOverlayStateController.removeComplication(mComplication);
-            } else if (mSmartSpaceController.isEnabled()) {
-                mDreamOverlayStateController.addComplication(mComplication);
-            }
-        }
     }
 
     private static class SmartSpaceComplicationViewHolder implements ViewHolder {
         private static final int SMARTSPACE_COMPLICATION_WEIGHT = 10;
-        private final LockscreenSmartspaceController mSmartSpaceController;
+        private final DreamsSmartspaceController mSmartSpaceController;
         private final Context mContext;
 
         protected SmartSpaceComplicationViewHolder(
                 Context context,
-                LockscreenSmartspaceController smartSpaceController) {
+                DreamsSmartspaceController smartSpaceController) {
             mSmartSpaceController = smartSpaceController;
             mContext = context;
         }
@@ -109,12 +120,12 @@
         }
     }
 
-    private final LockscreenSmartspaceController mSmartSpaceController;
+    private final DreamsSmartspaceController mSmartSpaceController;
     private final Context mContext;
 
     @Inject
     public SmartSpaceComplication(Context context,
-            LockscreenSmartspaceController smartSpaceController) {
+            DreamsSmartspaceController smartSpaceController) {
         mContext = context;
         mSmartSpaceController = smartSpaceController;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
index 62b319b..4e528bb 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
@@ -21,6 +21,7 @@
 
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.util.Log;
 import android.view.View;
 
 import androidx.constraintlayout.widget.ConstraintLayout;
@@ -42,6 +43,8 @@
  * a {@link ComplicationLayoutEngine}.
  */
 public class ComplicationHostViewController extends ViewController<ConstraintLayout> {
+    public static final String TAG = "ComplicationHostViewController";
+
     private final ComplicationLayoutEngine mLayoutEngine;
     private final LifecycleOwner mLifecycleOwner;
     private final ComplicationCollectionViewModel mComplicationCollectionViewModel;
@@ -113,6 +116,12 @@
                     final Complication.ViewHolder viewHolder = complication.getComplication()
                             .createView(complication);
                     mComplications.put(id, viewHolder);
+                    if (viewHolder.getView().getParent() != null) {
+                        Log.e(TAG, "View for complication "
+                                + complication.getComplication().getClass()
+                                + " already has a parent. Make sure not to reuse complication "
+                                + "views!");
+                    }
                     mLayoutEngine.addComplication(id, viewHolder.getView(),
                             viewHolder.getLayoutParams(), viewHolder.getCategory());
                 });
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index de5b4bb..c7b02cd 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -26,7 +26,7 @@
 import dagger.Provides;
 
 /**
- * Dagger Module providing Communal-related functionality.
+ * Dagger Module providing Dream-related functionality.
  */
 @Module(includes = {
             RegisteredComplicationsModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt
new file mode 100644
index 0000000..4e228a1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt
@@ -0,0 +1,219 @@
+/*
+ * 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.dreams.smartspace
+
+import android.app.smartspace.SmartspaceConfig
+import android.app.smartspace.SmartspaceManager
+import android.app.smartspace.SmartspaceSession
+import android.content.Context
+import android.graphics.Color
+import android.util.Log
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
+import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView
+import com.android.systemui.smartspace.SmartspacePrecondition
+import com.android.systemui.smartspace.SmartspaceTargetFilter
+import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_DATA_PLUGIN
+import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_PRECONDITION
+import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_TARGET_FILTER
+import com.android.systemui.smartspace.dagger.SmartspaceViewComponent
+import com.android.systemui.util.concurrency.Execution
+import java.lang.RuntimeException
+import java.util.Optional
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import javax.inject.Named
+
+/**
+ * Controller for managing the smartspace view on the dream
+ */
+@SysUISingleton
+class DreamsSmartspaceController @Inject constructor(
+    private val context: Context,
+    private val smartspaceManager: SmartspaceManager,
+    private val execution: Execution,
+    @Main private val uiExecutor: Executor,
+    private val smartspaceViewComponentFactory: SmartspaceViewComponent.Factory,
+    @Named(DREAM_SMARTSPACE_PRECONDITION) private val precondition: SmartspacePrecondition,
+    @Named(DREAM_SMARTSPACE_TARGET_FILTER)
+    private val optionalTargetFilter: Optional<SmartspaceTargetFilter>,
+    @Named(DREAM_SMARTSPACE_DATA_PLUGIN) optionalPlugin: Optional<BcSmartspaceDataPlugin>
+) {
+    companion object {
+        private const val TAG = "DreamsSmartspaceCtrlr"
+    }
+
+    private var session: SmartspaceSession? = null
+    private val plugin: BcSmartspaceDataPlugin? = optionalPlugin.orElse(null)
+    private var targetFilter: SmartspaceTargetFilter? = optionalTargetFilter.orElse(null)
+
+    // A shadow copy of listeners is maintained to track whether the session should remain open.
+    private var listeners = mutableSetOf<BcSmartspaceDataPlugin.SmartspaceTargetListener>()
+
+    // Smartspace can be used on multiple displays, such as when the user casts their screen
+    private var smartspaceViews = mutableSetOf<SmartspaceView>()
+
+    var preconditionListener = object : SmartspacePrecondition.Listener {
+        override fun onCriteriaChanged() {
+            reloadSmartspace()
+        }
+    }
+
+    init {
+        precondition.addListener(preconditionListener)
+    }
+
+    var filterListener = object : SmartspaceTargetFilter.Listener {
+        override fun onCriteriaChanged() {
+            reloadSmartspace()
+        }
+    }
+
+    init {
+        targetFilter?.addListener(filterListener)
+    }
+
+    var stateChangeListener = object : View.OnAttachStateChangeListener {
+        override fun onViewAttachedToWindow(v: View) {
+            val view = v as SmartspaceView
+            // Until there is dream color matching
+            view.setPrimaryTextColor(Color.WHITE)
+            smartspaceViews.add(view)
+            connectSession()
+        }
+
+        override fun onViewDetachedFromWindow(v: View) {
+            smartspaceViews.remove(v as SmartspaceView)
+
+            if (smartspaceViews.isEmpty()) {
+                disconnect()
+            }
+        }
+    }
+
+    private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets ->
+        execution.assertIsMainThread()
+
+        val filteredTargets = targets.filter { targetFilter?.filterSmartspaceTarget(it) ?: true }
+        plugin?.onTargetsAvailable(filteredTargets)
+    }
+
+    /**
+     * Constructs the smartspace view and connects it to the smartspace service.
+     */
+    fun buildAndConnectView(parent: ViewGroup): View? {
+        execution.assertIsMainThread()
+
+        if (!precondition.conditionsMet()) {
+            throw RuntimeException("Cannot build view when not enabled")
+        }
+
+        val view = buildView(parent)
+        connectSession()
+
+        return view
+    }
+
+    private fun buildView(parent: ViewGroup): View? {
+        return if (plugin != null) {
+            var view = smartspaceViewComponentFactory.create(parent, plugin, stateChangeListener)
+                    .getView()
+
+            if (view is View) {
+                return view
+            }
+
+            return null
+        } else {
+            null
+        }
+    }
+
+    private fun hasActiveSessionListeners(): Boolean {
+        return smartspaceViews.isNotEmpty() || listeners.isNotEmpty()
+    }
+
+    private fun connectSession() {
+        if (plugin == null || session != null || !hasActiveSessionListeners()) {
+            return
+        }
+
+        if (!precondition.conditionsMet()) {
+            return
+        }
+
+        // TODO(b/217559844): Replace with "dream" session when available.
+        val newSession = smartspaceManager.createSmartspaceSession(
+                SmartspaceConfig.Builder(context, "lockscreen").build())
+        Log.d(TAG, "Starting smartspace session for dream")
+        newSession.addOnTargetsAvailableListener(uiExecutor, sessionListener)
+        this.session = newSession
+
+        plugin.registerSmartspaceEventNotifier {
+                e -> session?.notifySmartspaceEvent(e)
+        }
+
+        reloadSmartspace()
+    }
+
+    /**
+     * Disconnects the smartspace view from the smartspace service and cleans up any resources.
+     */
+    private fun disconnect() {
+        if (hasActiveSessionListeners()) return
+
+        execution.assertIsMainThread()
+
+        if (session == null) {
+            return
+        }
+
+        session?.let {
+            it.removeOnTargetsAvailableListener(sessionListener)
+            it.close()
+        }
+
+        session = null
+
+        plugin?.registerSmartspaceEventNotifier(null)
+        plugin?.onTargetsAvailable(emptyList())
+        Log.d(TAG, "Ending smartspace session for dream")
+    }
+
+    fun addListener(listener: SmartspaceTargetListener) {
+        execution.assertIsMainThread()
+        plugin?.registerListener(listener)
+        listeners.add(listener)
+
+        connectSession()
+    }
+
+    fun removeListener(listener: SmartspaceTargetListener) {
+        execution.assertIsMainThread()
+        plugin?.unregisterListener(listener)
+        listeners.remove(listener)
+        disconnect()
+    }
+
+    private fun reloadSmartspace() {
+        session?.requestSmartspaceUpdate()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index bf689e3..61cfe92 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.flags;
 
+import com.android.internal.annotations.Keep;
 import com.android.systemui.R;
 
 import java.lang.reflect.Field;
@@ -144,7 +145,7 @@
     /***************************************/
     // 900 - media
     public static final BooleanFlag MEDIA_TAP_TO_TRANSFER = new BooleanFlag(900, true);
-    public static final BooleanFlag MEDIA_SESSION_ACTIONS = new BooleanFlag(901, true);
+    public static final BooleanFlag MEDIA_SESSION_ACTIONS = new BooleanFlag(901, false);
     public static final BooleanFlag MEDIA_SESSION_LAYOUT = new BooleanFlag(902, true);
     public static final BooleanFlag MEDIA_NEARBY_DEVICES = new BooleanFlag(903, true);
     public static final BooleanFlag MEDIA_MUTE_AWAIT = new BooleanFlag(904, true);
@@ -154,8 +155,9 @@
             new BooleanFlag(1000, true);
 
     // 1100 - windowing
+    @Keep
     public static final SysPropBooleanFlag WM_ENABLE_SHELL_TRANSITIONS =
-            new SysPropBooleanFlag(1100, "persist.debug.shell_transit", false);
+            new SysPropBooleanFlag(1100, "persist.wm.debug.shell_transit", false);
 
     // Pay no attention to the reflection behind the curtain.
     // ========================== Curtain ==========================
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index 7a278f7..af553c7 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -624,7 +624,9 @@
                     addIfShouldShowAction(tempActions, new LogoutAction());
                 }
             } else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) {
-                addIfShouldShowAction(tempActions, new EmergencyDialerAction());
+                if (shouldDisplayEmergency()) {
+                    addIfShouldShowAction(tempActions, new EmergencyDialerAction());
+                }
             } else {
                 Log.e(TAG, "Invalid global action key " + actionKey);
             }
@@ -704,6 +706,12 @@
     }
 
     @VisibleForTesting
+    boolean shouldDisplayEmergency() {
+        // Emergency calling requires a telephony radio.
+        return mHasTelephony;
+    }
+
+    @VisibleForTesting
     boolean shouldDisplayBugReport(UserInfo currentUser) {
         return mGlobalSettings.getInt(Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0
                 && (currentUser == null || currentUser.isPrimary());
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index c01d2c3..736e2e0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1706,14 +1706,6 @@
                 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
                 return;
             }
-
-            if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
-                if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
-                // Without this, settings is not enabled until the lock screen first appears
-                setShowingLocked(false);
-                hideLocked();
-                return;
-            }
         }
 
         if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 831a606..ffdd537 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -54,6 +54,7 @@
 import com.android.systemui.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.GhostedViewLaunchAnimatorController;
+import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.media.dialog.MediaOutputDialogFactory;
 import com.android.systemui.monet.ColorScheme;
@@ -104,10 +105,18 @@
             R.id.action4
     };
 
+    // Buttons to show in small player when using semantic actions
+    private static final List<Integer> SEMANTIC_ACTION_IDS = List.of(
+            R.id.actionPlayPause,
+            R.id.actionPrev,
+            R.id.actionNext
+    );
+
     private final SeekBarViewModel mSeekBarViewModel;
     private SeekBarObserver mSeekBarObserver;
     protected final Executor mBackgroundExecutor;
     private final ActivityStarter mActivityStarter;
+    private final BroadcastSender mBroadcastSender;
 
     private Context mContext;
     private MediaViewHolder mMediaViewHolder;
@@ -128,7 +137,6 @@
     private MediaCarouselController mMediaCarouselController;
     private final MediaOutputDialogFactory mMediaOutputDialogFactory;
     private final FalsingManager mFalsingManager;
-    private final MediaFlags mMediaFlags;
 
     // Used for swipe-to-dismiss logging.
     protected boolean mIsImpressed = false;
@@ -142,21 +150,22 @@
      */
     @Inject
     public MediaControlPanel(Context context, @Background Executor backgroundExecutor,
-            ActivityStarter activityStarter, MediaViewController mediaViewController,
-            SeekBarViewModel seekBarViewModel, Lazy<MediaDataManager> lazyMediaDataManager,
+            ActivityStarter activityStarter, BroadcastSender broadcastSender,
+            MediaViewController mediaViewController, SeekBarViewModel seekBarViewModel,
+            Lazy<MediaDataManager> lazyMediaDataManager,
             MediaOutputDialogFactory mediaOutputDialogFactory,
             MediaCarouselController mediaCarouselController,
-            FalsingManager falsingManager, MediaFlags mediaFlags, SystemClock systemClock) {
+            FalsingManager falsingManager, SystemClock systemClock) {
         mContext = context;
         mBackgroundExecutor = backgroundExecutor;
         mActivityStarter = activityStarter;
+        mBroadcastSender = broadcastSender;
         mSeekBarViewModel = seekBarViewModel;
         mMediaViewController = mediaViewController;
         mMediaDataManagerLazy = lazyMediaDataManager;
         mMediaOutputDialogFactory = mediaOutputDialogFactory;
         mMediaCarouselController = mediaCarouselController;
         mFalsingManager = falsingManager;
-        mMediaFlags = mediaFlags;
         mSystemClock = systemClock;
         loadDimens();
 
@@ -495,17 +504,16 @@
         List<MediaAction> actionIcons = data.getActions();
         List<Integer> actionsWhenCollapsed = data.getActionsToShowInCompact();
 
-        // If the session actions flag is enabled, but we're still using the regular layout, use
-        // the session actions anyways
-        if (mMediaFlags.areMediaSessionActionsEnabled() && data.getSemanticActions() != null) {
+        // If we got session actions, use those instead
+        if (data.getSemanticActions() != null) {
             MediaButton semanticActions = data.getSemanticActions();
 
             actionIcons = new ArrayList<MediaAction>();
-            actionIcons.add(semanticActions.getStartCustom());
+            actionIcons.add(semanticActions.getCustom0());
             actionIcons.add(semanticActions.getPrevOrCustom());
             actionIcons.add(semanticActions.getPlayOrPause());
             actionIcons.add(semanticActions.getNextOrCustom());
-            actionIcons.add(semanticActions.getEndCustom());
+            actionIcons.add(semanticActions.getCustom1());
 
             actionsWhenCollapsed = new ArrayList<Integer>();
             actionsWhenCollapsed.add(1);
@@ -562,6 +570,9 @@
 
     /** Bind elements specific to PlayerSessionViewHolder */
     private void bindSessionPlayer(@NonNull MediaData data, String key) {
+        ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
+        ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
+
         // Default colors
         int surfaceColor = mBackgroundColor;
         int accentPrimary = com.android.settingslib.Utils.getColorAttr(mContext,
@@ -575,25 +586,6 @@
         int textTertiary = com.android.settingslib.Utils.getColorAttr(mContext,
                 com.android.internal.R.attr.textColorTertiary).getDefaultColor();
 
-        // App icon - use launcher icon
-        ImageView appIconView = mMediaViewHolder.getAppIcon();
-        appIconView.clearColorFilter();
-        try {
-            Drawable icon = mContext.getPackageManager().getApplicationIcon(
-                    data.getPackageName());
-            appIconView.setImageDrawable(icon);
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.w(TAG, "Cannot find icon for package " + data.getPackageName(), e);
-            // Fall back to notification icon
-            if (data.getAppIcon() != null) {
-                appIconView.setImageIcon(data.getAppIcon());
-            } else {
-                appIconView.setImageResource(R.drawable.ic_music_note);
-            }
-            int color = mContext.getColor(R.color.material_dynamic_secondary10);
-            appIconView.setColorFilter(color);
-        }
-
         // Album art
         ColorScheme colorScheme = null;
         ImageView albumView = mMediaViewHolder.getAlbumView();
@@ -640,6 +632,25 @@
                 ColorStateList.valueOf(surfaceColor));
         mMediaViewHolder.getPlayer().setBackgroundTintList(bgColorList);
 
+        // App icon - use notification icon
+        ImageView appIconView = mMediaViewHolder.getAppIcon();
+        appIconView.clearColorFilter();
+        if (data.getAppIcon() != null && !data.getResumption()) {
+            appIconView.setImageIcon(data.getAppIcon());
+            appIconView.setColorFilter(accentPrimary);
+        } else {
+            // Resume players use launcher icon
+            appIconView.setColorFilter(getGrayscaleFilter());
+            try {
+                Drawable icon = mContext.getPackageManager().getApplicationIcon(
+                        data.getPackageName());
+                appIconView.setImageDrawable(icon);
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.w(TAG, "Cannot find icon for package " + data.getPackageName(), e);
+                appIconView.setImageResource(R.drawable.ic_music_note);
+            }
+        }
+
         // Metadata text
         mMediaViewHolder.getTitleText().setTextColor(textPrimary);
         mMediaViewHolder.getArtistText().setTextColor(textSecondary);
@@ -660,26 +671,68 @@
 
         // Media action buttons
         MediaButton semanticActions = data.getSemanticActions();
+        PlayerSessionViewHolder sessionHolder = (PlayerSessionViewHolder) mMediaViewHolder;
+        ImageButton[] genericButtons = new ImageButton[]{
+                sessionHolder.getAction0(),
+                sessionHolder.getAction1(),
+                sessionHolder.getAction2(),
+                sessionHolder.getAction3(),
+                sessionHolder.getAction4()};
+
+        ImageButton[] semanticButtons = new ImageButton[]{
+                sessionHolder.getActionPlayPause(),
+                sessionHolder.getActionNext(),
+                sessionHolder.getActionPrev()};
+
         if (semanticActions != null) {
-            PlayerSessionViewHolder sessionHolder = (PlayerSessionViewHolder) mMediaViewHolder;
+            // Hide all the generic buttons
+            for (ImageButton b: genericButtons) {
+                setVisibleAndAlpha(collapsedSet, b.getId(), false);
+                setVisibleAndAlpha(expandedSet, b.getId(), false);
+            }
 
             // Play/pause button has a background
             sessionHolder.getActionPlayPause().setBackgroundTintList(accentColorList);
             setSemanticButton(sessionHolder.getActionPlayPause(), semanticActions.getPlayOrPause(),
-                    ColorStateList.valueOf(textPrimaryInverse));
+                    ColorStateList.valueOf(textPrimaryInverse), collapsedSet, expandedSet, true);
 
             setSemanticButton(sessionHolder.getActionNext(), semanticActions.getNextOrCustom(),
-                    textColorList);
+                    textColorList, collapsedSet, expandedSet, true);
             setSemanticButton(sessionHolder.getActionPrev(), semanticActions.getPrevOrCustom(),
-                    textColorList);
-            setSemanticButton(sessionHolder.getActionStart(), semanticActions.getStartCustom(),
-                    textColorList);
-            setSemanticButton(sessionHolder.getActionEnd(), semanticActions.getEndCustom(),
-                    textColorList);
+                    textColorList, collapsedSet, expandedSet, true);
+            setSemanticButton(sessionHolder.getAction0(), semanticActions.getCustom0(),
+                    textColorList, collapsedSet, expandedSet, false);
+            setSemanticButton(sessionHolder.getAction1(), semanticActions.getCustom1(),
+                    textColorList, collapsedSet, expandedSet, false);
         } else {
-            Log.w(TAG, "Using semantic player, but did not get buttons");
+            // Hide all the semantic buttons
+            for (int id : SEMANTIC_ACTION_IDS) {
+                setVisibleAndAlpha(collapsedSet, id, false);
+                setVisibleAndAlpha(expandedSet, id, false);
+            }
+
+            // Set all the generic buttons
+            List<Integer> actionsWhenCollapsed = data.getActionsToShowInCompact();
+            List<MediaAction> actions = data.getActions();
+            int i = 0;
+            for (; i < actions.size(); i++) {
+                boolean showInCompact = actionsWhenCollapsed.contains(i);
+                setSemanticButton(genericButtons[i], actions.get(i), textColorList, collapsedSet,
+                        expandedSet, showInCompact);
+            }
+            for (; i < 5; i++) {
+                // Hide any unused buttons
+                setSemanticButton(genericButtons[i], null, textColorList, collapsedSet,
+                        expandedSet, false);
+            }
         }
 
+        // If disabled, set progress bar to INVISIBLE instead of GONE so layout weights still work
+        boolean seekbarEnabled = mSeekBarViewModel.getEnabled();
+        expandedSet.setVisibility(R.id.media_progress_bar,
+                seekbarEnabled ? ConstraintSet.VISIBLE : ConstraintSet.INVISIBLE);
+        expandedSet.setAlpha(R.id.media_progress_bar, seekbarEnabled ? 1.0f : 0.0f);
+
         // Long press buttons
         mMediaViewHolder.getLongPressText().setTextColor(textColorList);
         mMediaViewHolder.getSettingsText().setTextColor(textColorList);
@@ -688,11 +741,11 @@
         mMediaViewHolder.getCancelText().setBackgroundTintList(accentColorList);
         mMediaViewHolder.getDismissText().setTextColor(textColorList);
         mMediaViewHolder.getDismissText().setBackgroundTintList(accentColorList);
-
     }
 
     private void setSemanticButton(final ImageButton button, MediaAction mediaAction,
-            ColorStateList fgColor) {
+            ColorStateList fgColor, ConstraintSet collapsedSet, ConstraintSet expandedSet,
+            boolean showInCompact) {
         button.setImageTintList(fgColor);
         if (mediaAction != null) {
             button.setImageIcon(mediaAction.getIcon());
@@ -716,6 +769,9 @@
             button.setContentDescription(null);
             button.setEnabled(false);
         }
+
+        setVisibleAndAlpha(collapsedSet, button.getId(), mediaAction != null && showInCompact);
+        setVisibleAndAlpha(expandedSet, button.getId(), mediaAction != null);
     }
 
     @Nullable
@@ -899,7 +955,7 @@
                 // Dismiss the card Smartspace data through Smartspace trampoline activity.
                 mContext.startActivity(dismissIntent);
             } else {
-                mContext.sendBroadcast(dismissIntent);
+                mBroadcastSender.sendBroadcast(dismissIntent);
             }
         });
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
index 500e82e..4cf6291 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -149,11 +149,11 @@
     /**
      * First custom action space
      */
-    var startCustom: MediaAction? = null,
+    var custom0: MediaAction? = null,
     /**
-     * Last custom action space
+     * Second custom action space
      */
-    var endCustom: MediaAction? = null
+    var custom1: MediaAction? = null
 )
 
 /** State of a media action. */
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
index ae5c1f2..de44a9c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
@@ -21,6 +21,7 @@
 import android.util.Log
 import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.settings.CurrentUserTracker
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
@@ -56,6 +57,7 @@
 class MediaDataFilter @Inject constructor(
     private val context: Context,
     private val broadcastDispatcher: BroadcastDispatcher,
+    private val broadcastSender: BroadcastSender,
     private val lockscreenUserManager: NotificationLockscreenUserManager,
     @Main private val executor: Executor,
     private val systemClock: SystemClock
@@ -249,7 +251,7 @@
                 // Dismiss the card Smartspace data through Smartspace trampoline activity.
                 context.startActivity(dismissIntent)
             } else {
-                context.sendBroadcast(dismissIntent)
+                broadcastSender.sendBroadcast(dismissIntent)
             }
             smartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA.copy(
                 targetId = smartspaceMediaData.targetId, isValid = smartspaceMediaData.isValid)
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index fab06c2..ea92abd 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -610,7 +610,8 @@
         var actionIcons: List<MediaAction> = emptyList()
         var actionsToShowCollapsed: List<Int> = emptyList()
         var semanticActions: MediaButton? = null
-        if (mediaFlags.areMediaSessionActionsEnabled() && mediaController.playbackState != null) {
+        if (mediaFlags.areMediaSessionActionsEnabled(sbn.packageName, sbn.user.identifier) &&
+                mediaController.playbackState != null) {
             semanticActions = createActionsFromState(sbn.packageName, mediaController)
         } else {
             val actions = createActionsFromNotification(sbn)
@@ -726,7 +727,7 @@
                 }
             }
 
-            // Finally, assign the remaining button slots: C A play/pause B D
+            // Finally, assign the remaining button slots: play/pause A B C D
             // A = previous, else custom action (if not reserved)
             // B = next, else custom action (if not reserved)
             // C and D are always custom actions
@@ -752,8 +753,8 @@
                 null
             }
 
-            actions.startCustom = customActions[customIdx++]
-            actions.endCustom = customActions[customIdx++]
+            actions.custom0 = customActions[customIdx++]
+            actions.custom1 = customActions[customIdx++]
         }
         return actions
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt
index dd35a9a..f5200f9 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.media
 
+import android.app.StatusBarManager
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
@@ -26,16 +27,17 @@
     /**
      * Check whether media control actions should be based on PlaybackState instead of notification
      */
-    fun areMediaSessionActionsEnabled(): Boolean {
-        return featureFlags.isEnabled(Flags.MEDIA_SESSION_ACTIONS)
+    fun areMediaSessionActionsEnabled(packageName: String, userId: Int): Boolean {
+        val enabled = StatusBarManager.useMediaSessionActionsForApp(packageName, userId)
+        // Allow global override with flag
+        return enabled || featureFlags.isEnabled(Flags.MEDIA_SESSION_ACTIONS)
     }
 
     /**
      * Check whether media controls should use the new session-based layout
      */
     fun useMediaSessionLayout(): Boolean {
-        return featureFlags.isEnabled(Flags.MEDIA_SESSION_ACTIONS) &&
-            featureFlags.isEnabled(Flags.MEDIA_SESSION_LAYOUT)
+        return featureFlags.isEnabled(Flags.MEDIA_SESSION_LAYOUT)
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index 18b6699..7a4dee2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -292,6 +292,18 @@
     }
 
     /**
+     * Returns the amount of translationY of the media container, during the current guided
+     * transformation, if running. If there is no guided transformation running, it will return 0.
+     */
+    fun getGuidedTransformationTranslationY(): Int {
+        if (!isCurrentlyInGuidedTransformation()) {
+            return -1
+        }
+        val startHost = getHost(previousLocation) ?: return 0
+        return targetBounds.top - startHost.currentBounds.top
+    }
+
+    /**
      * Is the shade currently collapsing from the expanded qs? If we're on the lockscreen and in qs,
      * we wouldn't want to transition in that case.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
index 0a4b68b..eb209f7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
@@ -192,6 +192,14 @@
                 }
             }
 
+        override var squishFraction: Float = 1.0f
+            set(value) {
+                if (!value.equals(field)) {
+                    field = value
+                    changedListener?.invoke()
+                }
+            }
+
         override var showsOnlyActiveMedia: Boolean = false
             set(value) {
                 if (!value.equals(field)) {
@@ -242,6 +250,7 @@
         override fun copy(): MediaHostState {
             val mediaHostState = MediaHostStateHolder()
             mediaHostState.expansion = expansion
+            mediaHostState.squishFraction = squishFraction
             mediaHostState.showsOnlyActiveMedia = showsOnlyActiveMedia
             mediaHostState.measurementInput = measurementInput?.copy()
             mediaHostState.visible = visible
@@ -260,6 +269,9 @@
             if (expansion != other.expansion) {
                 return false
             }
+            if (squishFraction != other.squishFraction) {
+                return false
+            }
             if (showsOnlyActiveMedia != other.showsOnlyActiveMedia) {
                 return false
             }
@@ -278,6 +290,7 @@
         override fun hashCode(): Int {
             var result = measurementInput?.hashCode() ?: 0
             result = 31 * result + expansion.hashCode()
+            result = 31 * result + squishFraction.hashCode()
             result = 31 * result + falsingProtectionNeeded.hashCode()
             result = 31 * result + showsOnlyActiveMedia.hashCode()
             result = 31 * result + if (visible) 1 else 2
@@ -318,6 +331,11 @@
     var expansion: Float
 
     /**
+     * Fraction of the height animation.
+     */
+    var squishFraction: Float
+
+    /**
      * Is this host only showing active media or is it showing all of them including resumption?
      */
     var showsOnlyActiveMedia: Boolean
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index 77873e8..3860409 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -54,7 +54,7 @@
     private int mUid;
     private IMediaProjectionManager mService;
 
-    private SystemUIDialog mDialog;
+    private AlertDialog mDialog;
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -141,13 +141,18 @@
             dialogTitle = getString(R.string.media_projection_dialog_title, appName);
         }
 
-        mDialog = new SystemUIDialog(this);
-        mDialog.setTitle(dialogTitle);
-        mDialog.setIcon(R.drawable.ic_media_projection_permission);
-        mDialog.setMessage(dialogText);
-        mDialog.setPositiveButton(R.string.media_projection_action_text, this);
-        mDialog.setNeutralButton(android.R.string.cancel, this);
-        mDialog.setOnCancelListener(this);
+        mDialog = new AlertDialog.Builder(this, R.style.Theme_SystemUI_Dialog)
+                .setTitle(dialogTitle)
+                .setIcon(R.drawable.ic_media_projection_permission)
+                .setMessage(dialogText)
+                .setPositiveButton(R.string.media_projection_action_text, this)
+                .setNeutralButton(android.R.string.cancel, this)
+                .setOnCancelListener(this)
+                .create();
+
+        SystemUIDialog.registerDismissListener(mDialog);
+        SystemUIDialog.applyFlags(mDialog);
+        SystemUIDialog.setDialogSize(mDialog);
 
         mDialog.create();
         mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setFilterTouchesWhenObscured(true);
@@ -186,7 +191,7 @@
     private Intent getMediaProjectionIntent(int uid, String packageName)
             throws RemoteException {
         IMediaProjection projection = mService.createProjection(uid, packageName,
-                 MediaProjectionManager.TYPE_SCREEN_CAPTURE, false /* permanentGrant */);
+                MediaProjectionManager.TYPE_SCREEN_CAPTURE, false /* permanentGrant */);
         Intent intent = new Intent();
         intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, projection.asBinder());
         return intent;
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
index 591aad1..a60016b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
@@ -18,13 +18,11 @@
 
 import android.content.Context
 import android.content.res.Configuration
+import androidx.annotation.VisibleForTesting
 import androidx.constraintlayout.widget.ConstraintSet
 import com.android.systemui.R
 import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.util.animation.MeasurementOutput
-import com.android.systemui.util.animation.TransitionLayout
-import com.android.systemui.util.animation.TransitionLayoutController
-import com.android.systemui.util.animation.TransitionViewState
+import com.android.systemui.util.animation.*
 import javax.inject.Inject
 
 /**
@@ -270,7 +268,6 @@
             TYPE.PLAYER_SESSION -> PlayerSessionViewHolder.gutsIds
             TYPE.RECOMMENDATION -> RecommendationViewHolder.gutsIds
         }
-
         controlsIds.forEach { id ->
             viewState.widgetStates.get(id)?.let { state ->
                 // Make sure to use the unmodified state if guts are not visible.
@@ -282,59 +279,79 @@
             viewState.widgetStates.get(id)?.alpha = if (isGutsVisible) 1f else 0f
             viewState.widgetStates.get(id)?.gone = !isGutsVisible
         }
-
         if (shouldHideGutsSettings) {
             viewState.widgetStates.get(R.id.settings)?.gone = true
         }
     }
 
     /**
+     * Apply squishFraction to a copy of viewState such that the cached version is untouched.
+     */
+    private fun squishViewState(viewState: TransitionViewState,
+                                squishFraction: Float): TransitionViewState {
+        val squishedViewState = viewState.copy()
+        squishedViewState.height = (squishedViewState.height * squishFraction).toInt()
+        val albumArtViewState = viewState.widgetStates.get(R.id.album_art)
+        if (albumArtViewState != null) {
+            albumArtViewState.height = squishedViewState.height
+        }
+        return squishedViewState;
+    }
+
+    /**
      * Obtain a new viewState for a given media state. This usually returns a cached state, but if
      * it's not available, it will recreate one by measuring, which may be expensive.
      */
-    private fun obtainViewState(state: MediaHostState?): TransitionViewState? {
+    @VisibleForTesting
+    public fun obtainViewState(state: MediaHostState?): TransitionViewState? {
         if (state == null || state.measurementInput == null) {
             return null
         }
         // Only a subset of the state is relevant to get a valid viewState. Let's get the cachekey
         var cacheKey = getKey(state, isGutsVisible, tmpKey)
         val viewState = viewStates[cacheKey]
+
         if (viewState != null) {
             // we already have cached this measurement, let's continue
+            if (state.squishFraction < 1f) {
+                return squishViewState(viewState, state.squishFraction);
+            }
             return viewState
         }
         // Copy the key since this might call recursively into it and we're using tmpKey
         cacheKey = cacheKey.copy()
         val result: TransitionViewState?
-        if (transitionLayout != null) {
-            // Let's create a new measurement
-            if (state.expansion == 0.0f || state.expansion == 1.0f) {
-                result = transitionLayout!!.calculateViewState(
-                        state.measurementInput!!,
-                        constraintSetForExpansion(state.expansion),
-                        TransitionViewState())
-
-                setGutsViewState(result)
-                // We don't want to cache interpolated or null states as this could quickly fill up
-                // our cache. We only cache the start and the end states since the interpolation
-                // is cheap
-                viewStates[cacheKey] = result
-            } else {
-                // This is an interpolated state
-                val startState = state.copy().also { it.expansion = 0.0f }
-
-                // Given that we have a measurement and a view, let's get (guaranteed) viewstates
-                // from the start and end state and interpolate them
-                val startViewState = obtainViewState(startState) as TransitionViewState
-                val endState = state.copy().also { it.expansion = 1.0f }
-                val endViewState = obtainViewState(endState) as TransitionViewState
-                result = layoutController.getInterpolatedState(
-                        startViewState,
-                        endViewState,
-                        state.expansion)
-            }
+        if (transitionLayout == null) {
+            return null
+        }
+        // Not cached. Let's create a new measurement
+        if (state.expansion == 0.0f || state.expansion == 1.0f) {
+            result = transitionLayout!!.calculateViewState(
+                    state.measurementInput!!,
+                    constraintSetForExpansion(state.expansion),
+                    TransitionViewState())
+            // We don't want to cache interpolated or null states as this could quickly fill up
+            // our cache. We only cache the start and the end states since the interpolation
+            // is cheap
+            setGutsViewState(result)
+            viewStates[cacheKey] = result
         } else {
-            result = null
+            // This is an interpolated state
+            val startState = state.copy().also { it.expansion = 0.0f }
+
+            // Given that we have a measurement and a view, let's get (guaranteed) viewstates
+            // from the start and end state and interpolate them
+            val startViewState = obtainViewState(startState) as TransitionViewState
+            val endState = state.copy().also { it.expansion = 1.0f }
+
+            val endViewState = obtainViewState(endState) as TransitionViewState
+            result = layoutController.getInterpolatedState(
+                    startViewState,
+                    endViewState,
+                    state.expansion)
+        }
+        if (state.squishFraction < 1f) {
+            return squishViewState(result, state.squishFraction);
         }
         return result
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
index e57b247..5f60696 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
@@ -60,12 +60,24 @@
     val settings = itemView.requireViewById<View>(R.id.settings)
     val settingsText = itemView.requireViewById<TextView>(R.id.settings_text)
 
+    // Action Buttons
+    val action0 = itemView.requireViewById<ImageButton>(R.id.action0)
+    val action1 = itemView.requireViewById<ImageButton>(R.id.action1)
+    val action2 = itemView.requireViewById<ImageButton>(R.id.action2)
+    val action3 = itemView.requireViewById<ImageButton>(R.id.action3)
+    val action4 = itemView.requireViewById<ImageButton>(R.id.action4)
+
     init {
         (player.background as IlluminationDrawable).let {
             it.registerLightSource(seamless)
             it.registerLightSource(cancel)
             it.registerLightSource(dismiss)
             it.registerLightSource(settings)
+            it.registerLightSource(action0)
+            it.registerLightSource(action1)
+            it.registerLightSource(action2)
+            it.registerLightSource(action3)
+            it.registerLightSource(action4)
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/PlayerSessionViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/PlayerSessionViewHolder.kt
index 87d2cff..6928ebb 100644
--- a/packages/SystemUI/src/com/android/systemui/media/PlayerSessionViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/PlayerSessionViewHolder.kt
@@ -31,16 +31,12 @@
     val actionPlayPause = itemView.requireViewById<ImageButton>(R.id.actionPlayPause)
     val actionNext = itemView.requireViewById<ImageButton>(R.id.actionNext)
     val actionPrev = itemView.requireViewById<ImageButton>(R.id.actionPrev)
-    val actionStart = itemView.requireViewById<ImageButton>(R.id.actionStart)
-    val actionEnd = itemView.requireViewById<ImageButton>(R.id.actionEnd)
 
     init {
         (player.background as IlluminationDrawable).let {
             it.registerLightSource(actionPlayPause)
             it.registerLightSource(actionNext)
             it.registerLightSource(actionPrev)
-            it.registerLightSource(actionStart)
-            it.registerLightSource(actionEnd)
         }
     }
 
@@ -49,8 +45,11 @@
             R.id.actionPlayPause -> actionPlayPause
             R.id.actionNext -> actionNext
             R.id.actionPrev -> actionPrev
-            R.id.actionStart -> actionStart
-            R.id.actionEnd -> actionEnd
+            R.id.action0 -> action0
+            R.id.action1 -> action1
+            R.id.action2 -> action2
+            R.id.action3 -> action3
+            R.id.action4 -> action4
             else -> {
                 throw IllegalArgumentException()
             }
@@ -90,8 +89,11 @@
                 R.id.actionPlayPause,
                 R.id.actionNext,
                 R.id.actionPrev,
-                R.id.actionStart,
-                R.id.actionEnd,
+                R.id.action0,
+                R.id.action1,
+                R.id.action2,
+                R.id.action3,
+                R.id.action4,
                 R.id.icon
         )
         val gutsIds = setOf(
diff --git a/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt
index 20b2d4a..dd3fa89 100644
--- a/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt
@@ -33,23 +33,6 @@
     override val elapsedTimeView = itemView.requireViewById<TextView>(R.id.media_elapsed_time)
     override val totalTimeView = itemView.requireViewById<TextView>(R.id.media_total_time)
 
-    // Action Buttons
-    val action0 = itemView.requireViewById<ImageButton>(R.id.action0)
-    val action1 = itemView.requireViewById<ImageButton>(R.id.action1)
-    val action2 = itemView.requireViewById<ImageButton>(R.id.action2)
-    val action3 = itemView.requireViewById<ImageButton>(R.id.action3)
-    val action4 = itemView.requireViewById<ImageButton>(R.id.action4)
-
-    init {
-        (player.background as IlluminationDrawable).let {
-            it.registerLightSource(action0)
-            it.registerLightSource(action1)
-            it.registerLightSource(action2)
-            it.registerLightSource(action3)
-            it.registerLightSource(action4)
-        }
-    }
-
     override fun getAction(id: Int): ImageButton {
         return when (id) {
             R.id.action0 -> action0
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
index cf997055..57701ab 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
@@ -50,25 +50,46 @@
                 .getDimensionPixelSize(R.dimen.qs_media_disabled_seekbar_vertical_padding)
     }
 
+    init {
+        val seekBarProgressWavelength = holder.seekBar.context.resources
+                .getDimensionPixelSize(R.dimen.qs_media_seekbar_progress_wavelength).toFloat()
+        val seekBarProgressAmplitude = holder.seekBar.context.resources
+                .getDimensionPixelSize(R.dimen.qs_media_seekbar_progress_amplitude).toFloat()
+        val seekBarProgressPhase = holder.seekBar.context.resources
+                .getDimensionPixelSize(R.dimen.qs_media_seekbar_progress_phase).toFloat()
+        val seekBarProgressStrokeWidth = holder.seekBar.context.resources
+                .getDimensionPixelSize(R.dimen.qs_media_seekbar_progress_stroke_width).toFloat()
+        val progressDrawable = holder.seekBar.progressDrawable as? SquigglyProgress
+        progressDrawable?.let {
+            it.waveLength = seekBarProgressWavelength
+            it.lineAmplitude = seekBarProgressAmplitude
+            it.phaseSpeed = seekBarProgressPhase
+            it.strokeWidth = seekBarProgressStrokeWidth
+        }
+    }
+
     /** Updates seek bar views when the data model changes. */
     @UiThread
     override fun onChanged(data: SeekBarViewModel.Progress) {
+        val progressDrawable = holder.seekBar.progressDrawable as? SquigglyProgress
         if (!data.enabled) {
             if (holder.seekBar.maxHeight != seekBarDisabledHeight) {
                 holder.seekBar.maxHeight = seekBarDisabledHeight
                 setVerticalPadding(seekBarDisabledVerticalPadding)
             }
-            holder.seekBar.setEnabled(false)
-            holder.seekBar.getThumb().setAlpha(0)
-            holder.seekBar.setProgress(0)
-            holder.elapsedTimeView?.setText("")
-            holder.totalTimeView?.setText("")
+            holder.seekBar.isEnabled = false
+            progressDrawable?.animate = false
+            holder.seekBar.thumb.alpha = 0
+            holder.seekBar.progress = 0
+            holder.elapsedTimeView?.text = ""
+            holder.totalTimeView?.text = ""
             holder.seekBar.contentDescription = ""
             return
         }
 
-        holder.seekBar.getThumb().setAlpha(if (data.seekAvailable) 255 else 0)
-        holder.seekBar.setEnabled(data.seekAvailable)
+        holder.seekBar.thumb.alpha = if (data.seekAvailable) 255 else 0
+        holder.seekBar.isEnabled = data.seekAvailable
+        progressDrawable?.animate = data.playing
 
         if (holder.seekBar.maxHeight != seekBarEnabledMaxHeight) {
             holder.seekBar.maxHeight = seekBarEnabledMaxHeight
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
index 9cf9c48..49cd161 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
@@ -31,6 +31,7 @@
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.statusbar.NotificationMediaManager
 import com.android.systemui.util.concurrency.RepeatableExecutor
 import javax.inject.Inject
 
@@ -73,7 +74,7 @@
 class SeekBarViewModel @Inject constructor(
     @Background private val bgExecutor: RepeatableExecutor
 ) {
-    private var _data = Progress(false, false, null, 0)
+    private var _data = Progress(false, false, false, null, 0)
         set(value) {
             field = value
             _progress.postValue(value)
@@ -131,6 +132,8 @@
 
     lateinit var logSmartspaceClick: () -> Unit
 
+    fun getEnabled() = _data.enabled
+
     /**
      * Event indicating that the user has started interacting with the seek bar.
      */
@@ -192,10 +195,12 @@
         val seekAvailable = ((playbackState?.actions ?: 0L) and PlaybackState.ACTION_SEEK_TO) != 0L
         val position = playbackState?.position?.toInt()
         val duration = mediaMetadata?.getLong(MediaMetadata.METADATA_KEY_DURATION)?.toInt() ?: 0
+        val playing = NotificationMediaManager
+                .isPlayingState(playbackState?.state ?: PlaybackState.STATE_NONE)
         val enabled = if (playbackState == null ||
                 playbackState?.getState() == PlaybackState.STATE_NONE ||
                 (duration <= 0)) false else true
-        _data = Progress(enabled, seekAvailable, position, duration)
+        _data = Progress(enabled, seekAvailable, playing, position, duration)
         checkIfPollingNeeded()
     }
 
@@ -412,6 +417,7 @@
     data class Progress(
         val enabled: Boolean,
         val seekAvailable: Boolean,
+        val playing: Boolean,
         val elapsedTime: Int?,
         val duration: Int
     )
diff --git a/packages/SystemUI/src/com/android/systemui/media/SquigglyProgress.kt b/packages/SystemUI/src/com/android/systemui/media/SquigglyProgress.kt
new file mode 100644
index 0000000..f1058e2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/SquigglyProgress.kt
@@ -0,0 +1,184 @@
+package com.android.systemui.media
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ValueAnimator
+import android.content.res.ColorStateList
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.ColorFilter
+import android.graphics.Paint
+import android.graphics.Path
+import android.graphics.PixelFormat
+import android.graphics.drawable.Drawable
+import android.os.SystemClock
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.animation.Interpolators
+import kotlin.math.abs
+import kotlin.math.cos
+
+private const val TAG = "Squiggly"
+
+private const val TWO_PI = (Math.PI * 2f).toFloat()
+@VisibleForTesting
+internal const val DISABLED_ALPHA = 77
+
+class SquigglyProgress : Drawable() {
+
+    private val wavePaint = Paint()
+    private val linePaint = Paint()
+    private val path = Path()
+    private var heightFraction = 0f
+    private var heightAnimator: ValueAnimator? = null
+    private var phaseOffset = 0f
+    private var lastFrameTime = -1L
+
+    // Horizontal length of the sine wave
+    var waveLength = 0f
+    // Height of each peak of the sine wave
+    var lineAmplitude = 0f
+    // Line speed in px per second
+    var phaseSpeed = 0f
+    // Progress stroke width, both for wave and solid line
+    var strokeWidth = 0f
+        set(value) {
+            if (field == value) {
+                return
+            }
+            field = value
+            wavePaint.strokeWidth = value
+            linePaint.strokeWidth = value
+        }
+
+    init {
+        wavePaint.strokeCap = Paint.Cap.ROUND
+        linePaint.strokeCap = Paint.Cap.ROUND
+        linePaint.style = Paint.Style.STROKE
+        wavePaint.style = Paint.Style.STROKE
+        linePaint.alpha = DISABLED_ALPHA
+    }
+
+    var animate: Boolean = false
+        set(value) {
+            if (field == value) {
+                return
+            }
+            field = value
+            if (field) {
+                lastFrameTime = SystemClock.uptimeMillis()
+            }
+            heightAnimator?.cancel()
+            heightAnimator = ValueAnimator.ofFloat(heightFraction, if (animate) 1f else 0f).apply {
+                if (animate) {
+                    startDelay = 60
+                    duration = 800
+                    interpolator = Interpolators.EMPHASIZED_DECELERATE
+                } else {
+                    duration = 550
+                    interpolator = Interpolators.STANDARD_DECELERATE
+                }
+                addUpdateListener {
+                    heightFraction = it.animatedValue as Float
+                    invalidateSelf()
+                }
+                addListener(object : AnimatorListenerAdapter() {
+                    override fun onAnimationEnd(animation: Animator?) {
+                        heightAnimator = null
+                    }
+                })
+                start()
+            }
+        }
+
+    override fun draw(canvas: Canvas) {
+        if (animate) {
+            invalidateSelf()
+            val now = SystemClock.uptimeMillis()
+            phaseOffset -= (now - lastFrameTime) / 1000f * phaseSpeed
+            phaseOffset %= waveLength
+            lastFrameTime = now
+        }
+
+        val totalProgressPx = (bounds.width() * (level / 10_000f))
+        canvas.save()
+        canvas.translate(bounds.left.toFloat(), bounds.centerY().toFloat())
+        // Clip drawing, so we stop at the thumb
+        canvas.clipRect(
+                0f,
+                -lineAmplitude - strokeWidth,
+                totalProgressPx,
+                lineAmplitude + strokeWidth)
+
+        // The squiggly line
+        val start = phaseOffset
+        var currentX = start
+        var waveSign = 1f
+        path.rewind()
+        path.moveTo(start, lineAmplitude * heightFraction)
+        while (currentX < totalProgressPx) {
+            val nextX = currentX + waveLength / 2f
+            val nextWaveSign = waveSign * -1
+            path.cubicTo(
+                    currentX + waveLength / 4f, lineAmplitude * waveSign * heightFraction,
+                    nextX - waveLength / 4f, lineAmplitude * nextWaveSign * heightFraction,
+                    nextX, lineAmplitude * nextWaveSign * heightFraction)
+            currentX = nextX
+            waveSign = nextWaveSign
+        }
+        wavePaint.style = Paint.Style.STROKE
+        canvas.drawPath(path, wavePaint)
+        canvas.restore()
+
+        // Draw round line cap at the beginning of the wave
+        val startAmp = cos(abs(phaseOffset) / waveLength * TWO_PI)
+        val p = Paint()
+        p.color = Color.WHITE
+        canvas.drawPoint(
+                bounds.left.toFloat(),
+                bounds.centerY() + startAmp * lineAmplitude * heightFraction,
+                wavePaint)
+
+        // Draw continuous line, to the right of the thumb
+        canvas.drawLine(
+                bounds.left.toFloat() + totalProgressPx,
+                bounds.centerY().toFloat(),
+                bounds.width().toFloat(),
+                bounds.centerY().toFloat(),
+                linePaint)
+    }
+
+    override fun getOpacity(): Int {
+        return PixelFormat.TRANSLUCENT
+    }
+
+    override fun setColorFilter(colorFilter: ColorFilter?) {
+        wavePaint.colorFilter = colorFilter
+        linePaint.colorFilter = colorFilter
+    }
+
+    override fun setAlpha(alpha: Int) {
+        wavePaint.alpha = alpha
+        linePaint.alpha = (DISABLED_ALPHA * (alpha / 255f)).toInt()
+    }
+
+    override fun getAlpha(): Int {
+        return wavePaint.alpha
+    }
+
+    override fun setTint(tintColor: Int) {
+        wavePaint.color = tintColor
+        linePaint.color = tintColor
+    }
+
+    override fun onLevelChange(level: Int): Boolean {
+        return animate
+    }
+
+    override fun setTintList(tint: ColorStateList?) {
+        if (tint == null) {
+            return
+        }
+        wavePaint.color = tint.defaultColor
+        linePaint.color = tint.defaultColor
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index c96aca3..62d5c8e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -34,7 +34,6 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ProgressBar;
-import android.widget.RelativeLayout;
 import android.widget.SeekBar;
 import android.widget.TextView;
 
@@ -129,7 +128,7 @@
         final ImageView mTitleIcon;
         final ProgressBar mProgressBar;
         final SeekBar mSeekBar;
-        final RelativeLayout mTwoLineLayout;
+        final LinearLayout mTwoLineLayout;
         final ImageView mStatusIcon;
         final CheckBox mCheckBox;
         private String mDeviceId;
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 04a324b..a8141c0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -21,7 +21,6 @@
 
 import android.app.WallpaperColors;
 import android.content.Context;
-import android.content.Intent;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -55,6 +54,7 @@
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 
 /**
@@ -71,6 +71,7 @@
 
     final Context mContext;
     final MediaOutputController mMediaOutputController;
+    final BroadcastSender mBroadcastSender;
 
     @VisibleForTesting
     View mDialogView;
@@ -98,11 +99,13 @@
         }
     };
 
-    public MediaOutputBaseDialog(Context context, MediaOutputController mediaOutputController) {
+    public MediaOutputBaseDialog(Context context, BroadcastSender broadcastSender,
+            MediaOutputController mediaOutputController) {
         super(context, R.style.Theme_SystemUI_Dialog_Media);
 
         // Save the context that is wrapped with our theme.
         mContext = getContext();
+        mBroadcastSender = broadcastSender;
         mMediaOutputController = mediaOutputController;
         mLayoutManager = new LinearLayoutManager(mContext);
         mListMaxHeight = context.getResources().getDimensionPixelSize(
@@ -152,7 +155,7 @@
             dismiss();
         });
         mAppButton.setOnClickListener(v -> {
-            mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+            mBroadcastSender.closeSystemDialogs();
             if (mMediaOutputController.getAppLaunchIntent() != null) {
                 mContext.startActivity(mMediaOutputController.getAppLaunchIntent());
             }
@@ -211,10 +214,8 @@
                 ColorFilter buttonColorFilter = new PorterDuffColorFilter(
                         mAdapter.getController().getColorButtonBackground(),
                         PorterDuff.Mode.SRC_IN);
-                ColorFilter onlineButtonColorFilter = new PorterDuffColorFilter(
-                        mAdapter.getController().getColorInactiveItem(), PorterDuff.Mode.SRC_IN);
                 mDoneButton.getBackground().setColorFilter(buttonColorFilter);
-                mStopButton.getBackground().setColorFilter(onlineButtonColorFilter);
+                mStopButton.getBackground().setColorFilter(buttonColorFilter);
             }
             mHeaderIcon.setVisibility(View.VISIBLE);
             mHeaderIcon.setImageIcon(icon);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index f16ca7d..0b6c68d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -30,12 +30,16 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
+import android.media.INearbyMediaDevicesUpdateCallback;
 import android.media.MediaMetadata;
 import android.media.MediaRoute2Info;
+import android.media.NearbyDevice;
 import android.media.RoutingSessionInfo;
 import android.media.session.MediaController;
 import android.media.session.MediaSessionManager;
 import android.media.session.PlaybackState;
+import android.os.IBinder;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -49,7 +53,6 @@
 import androidx.mediarouter.media.MediaRouter;
 import androidx.mediarouter.media.MediaRouterParams;
 
-import com.android.internal.logging.UiEventLogger;
 import com.android.settingslib.RestrictedLockUtilsInternal;
 import com.android.settingslib.Utils;
 import com.android.settingslib.bluetooth.BluetoothUtils;
@@ -61,15 +64,18 @@
 import com.android.systemui.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.monet.ColorScheme;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
-import com.android.systemui.statusbar.phone.ShadeController;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import javax.inject.Inject;
@@ -77,7 +83,8 @@
 /**
  * Controller for media output dialog
  */
-public class MediaOutputController implements LocalMediaManager.DeviceCallback {
+public class MediaOutputController implements LocalMediaManager.DeviceCallback,
+        INearbyMediaDevicesUpdateCallback {
 
     private static final String TAG = "MediaOutputController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -86,15 +93,14 @@
     private final String mPackageName;
     private final Context mContext;
     private final MediaSessionManager mMediaSessionManager;
-    private final LocalBluetoothManager mLocalBluetoothManager;
-    private final ShadeController mShadeController;
     private final ActivityStarter mActivityStarter;
     private final DialogLaunchAnimator mDialogLaunchAnimator;
     private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>();
-    private final boolean mAboveStatusbar;
     private final CommonNotifCollection mNotifCollection;
     @VisibleForTesting
     final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
+    private final NearbyMediaDevicesManager mNearbyMediaDevicesManager;
+    private final Map<String, Integer> mNearbyDeviceInfoMap = new ConcurrentHashMap<>();
 
     private MediaController mMediaController;
     @VisibleForTesting
@@ -103,7 +109,6 @@
     LocalMediaManager mLocalMediaManager;
 
     private MediaOutputMetricLogger mMetricLogger;
-    private UiEventLogger mUiEventLogger;
 
     private int mColorActiveItem;
     private int mColorInactiveItem;
@@ -113,23 +118,21 @@
 
     @Inject
     public MediaOutputController(@NonNull Context context, String packageName,
-            boolean aboveStatusbar, MediaSessionManager mediaSessionManager, LocalBluetoothManager
-            lbm, ShadeController shadeController, ActivityStarter starter,
-            CommonNotifCollection notifCollection, UiEventLogger uiEventLogger,
-            DialogLaunchAnimator dialogLaunchAnimator) {
+            MediaSessionManager mediaSessionManager, LocalBluetoothManager
+            lbm, ActivityStarter starter,
+            CommonNotifCollection notifCollection,
+            DialogLaunchAnimator dialogLaunchAnimator,
+            Optional<NearbyMediaDevicesManager> nearbyMediaDevicesManagerOptional) {
         mContext = context;
         mPackageName = packageName;
         mMediaSessionManager = mediaSessionManager;
-        mLocalBluetoothManager = lbm;
-        mShadeController = shadeController;
         mActivityStarter = starter;
-        mAboveStatusbar = aboveStatusbar;
         mNotifCollection = notifCollection;
         InfoMediaManager imm = new InfoMediaManager(mContext, packageName, null, lbm);
         mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName);
         mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
-        mUiEventLogger = uiEventLogger;
         mDialogLaunchAnimator = dialogLaunchAnimator;
+        mNearbyMediaDevicesManager = nearbyMediaDevicesManagerOptional.orElse(null);
         mColorActiveItem = Utils.getColorStateListDefaultColor(mContext,
                 R.color.media_dialog_active_item_main_content);
         mColorInactiveItem = Utils.getColorStateListDefaultColor(mContext,
@@ -144,6 +147,10 @@
 
     void start(@NonNull Callback cb) {
         mMediaDevices.clear();
+        mNearbyDeviceInfoMap.clear();
+        if (mNearbyMediaDevicesManager != null) {
+            mNearbyMediaDevicesManager.registerNearbyDevicesCallback(this);
+        }
         if (!TextUtils.isEmpty(mPackageName)) {
             for (MediaController controller : mMediaSessionManager.getActiveSessions(null)) {
                 if (TextUtils.equals(controller.getPackageName(), mPackageName)) {
@@ -187,6 +194,10 @@
             mLocalMediaManager.stopScan();
         }
         mMediaDevices.clear();
+        if (mNearbyMediaDevicesManager != null) {
+            mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this);
+        }
+        mNearbyDeviceInfoMap.clear();
     }
 
     @Override
@@ -417,6 +428,15 @@
         }
         mMediaDevices.clear();
         mMediaDevices.addAll(targetMediaDevices);
+        attachRangeInfo();
+    }
+
+    private void attachRangeInfo() {
+        for (MediaDevice mediaDevice : mMediaDevices) {
+            if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) {
+                mediaDevice.setRangeZone(mNearbyDeviceInfoMap.get(mediaDevice.getId()));
+            }
+        }
     }
 
     List<MediaDevice> getGroupMediaDevices() {
@@ -600,16 +620,6 @@
         mActivityStarter.startActivity(launchIntent, true, controller);
     }
 
-    void launchMediaOutputGroupDialog(View mediaOutputDialog) {
-        // We show the output group dialog from the output dialog.
-        MediaOutputController controller = new MediaOutputController(mContext, mPackageName,
-                mAboveStatusbar, mMediaSessionManager, mLocalBluetoothManager, mShadeController,
-                mActivityStarter, mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
-        MediaOutputGroupDialog dialog = new MediaOutputGroupDialog(mContext, mAboveStatusbar,
-                controller);
-        mDialogLaunchAnimator.showFromView(dialog, mediaOutputDialog);
-    }
-
     boolean isActiveRemoteDevice(@NonNull MediaDevice device) {
         final List<String> features = device.getFeatures();
         return (features.contains(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK)
@@ -629,6 +639,20 @@
                 || mLocalMediaManager.isMediaSessionAvailableForVolumeControl();
     }
 
+    @Override
+    public void onDevicesUpdated(List<NearbyDevice> nearbyDevices) throws RemoteException {
+        mNearbyDeviceInfoMap.clear();
+        for (NearbyDevice nearbyDevice : nearbyDevices) {
+            mNearbyDeviceInfoMap.put(nearbyDevice.getMediaRoute2Id(), nearbyDevice.getRangeZone());
+        }
+        mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this);
+    }
+
+    @Override
+    public IBinder asBinder() {
+        return null;
+    }
+
     private final MediaController.Callback mCb = new MediaController.Callback() {
         @Override
         public void onMetadataChanged(MediaMetadata metadata) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
index 7696a1f..7834ec0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
@@ -28,6 +28,7 @@
 import com.android.internal.logging.UiEvent;
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.SysUISingleton;
 
 /**
@@ -37,9 +38,9 @@
 public class MediaOutputDialog extends MediaOutputBaseDialog {
     final UiEventLogger mUiEventLogger;
 
-    MediaOutputDialog(Context context, boolean aboveStatusbar, MediaOutputController
-            mediaOutputController, UiEventLogger uiEventLogger) {
-        super(context, mediaOutputController);
+    MediaOutputDialog(Context context, boolean aboveStatusbar, BroadcastSender broadcastSender,
+            MediaOutputController mediaOutputController, UiEventLogger uiEventLogger) {
+        super(context, broadcastSender, mediaOutputController);
         mUiEventLogger = uiEventLogger;
         mAdapter = new MediaOutputAdapter(mMediaOutputController, this);
         if (!aboveStatusbar) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
index 9e252ea..0d7d60a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
@@ -22,9 +22,11 @@
 import com.android.internal.logging.UiEventLogger
 import com.android.settingslib.bluetooth.LocalBluetoothManager
 import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.broadcast.BroadcastSender
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
-import com.android.systemui.statusbar.phone.ShadeController
+import java.util.Optional
 import javax.inject.Inject
 
 /**
@@ -34,11 +36,12 @@
     private val context: Context,
     private val mediaSessionManager: MediaSessionManager,
     private val lbm: LocalBluetoothManager?,
-    private val shadeController: ShadeController,
     private val starter: ActivityStarter,
+    private val broadcastSender: BroadcastSender,
     private val notifCollection: CommonNotifCollection,
     private val uiEventLogger: UiEventLogger,
-    private val dialogLaunchAnimator: DialogLaunchAnimator
+    private val dialogLaunchAnimator: DialogLaunchAnimator,
+    private val nearbyMediaDevicesManagerOptional: Optional<NearbyMediaDevicesManager>
 ) {
     companion object {
         var mediaOutputDialog: MediaOutputDialog? = null
@@ -49,10 +52,11 @@
         // Dismiss the previous dialog, if any.
         mediaOutputDialog?.dismiss()
 
-        val controller = MediaOutputController(context, packageName, aboveStatusBar,
-            mediaSessionManager, lbm, shadeController, starter, notifCollection,
-            uiEventLogger, dialogLaunchAnimator)
-        val dialog = MediaOutputDialog(context, aboveStatusBar, controller, uiEventLogger)
+        val controller = MediaOutputController(context, packageName,
+                mediaSessionManager, lbm, starter, notifCollection,
+                dialogLaunchAnimator, nearbyMediaDevicesManagerOptional)
+        val dialog =
+            MediaOutputDialog(context, aboveStatusBar, broadcastSender, controller, uiEventLogger)
         mediaOutputDialog = dialog
 
         // Show the dialog.
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java
index f1c6601..bb3f969 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java
@@ -25,6 +25,7 @@
 import androidx.core.graphics.drawable.IconCompat;
 
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastSender;
 
 /**
  * Dialog for media output group.
@@ -32,9 +33,9 @@
 // TODO(b/203073091): Remove this class once group logic been implemented.
 public class MediaOutputGroupDialog extends MediaOutputBaseDialog {
 
-    MediaOutputGroupDialog(Context context, boolean aboveStatusbar, MediaOutputController
-            mediaOutputController) {
-        super(context, mediaOutputController);
+    MediaOutputGroupDialog(Context context, boolean aboveStatusbar, BroadcastSender broadcastSender,
+            MediaOutputController mediaOutputController) {
+        super(context, broadcastSender, mediaOutputController);
         mMediaOutputController.resetGroupMediaDevices();
         mAdapter = new MediaOutputGroupAdapter(mMediaOutputController);
         if (!aboveStatusbar) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
index 9dd8222..3961f07 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.media.taptotransfer
 
+import android.annotation.SuppressLint
 import android.app.StatusBarManager
 import android.content.Context
 import android.media.MediaRoute2Info
@@ -23,16 +24,12 @@
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.media.taptotransfer.sender.AlmostCloseToEndCast
-import com.android.systemui.media.taptotransfer.sender.AlmostCloseToStartCast
-import com.android.systemui.media.taptotransfer.sender.TransferFailed
-import com.android.systemui.media.taptotransfer.sender.TransferToReceiverTriggered
-import com.android.systemui.media.taptotransfer.sender.TransferToThisDeviceSucceeded
-import com.android.systemui.media.taptotransfer.sender.TransferToThisDeviceTriggered
-import com.android.systemui.media.taptotransfer.sender.TransferToReceiverSucceeded
+import com.android.systemui.media.taptotransfer.receiver.ChipStateReceiver
+import com.android.systemui.media.taptotransfer.sender.ChipStateSender
 import com.android.systemui.statusbar.commandline.Command
 import com.android.systemui.statusbar.commandline.CommandRegistry
 import java.io.PrintWriter
+import java.lang.IllegalArgumentException
 import java.util.concurrent.Executor
 import javax.inject.Inject
 
@@ -46,28 +43,6 @@
     private val context: Context,
     @Main private val mainExecutor: Executor
 ) {
-    /**
-     * A map from a display state string typed in the command line to the display int it represents.
-     */
-    private val stateStringToStateInt: Map<String, Int> = mapOf(
-        AlmostCloseToStartCast::class.simpleName!!
-                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
-        AlmostCloseToEndCast::class.simpleName!!
-                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
-        TransferToReceiverTriggered::class.simpleName!!
-                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
-        TransferToThisDeviceTriggered::class.simpleName!!
-                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
-        TransferToReceiverSucceeded::class.simpleName!!
-                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
-        TransferToThisDeviceSucceeded::class.simpleName!!
-                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
-        TransferFailed::class.simpleName!!
-                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
-        FAR_FROM_RECEIVER_STATE
-                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER
-    )
-
     init {
         commandRegistry.registerCommand(SENDER_COMMAND) { SenderCommand() }
         commandRegistry.registerCommand(RECEIVER_COMMAND) { ReceiverCommand() }
@@ -76,21 +51,23 @@
     /** All commands for the sender device. */
     inner class SenderCommand : Command {
         override fun execute(pw: PrintWriter, args: List<String>) {
-            val routeInfo = MediaRoute2Info.Builder("id", args[0])
-                    .addFeature("feature")
-                    .setPackageName(TEST_PACKAGE_NAME)
-                    .build()
-
             val commandName = args[1]
             @StatusBarManager.MediaTransferSenderState
-            val displayState = stateStringToStateInt[commandName]
-            if (displayState == null) {
+            val displayState: Int?
+            try {
+                displayState = ChipStateSender.getSenderStateIdFromName(commandName)
+            }  catch (ex: IllegalArgumentException) {
                 pw.println("Invalid command name $commandName")
                 return
             }
 
+            @SuppressLint("WrongConstant") // sysui allowed to call STATUS_BAR_SERVICE
             val statusBarManager = context.getSystemService(Context.STATUS_BAR_SERVICE)
                     as StatusBarManager
+            val routeInfo = MediaRoute2Info.Builder("id", args[0])
+                    .addFeature("feature")
+                    .setPackageName(TEST_PACKAGE_NAME)
+                    .build()
             statusBarManager.updateMediaTapToTransferSenderDisplay(
                     displayState,
                     routeInfo,
@@ -136,6 +113,17 @@
     /** All commands for the receiver device. */
     inner class ReceiverCommand : Command {
         override fun execute(pw: PrintWriter, args: List<String>) {
+            val commandName = args[0]
+            @StatusBarManager.MediaTransferReceiverState
+            val displayState: Int?
+            try {
+                displayState = ChipStateReceiver.getReceiverStateIdFromName(commandName)
+            } catch (ex: IllegalArgumentException) {
+                pw.println("Invalid command name $commandName")
+                return
+            }
+
+            @SuppressLint("WrongConstant") // sysui is allowed to call STATUS_BAR_SERVICE
             val statusBarManager = context.getSystemService(Context.STATUS_BAR_SERVICE)
                     as StatusBarManager
             val routeInfo = MediaRoute2Info.Builder("id", "Test Name")
@@ -143,24 +131,12 @@
                 .setPackageName(TEST_PACKAGE_NAME)
                 .build()
 
-            when(val commandName = args[0]) {
-                CLOSE_TO_SENDER_STATE ->
-                    statusBarManager.updateMediaTapToTransferReceiverDisplay(
-                        StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
-                        routeInfo,
-                        null,
-                        null
-                    )
-                FAR_FROM_SENDER_STATE ->
-                    statusBarManager.updateMediaTapToTransferReceiverDisplay(
-                        StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
-                        routeInfo,
-                        null,
-                        null
-                    )
-                else ->
-                    pw.println("Invalid command name $commandName")
-            }
+            statusBarManager.updateMediaTapToTransferReceiverDisplay(
+                    displayState,
+                    routeInfo,
+                    null,
+                    null
+                )
         }
 
         override fun help(pw: PrintWriter) {
@@ -173,11 +149,5 @@
 const val SENDER_COMMAND = "media-ttt-chip-sender"
 @VisibleForTesting
 const val RECEIVER_COMMAND = "media-ttt-chip-receiver"
-@VisibleForTesting
-const val FAR_FROM_RECEIVER_STATE = "FarFromReceiver"
-@VisibleForTesting
-const val CLOSE_TO_SENDER_STATE = "CloseToSender"
-@VisibleForTesting
-const val FAR_FROM_SENDER_STATE = "FarFromSender"
 private const val CLI_TAG = "MediaTransferCli"
 private const val TEST_PACKAGE_NAME = "com.android.systemui"
diff --git a/core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
similarity index 60%
copy from core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl
copy to packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
index 6ca8cec..3cc99a8 100644
--- a/core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
@@ -14,9 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony;
+package com.android.systemui.media.taptotransfer.common
 
-oneway interface ICarrierPrivilegesListener {
-    void onCarrierPrivilegesChanged(
-            in List<String> privilegedPackageNames, in int[] privilegedUids);
+/**
+ * A superclass chip state that will be subclassed by the sender chip and receiver chip.
+ */
+interface ChipInfoCommon {
+    /**
+     * Returns the amount of time the given chip state should display on the screen before it times
+     * out and disappears.
+     */
+    fun getTimeoutMs(): Long
 }
+
+const val DEFAULT_TIMEOUT_MILLIS = 3000L
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
index 9c4b39d..71cacac 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
@@ -19,14 +19,18 @@
 import android.annotation.LayoutRes
 import android.annotation.SuppressLint
 import android.content.Context
+import android.content.pm.PackageManager
 import android.graphics.PixelFormat
+import android.graphics.drawable.Drawable
+import android.os.PowerManager
+import android.os.SystemClock
+import android.util.Log
 import android.view.Gravity
 import android.view.LayoutInflater
 import android.view.MotionEvent
 import android.view.View
 import android.view.ViewGroup
 import android.view.WindowManager
-import androidx.annotation.VisibleForTesting
 import com.android.internal.widget.CachingIconView
 import com.android.systemui.R
 import com.android.systemui.dagger.qualifiers.Main
@@ -40,14 +44,18 @@
  *
  * Subclasses need to override and implement [updateChipView], which is where they can control what
  * gets displayed to the user.
+ *
+ * The generic type T is expected to contain all the information necessary for the subclasses to
+ * display the chip in a certain state, since they receive <T> in [updateChipView].
  */
-abstract class MediaTttChipControllerCommon<T : MediaTttChipState>(
+abstract class MediaTttChipControllerCommon<T : ChipInfoCommon>(
     internal val context: Context,
     internal val logger: MediaTttLogger,
     private val windowManager: WindowManager,
     private val viewUtil: ViewUtil,
     @Main private val mainExecutor: DelayableExecutor,
     private val tapGestureDetector: TapGestureDetector,
+    private val powerManager: PowerManager,
     @LayoutRes private val chipLayoutRes: Int
 ) {
     /** The window layout parameters we'll use when attaching the view to a window. */
@@ -64,10 +72,10 @@
     }
 
     /** The chip view currently being displayed. Null if the chip is not being displayed. */
-    var chipView: ViewGroup? = null
+    private var chipView: ViewGroup? = null
 
     /** A [Runnable] that, when run, will cancel the pending timeout of the chip. */
-    var cancelChipViewTimeout: Runnable? = null
+    private var cancelChipViewTimeout: Runnable? = null
 
     /**
      * Displays the chip with the current state.
@@ -75,7 +83,7 @@
      * This method handles inflating and attaching the view, then delegates to [updateChipView] to
      * display the correct information in the chip.
      */
-    fun displayChip(chipState: T) {
+    fun displayChip(chipInfo: T) {
         val oldChipView = chipView
         if (chipView == null) {
             chipView = LayoutInflater
@@ -84,19 +92,25 @@
         }
         val currentChipView = chipView!!
 
-        updateChipView(chipState, currentChipView)
+        updateChipView(chipInfo, currentChipView)
 
         // Add view if necessary
         if (oldChipView == null) {
             tapGestureDetector.addOnGestureDetectedCallback(TAG, this::onScreenTapped)
             windowManager.addView(chipView, windowLayoutParams)
+            // Wake the screen so the user will see the chip
+            powerManager.wakeUp(
+                SystemClock.uptimeMillis(),
+                PowerManager.WAKE_REASON_APPLICATION,
+                "com.android.systemui:media_tap_to_transfer_activated"
+            )
         }
 
         // Cancel and re-set the chip timeout each time we get a new state.
         cancelChipViewTimeout?.run()
         cancelChipViewTimeout = mainExecutor.executeDelayed(
             { removeChip(MediaTttRemovalReason.REASON_TIMEOUT) },
-            chipState.getTimeoutMs()
+            chipInfo.getTimeoutMs()
         )
     }
 
@@ -117,20 +131,28 @@
     }
 
     /**
-     * A method implemented by subclasses to update [currentChipView] based on [chipState].
+     * A method implemented by subclasses to update [currentChipView] based on [chipInfo].
      */
-    abstract fun updateChipView(chipState: T, currentChipView: ViewGroup)
+    abstract fun updateChipView(chipInfo: T, currentChipView: ViewGroup)
 
     /**
      * An internal method to set the icon on the view.
      *
      * This is in the common superclass since both the sender and the receiver show an icon.
+     *
+     * @param appPackageName the package name of the app playing the media. Will be used to fetch
+     *   the app icon and app name if overrides aren't provided.
      */
-    internal fun setIcon(chipState: T, currentChipView: ViewGroup) {
+    internal fun setIcon(
+        currentChipView: ViewGroup,
+        appPackageName: String?,
+        appIconDrawableOverride: Drawable? = null,
+        appNameOverride: CharSequence? = null,
+    ) {
         val appIconView = currentChipView.requireViewById<CachingIconView>(R.id.app_icon)
-        appIconView.contentDescription = chipState.getAppName(context)
+        appIconView.contentDescription = appNameOverride ?: getAppName(appPackageName)
 
-        val appIcon = chipState.getAppIcon(context)
+        val appIcon = appIconDrawableOverride ?: getAppIcon(appPackageName)
         val visibility = if (appIcon != null) {
             View.VISIBLE
         } else {
@@ -140,6 +162,30 @@
         appIconView.visibility = visibility
     }
 
+    /** Returns the icon of the app playing the media or null if we can't find it. */
+    private fun getAppIcon(appPackageName: String?): Drawable? {
+        appPackageName ?: return null
+        return try {
+            context.packageManager.getApplicationIcon(appPackageName)
+        } catch (e: PackageManager.NameNotFoundException) {
+            Log.w(TAG, "Cannot find icon for package $appPackageName", e)
+            null
+        }
+    }
+
+    /** Returns the name of the app playing the media or null if we can't find it. */
+    private fun getAppName(appPackageName: String?): String? {
+        appPackageName ?: return null
+        return try {
+            context.packageManager.getApplicationInfo(
+                    appPackageName, PackageManager.ApplicationInfoFlags.of(0)
+            ).loadLabel(context.packageManager).toString()
+        } catch (e: PackageManager.NameNotFoundException) {
+            Log.w(TAG, "Cannot find name for package $appPackageName", e)
+            null
+        }
+    }
+
     private fun onScreenTapped(e: MotionEvent) {
         val view = chipView ?: return
         // If the tap is within the chip bounds, we shouldn't hide the chip (in case users think the
@@ -159,4 +205,3 @@
     const val REASON_TIMEOUT = "TIMEOUT"
     const val REASON_SCREEN_TAP = "SCREEN_TAP"
 }
-
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt
deleted file mode 100644
index 6f60181..0000000
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.taptotransfer.common
-
-import android.content.Context
-import android.content.pm.PackageManager
-import android.graphics.drawable.Drawable
-import android.util.Log
-
-/**
- * A superclass chip state that will be subclassed by the sender chip and receiver chip.
- *
- * @property appPackageName the package name of the app playing the media. Will be used to fetch the
- *   app icon and app name.
- */
-open class MediaTttChipState(
-    internal val appPackageName: String?,
-) {
-    open fun getAppIcon(context: Context): Drawable? {
-        appPackageName ?: return null
-        return try {
-            context.packageManager.getApplicationIcon(appPackageName)
-        } catch (e: PackageManager.NameNotFoundException) {
-            Log.w(TAG, "Cannot find icon for package $appPackageName", e)
-            null
-        }
-    }
-
-    /** Returns the name of the app playing the media or null if we can't find it. */
-    open fun getAppName(context: Context): String? {
-        appPackageName ?: return null
-        return try {
-            context.packageManager.getApplicationInfo(
-                appPackageName, PackageManager.ApplicationInfoFlags.of(0)
-            ).loadLabel(context.packageManager).toString()
-        } catch (e: PackageManager.NameNotFoundException) {
-            Log.w(TAG, "Cannot find name for package $appPackageName", e)
-            null
-        }
-    }
-
-    /**
-     * Returns the amount of time this chip should display on the screen before it times out and
-     * disappears. [MediaTttChipControllerCommon] will ensure that the timeout resets each time we
-     * receive a new state.
-     */
-    open fun getTimeoutMs(): Long = DEFAULT_TIMEOUT_MILLIS
-}
-
-private const val DEFAULT_TIMEOUT_MILLIS = 3000L
-private val TAG = MediaTttChipState::class.simpleName!!
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
index 6a4b62a..a0e803f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
@@ -16,35 +16,43 @@
 
 package com.android.systemui.media.taptotransfer.receiver
 
-import android.content.Context
-import android.graphics.drawable.Drawable
-import com.android.systemui.media.taptotransfer.common.MediaTttChipState
+import android.app.StatusBarManager
+import com.android.internal.logging.UiEventLogger
 
 /**
  * A class that stores all the information necessary to display the media tap-to-transfer chip on
  * the receiver device.
- *
- * @property appIconDrawable a drawable representing the icon of the app playing the media. If
- *     present, this will be used in [this.getAppIcon] instead of [appPackageName].
- * @property appName a name for the app playing the media. If present, this will be used in
- *     [this.getAppName] instead of [appPackageName].
  */
-class ChipStateReceiver(
-    appPackageName: String?,
-    private val appIconDrawable: Drawable?,
-    private val appName: CharSequence?
-) : MediaTttChipState(appPackageName) {
-    override fun getAppIcon(context: Context): Drawable? {
-        if (appIconDrawable != null) {
-            return appIconDrawable
-        }
-        return super.getAppIcon(context)
-    }
+enum class ChipStateReceiver(
+    @StatusBarManager.MediaTransferSenderState val stateInt: Int,
+    val uiEvent: UiEventLogger.UiEventEnum,
+) {
+    CLOSE_TO_SENDER(
+        StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
+        MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER,
+    ),
+    FAR_FROM_SENDER(
+        StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
+        MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_FAR_FROM_SENDER,
+    );
 
-    override fun getAppName(context: Context): String? {
-        if (appName != null) {
-            return appName.toString()
-        }
-        return super.getAppName(context)
+    companion object {
+        /**
+         * Returns the receiver state enum associated with the given [displayState] from
+         * [StatusBarManager].
+         */
+        fun getReceiverStateFromId(
+            @StatusBarManager.MediaTransferReceiverState displayState: Int
+        ) : ChipStateReceiver = values().first { it.stateInt == displayState }
+
+
+        /**
+         * Returns the state int from [StatusBarManager] associated with the given sender state
+         * name.
+         *
+         * @param name the name of one of the [ChipStateReceiver] enums.
+         */
+        @StatusBarManager.MediaTransferReceiverState
+        fun getReceiverStateIdFromName(name: String): Int = valueOf(name).stateInt
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index 1a96ddf..44965d7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -18,15 +18,19 @@
 
 import android.app.StatusBarManager
 import android.content.Context
+import android.graphics.drawable.Drawable
 import android.graphics.drawable.Icon
 import android.media.MediaRoute2Info
 import android.os.Handler
+import android.os.PowerManager
 import android.util.Log
 import android.view.ViewGroup
 import android.view.WindowManager
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.media.taptotransfer.common.ChipInfoCommon
+import com.android.systemui.media.taptotransfer.common.DEFAULT_TIMEOUT_MILLIS
 import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCommon
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
 import com.android.systemui.statusbar.CommandQueue
@@ -49,14 +53,17 @@
     viewUtil: ViewUtil,
     mainExecutor: DelayableExecutor,
     tapGestureDetector: TapGestureDetector,
+    powerManager: PowerManager,
     @Main private val mainHandler: Handler,
-) : MediaTttChipControllerCommon<ChipStateReceiver>(
+    private val uiEventLogger: MediaTttReceiverUiEventLogger,
+) : MediaTttChipControllerCommon<ChipReceiverInfo>(
     context,
     logger,
     windowManager,
     viewUtil,
     mainExecutor,
     tapGestureDetector,
+    powerManager,
     R.layout.media_ttt_chip_receiver
 ) {
     private val commandQueueCallbacks = object : CommandQueue.Callbacks {
@@ -82,45 +89,52 @@
         appIcon: Icon?,
         appName: CharSequence?
     ) {
-        logger.logStateChange(stateIntToString(displayState), routeInfo.id)
-        when(displayState) {
-            StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER -> {
-                val packageName = routeInfo.packageName
-                if (appIcon == null) {
-                    displayChip(ChipStateReceiver(packageName, null, appName))
-                } else {
-                    appIcon.loadDrawableAsync(
-                        context,
-                        Icon.OnDrawableLoadedListener { drawable ->
-                            displayChip(
-                                ChipStateReceiver(packageName, drawable, appName)
-                            )},
-                        // Notify the listener on the main handler since the listener will update
-                        // the UI.
-                        mainHandler
-                    )
-                }
-            }
-            StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER ->
-                removeChip(removalReason = FAR_FROM_SENDER)
-            else ->
-                Log.e(RECEIVER_TAG, "Unhandled MediaTransferReceiverState $displayState")
+        val chipState: ChipStateReceiver? = ChipStateReceiver.getReceiverStateFromId(displayState)
+        val stateName = chipState?.name ?: "Invalid"
+        logger.logStateChange(stateName, routeInfo.id)
+
+        if (chipState == null) {
+            Log.e(RECEIVER_TAG, "Unhandled MediaTransferReceiverState $displayState")
+            return
         }
+        uiEventLogger.logReceiverStateChange(chipState)
+
+        if (chipState == ChipStateReceiver.FAR_FROM_SENDER) {
+            removeChip(removalReason = ChipStateReceiver.FAR_FROM_SENDER::class.simpleName!!)
+            return
+        }
+        if (appIcon == null) {
+            displayChip(ChipReceiverInfo(routeInfo, appIconDrawableOverride = null, appName))
+            return
+        }
+
+        appIcon.loadDrawableAsync(
+                context,
+                Icon.OnDrawableLoadedListener { drawable ->
+                    displayChip(ChipReceiverInfo(routeInfo, drawable, appName))
+                },
+                // Notify the listener on the main handler since the listener will update
+                // the UI.
+                mainHandler
+        )
     }
 
-    override fun updateChipView(chipState: ChipStateReceiver, currentChipView: ViewGroup) {
-        setIcon(chipState, currentChipView)
-    }
-
-    private fun stateIntToString(@StatusBarManager.MediaTransferReceiverState state: Int): String {
-        return when (state) {
-            StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER -> CLOSE_TO_SENDER
-            StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER -> FAR_FROM_SENDER
-            else -> "INVALID: $state"
-        }
+    override fun updateChipView(chipInfo: ChipReceiverInfo, currentChipView: ViewGroup) {
+        setIcon(
+                currentChipView,
+                chipInfo.routeInfo.packageName,
+                chipInfo.appIconDrawableOverride,
+                chipInfo.appNameOverride
+        )
     }
 }
 
+data class ChipReceiverInfo(
+    val routeInfo: MediaRoute2Info,
+    val appIconDrawableOverride: Drawable?,
+    val appNameOverride: CharSequence?
+) : ChipInfoCommon {
+    override fun getTimeoutMs() = DEFAULT_TIMEOUT_MILLIS
+}
+
 private const val RECEIVER_TAG = "MediaTapToTransferRcvr"
-private const val CLOSE_TO_SENDER = "CLOSE_TO_SENDER"
-private const val FAR_FROM_SENDER = "FAR_FROM_SENDER"
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
new file mode 100644
index 0000000..39a2763
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.taptotransfer.receiver
+
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/** A class for analytics logging for the media tap-to-transfer chip on the receiver device. */
+@SysUISingleton
+class MediaTttReceiverUiEventLogger @Inject constructor(private val logger: UiEventLogger) {
+    /** Logs that the receiver chip has changed states. */
+    fun logReceiverStateChange(chipState: ChipStateReceiver) {
+        logger.log(chipState.uiEvent)
+    }
+}
+
+enum class MediaTttReceiverUiEvents(val metricId: Int) : UiEventLogger.UiEventEnum {
+    @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_RECEIVER_* docs")
+    MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER(982),
+    @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_RECEIVER_* docs")
+    MEDIA_TTT_RECEIVER_FAR_FROM_SENDER(983);
+
+    override fun getId() = metricId
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
index 22424a4..3c6805b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
@@ -16,27 +16,187 @@
 
 package com.android.systemui.media.taptotransfer.sender
 
+import android.app.StatusBarManager
 import android.content.Context
+import android.media.MediaRoute2Info
 import android.view.View
+import androidx.annotation.StringRes
+import com.android.internal.logging.UiEventLogger
 import com.android.internal.statusbar.IUndoMediaTransferCallback
 import com.android.systemui.R
-import com.android.systemui.media.taptotransfer.common.MediaTttChipState
+import com.android.systemui.media.taptotransfer.common.DEFAULT_TIMEOUT_MILLIS
 
 /**
- * A class that stores all the information necessary to display the media tap-to-transfer chip on
- * the sender device.
+ * A class enumerating all the possible states of the media tap-to-transfer chip on the sender
+ * device.
  *
- * This is a sealed class where each subclass represents a specific chip state. Each subclass can
- * contain additional information that is necessary for only that state.
+ * @property stateInt the integer from [StatusBarManager] corresponding with this state.
+ * @property stringResId the res ID of the string that should be displayed in the chip. Null if the
+ *   state should not have the chip be displayed.
+ * @property isMidTransfer true if the state represents that a transfer is currently ongoing.
+ * @property isTransferFailure true if the state represents that the transfer has failed.
+ * @property timeout the amount of time this chip should display on the screen before it times out
+ *   and disappears.
  */
-sealed class ChipStateSender(
-    appPackageName: String?
-) : MediaTttChipState(appPackageName) {
-    /** Returns a fully-formed string with the text that the chip should display. */
-    abstract fun getChipTextString(context: Context): String
+enum class ChipStateSender(
+    @StatusBarManager.MediaTransferSenderState val stateInt: Int,
+    val uiEvent: UiEventLogger.UiEventEnum,
+    @StringRes val stringResId: Int?,
+    val isMidTransfer: Boolean = false,
+    val isTransferFailure: Boolean = false,
+    val timeout: Long = DEFAULT_TIMEOUT_MILLIS
+) {
+    /**
+     * A state representing that the two devices are close but not close enough to *start* a cast to
+     * the receiver device. The chip will instruct the user to move closer in order to initiate the
+     * transfer to the receiver.
+     */
+    ALMOST_CLOSE_TO_START_CAST(
+        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
+        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST,
+        R.string.media_move_closer_to_start_cast,
+    ),
 
-    /** Returns true if the loading icon should be displayed and false otherwise. */
-    open fun showLoading(): Boolean = false
+    /**
+     * A state representing that the two devices are close but not close enough to *end* a cast
+     * that's currently occurring the receiver device. The chip will instruct the user to move
+     * closer in order to initiate the transfer from the receiver and back onto this device (the
+     * original sender).
+     */
+    ALMOST_CLOSE_TO_END_CAST(
+        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
+        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST,
+        R.string.media_move_closer_to_end_cast,
+    ),
+
+    /**
+     * A state representing that a transfer to the receiver device has been initiated (but not
+     * completed).
+     */
+    TRANSFER_TO_RECEIVER_TRIGGERED(
+        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
+        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED,
+        R.string.media_transfer_playing_different_device,
+        isMidTransfer = true,
+        timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
+    ),
+
+    /**
+     * A state representing that a transfer from the receiver device and back to this device (the
+     * sender) has been initiated (but not completed).
+     */
+    TRANSFER_TO_THIS_DEVICE_TRIGGERED(
+        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
+        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
+        R.string.media_transfer_playing_this_device,
+        isMidTransfer = true,
+        timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
+    ),
+
+    /**
+     * A state representing that a transfer to the receiver device has been successfully completed.
+     */
+    TRANSFER_TO_RECEIVER_SUCCEEDED(
+        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
+        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED,
+        R.string.media_transfer_playing_different_device
+    ) {
+        override fun undoClickListener(
+            controllerSender: MediaTttChipControllerSender,
+            routeInfo: MediaRoute2Info,
+            undoCallback: IUndoMediaTransferCallback?,
+            uiEventLogger: MediaTttSenderUiEventLogger
+        ): View.OnClickListener? {
+            if (undoCallback == null) {
+                return null
+            }
+            return View.OnClickListener {
+                uiEventLogger.logUndoClicked(
+                    MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED
+                )
+                undoCallback.onUndoTriggered()
+                // The external service should eventually send us a TransferToThisDeviceTriggered
+                // state, but that may take too long to go through the binder and the user may be
+                // confused ast o why the UI hasn't changed yet. So, we immediately change the UI
+                // here.
+                controllerSender.displayChip(
+                    ChipSenderInfo(
+                        TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, undoCallback
+                    )
+                )
+            }
+        }
+    },
+
+    /**
+     * A state representing that a transfer back to this device has been successfully completed.
+     */
+    TRANSFER_TO_THIS_DEVICE_SUCCEEDED(
+        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
+        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
+        R.string.media_transfer_playing_this_device
+    ) {
+        override fun undoClickListener(
+            controllerSender: MediaTttChipControllerSender,
+            routeInfo: MediaRoute2Info,
+            undoCallback: IUndoMediaTransferCallback?,
+            uiEventLogger: MediaTttSenderUiEventLogger
+        ): View.OnClickListener? {
+            if (undoCallback == null) {
+                return null
+            }
+            return View.OnClickListener {
+                uiEventLogger.logUndoClicked(
+                    MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
+                )
+                undoCallback.onUndoTriggered()
+                // The external service should eventually send us a TransferToReceiverTriggered
+                // state, but that may take too long to go through the binder and the user may be
+                // confused as to why the UI hasn't changed yet. So, we immediately change the UI
+                // here.
+                controllerSender.displayChip(
+                    ChipSenderInfo(
+                        TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo, undoCallback
+                    )
+                )
+            }
+        }
+    },
+
+    /** A state representing that a transfer to the receiver device has failed. */
+    TRANSFER_TO_RECEIVER_FAILED(
+        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
+        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED,
+        R.string.media_transfer_failed,
+        isTransferFailure = true
+    ),
+
+    /** A state representing that a transfer back to this device has failed. */
+    TRANSFER_TO_THIS_DEVICE_FAILED(
+        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED,
+        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED,
+        R.string.media_transfer_failed,
+        isTransferFailure = true
+    ),
+
+    /** A state representing that this device is far away from any receiver device. */
+    FAR_FROM_RECEIVER(
+        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
+        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_FAR_FROM_RECEIVER,
+        stringResId = null
+    );
+
+    /**
+     * Returns a fully-formed string with the text that the chip should display.
+     *
+     * @param otherDeviceName the name of the other device involved in the transfer.
+     */
+    fun getChipTextString(context: Context, otherDeviceName: String): String? {
+        if (stringResId == null) {
+            return null
+        }
+        return context.getString(stringResId, otherDeviceName)
+    }
 
     /**
      * Returns a click listener for the undo button on the chip. Returns null if this chip state
@@ -44,160 +204,37 @@
      *
      * @param controllerSender passed as a parameter in case we want to display a new chip state
      *   when undo is clicked.
+     * @param undoCallback if present, the callback that should be called when the user clicks the
+     *   undo button. The undo button will only be shown if this is non-null.
      */
     open fun undoClickListener(
-        controllerSender: MediaTttChipControllerSender
+        controllerSender: MediaTttChipControllerSender,
+        routeInfo: MediaRoute2Info,
+        undoCallback: IUndoMediaTransferCallback?,
+        uiEventLogger: MediaTttSenderUiEventLogger
     ): View.OnClickListener? = null
-}
 
-/**
- * A state representing that the two devices are close but not close enough to *start* a cast to
- * the receiver device. The chip will instruct the user to move closer in order to initiate the
- * transfer to the receiver.
- *
- * @property otherDeviceName the name of the other device involved in the transfer.
- */
-class AlmostCloseToStartCast(
-    appPackageName: String?,
-    private val otherDeviceName: String,
-) : ChipStateSender(appPackageName) {
-    override fun getChipTextString(context: Context): String {
-        return context.getString(R.string.media_move_closer_to_start_cast, otherDeviceName)
-    }
-}
+    companion object {
+        /**
+         * Returns the sender state enum associated with the given [displayState] from
+         * [StatusBarManager].
+         */
+        fun getSenderStateFromId(
+            @StatusBarManager.MediaTransferSenderState displayState: Int,
+        ): ChipStateSender = values().first { it.stateInt == displayState }
 
-/**
- * A state representing that the two devices are close but not close enough to *end* a cast that's
- * currently occurring the receiver device. The chip will instruct the user to move closer in order
- * to initiate the transfer from the receiver and back onto this device (the original sender).
- *
- * @property otherDeviceName the name of the other device involved in the transfer.
- */
-class AlmostCloseToEndCast(
-    appPackageName: String?,
-    private val otherDeviceName: String,
-) : ChipStateSender(appPackageName) {
-    override fun getChipTextString(context: Context): String {
-        return context.getString(R.string.media_move_closer_to_end_cast, otherDeviceName)
-    }
-}
-
-/**
- * A state representing that a transfer to the receiver device has been initiated (but not
- * completed).
- *
- * @property otherDeviceName the name of the other device involved in the transfer.
- */
-class TransferToReceiverTriggered(
-    appPackageName: String?,
-    private val otherDeviceName: String
-) : ChipStateSender(appPackageName) {
-    override fun getChipTextString(context: Context): String {
-        return context.getString(R.string.media_transfer_playing_different_device, otherDeviceName)
-    }
-
-    override fun showLoading() = true
-    override fun getTimeoutMs() = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
-}
-
-/**
- * A state representing that a transfer from the receiver device and back to this device (the
- * sender) has been initiated (but not completed).
- */
-class TransferToThisDeviceTriggered(
-    appPackageName: String?,
-) : ChipStateSender(appPackageName) {
-    override fun getChipTextString(context: Context): String {
-        return context.getString(R.string.media_transfer_playing_this_device)
-    }
-
-    override fun showLoading() = true
-    override fun getTimeoutMs() = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
-}
-
-/**
- * A state representing that a transfer to the receiver device has been successfully completed.
- *
- * @property otherDeviceName the name of the other device involved in the transfer.
- * @property undoCallback if present, the callback that should be called when the user clicks the
- *   undo button. The undo button will only be shown if this is non-null.
- */
-class TransferToReceiverSucceeded(
-    appPackageName: String?,
-    private val otherDeviceName: String,
-    val undoCallback: IUndoMediaTransferCallback? = null
-) : ChipStateSender(appPackageName) {
-    override fun getChipTextString(context: Context): String {
-        return context.getString(R.string.media_transfer_playing_different_device, otherDeviceName)
-    }
-
-    override fun undoClickListener(
-        controllerSender: MediaTttChipControllerSender
-    ): View.OnClickListener? {
-        if (undoCallback == null) {
-            return null
-        }
-
-        return View.OnClickListener {
-            this.undoCallback.onUndoTriggered()
-            // The external service should eventually send us a TransferToThisDeviceTriggered state,
-            // but that may take too long to go through the binder and the user may be confused as
-            // to why the UI hasn't changed yet. So, we immediately change the UI here.
-            controllerSender.displayChip(
-                TransferToThisDeviceTriggered(this.appPackageName)
-            )
-        }
-    }
-}
-
-/**
- * A state representing that a transfer back to this device has been successfully completed.
- *
- * @property otherDeviceName the name of the other device involved in the transfer.
- * @property undoCallback if present, the callback that should be called when the user clicks the
- *   undo button. The undo button will only be shown if this is non-null.
- */
-class TransferToThisDeviceSucceeded(
-    appPackageName: String?,
-    private val otherDeviceName: String,
-    val undoCallback: IUndoMediaTransferCallback? = null
-) : ChipStateSender(appPackageName) {
-    override fun getChipTextString(context: Context): String {
-        return context.getString(R.string.media_transfer_playing_this_device)
-    }
-
-    override fun undoClickListener(
-        controllerSender: MediaTttChipControllerSender
-    ): View.OnClickListener? {
-        if (undoCallback == null) {
-            return null
-        }
-
-        return View.OnClickListener {
-            this.undoCallback.onUndoTriggered()
-            // The external service should eventually send us a TransferToReceiverTriggered state,
-            // but that may take too long to go through the binder and the user may be confused as
-            // to why the UI hasn't changed yet. So, we immediately change the UI here.
-            controllerSender.displayChip(
-                TransferToReceiverTriggered(
-                    this.appPackageName,
-                    this.otherDeviceName
-                )
-            )
-        }
-    }
-}
-
-/** A state representing that a transfer has failed. */
-class TransferFailed(
-    appPackageName: String?,
-) : ChipStateSender(appPackageName) {
-    override fun getChipTextString(context: Context): String {
-        return context.getString(R.string.media_transfer_failed)
+        /**
+         * Returns the state int from [StatusBarManager] associated with the given sender state
+         * name.
+         *
+         * @param name the name of one of the [ChipStateSender] enums.
+         */
+        @StatusBarManager.MediaTransferSenderState
+        fun getSenderStateIdFromName(name: String): Int = valueOf(name).stateInt
     }
 }
 
 // Give the Transfer*Triggered states a longer timeout since those states represent an active
 // process and we should keep the user informed about it as long as possible (but don't allow it to
 // continue indefinitely).
-private const val TRANSFER_TRIGGERED_TIMEOUT_MILLIS = 15000L
\ No newline at end of file
+private const val TRANSFER_TRIGGERED_TIMEOUT_MILLIS = 15000L
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
index da2aac4..9f5ec7e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
@@ -19,6 +19,7 @@
 import android.app.StatusBarManager
 import android.content.Context
 import android.media.MediaRoute2Info
+import android.os.PowerManager
 import android.util.Log
 import android.view.View
 import android.view.ViewGroup
@@ -28,6 +29,7 @@
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.media.taptotransfer.common.ChipInfoCommon
 import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCommon
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
 import com.android.systemui.media.taptotransfer.common.MediaTttRemovalReason
@@ -50,13 +52,16 @@
     viewUtil: ViewUtil,
     @Main mainExecutor: DelayableExecutor,
     tapGestureDetector: TapGestureDetector,
-) : MediaTttChipControllerCommon<ChipStateSender>(
+    powerManager: PowerManager,
+    private val uiEventLogger: MediaTttSenderUiEventLogger
+) : MediaTttChipControllerCommon<ChipSenderInfo>(
     context,
     logger,
     windowManager,
     viewUtil,
     mainExecutor,
     tapGestureDetector,
+    powerManager,
     R.layout.media_ttt_chip
 ) {
     private var currentlyDisplayedChipState: ChipStateSender? = null
@@ -82,104 +87,83 @@
         routeInfo: MediaRoute2Info,
         undoCallback: IUndoMediaTransferCallback?
     ) {
-        logger.logStateChange(stateIntToString(displayState), routeInfo.id)
-        val appPackageName = routeInfo.packageName
-        val otherDeviceName = routeInfo.name.toString()
-        val chipState = when(displayState) {
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST ->
-                AlmostCloseToStartCast(appPackageName, otherDeviceName)
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST ->
-                AlmostCloseToEndCast(appPackageName, otherDeviceName)
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED ->
-                TransferToReceiverTriggered(appPackageName, otherDeviceName)
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED ->
-                TransferToThisDeviceTriggered(appPackageName)
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED ->
-                TransferToReceiverSucceeded(appPackageName, otherDeviceName, undoCallback)
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED ->
-                TransferToThisDeviceSucceeded(appPackageName, otherDeviceName, undoCallback)
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED ->
-                TransferFailed(appPackageName)
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER -> {
-                removeChip(removalReason = FAR_FROM_RECEIVER)
-                null
-            }
-            else -> {
-                Log.e(SENDER_TAG, "Unhandled MediaTransferSenderState $displayState")
-                null
-            }
-        }
+        val chipState: ChipStateSender? = ChipStateSender.getSenderStateFromId(displayState)
+        val stateName = chipState?.name ?: "Invalid"
+        logger.logStateChange(stateName, routeInfo.id)
 
-        chipState?.let {
-            displayChip(it)
+        if (chipState == null) {
+            Log.e(SENDER_TAG, "Unhandled MediaTransferSenderState $displayState")
+            return
+        }
+        uiEventLogger.logSenderStateChange(chipState)
+
+        if (chipState == ChipStateSender.FAR_FROM_RECEIVER) {
+            removeChip(removalReason = ChipStateSender.FAR_FROM_RECEIVER::class.simpleName!!)
+        } else {
+            displayChip(ChipSenderInfo(chipState, routeInfo, undoCallback))
         }
     }
 
     /** Displays the chip view for the given state. */
-    override fun updateChipView(chipState: ChipStateSender, currentChipView: ViewGroup) {
+    override fun updateChipView(
+            chipInfo: ChipSenderInfo,
+            currentChipView: ViewGroup) {
+        val chipState = chipInfo.state
         currentlyDisplayedChipState = chipState
 
         // App icon
-        setIcon(chipState, currentChipView)
+        setIcon(currentChipView, chipInfo.routeInfo.packageName)
 
         // Text
+        val otherDeviceName = chipInfo.routeInfo.name.toString()
         currentChipView.requireViewById<TextView>(R.id.text).apply {
-            text = chipState.getChipTextString(context)
+            text = chipState.getChipTextString(context, otherDeviceName)
         }
 
         // Loading
         currentChipView.requireViewById<View>(R.id.loading).visibility =
-            if (chipState.showLoading()) { View.VISIBLE } else { View.GONE }
+            chipState.isMidTransfer.visibleIfTrue()
+
 
         // Undo
         val undoView = currentChipView.requireViewById<View>(R.id.undo)
-        val undoClickListener = chipState.undoClickListener(this)
+        val undoClickListener = chipState.undoClickListener(
+                this, chipInfo.routeInfo, chipInfo.undoCallback, uiEventLogger
+        )
         undoView.setOnClickListener(undoClickListener)
-        undoView.visibility = if (undoClickListener != null) { View.VISIBLE } else { View.GONE }
+        undoView.visibility = (undoClickListener != null).visibleIfTrue()
 
         // Failure
-        val showFailure = chipState is TransferFailed
         currentChipView.requireViewById<View>(R.id.failure_icon).visibility =
-            if (showFailure) { View.VISIBLE } else { View.GONE }
+            chipState.isTransferFailure.visibleIfTrue()
     }
 
     override fun removeChip(removalReason: String) {
         // Don't remove the chip if we're mid-transfer since the user should still be able to
         // see the status of the transfer. (But do remove it if it's finally timed out.)
-        if ((currentlyDisplayedChipState is TransferToReceiverTriggered ||
-                currentlyDisplayedChipState is TransferToThisDeviceTriggered)
-            && removalReason != MediaTttRemovalReason.REASON_TIMEOUT) {
+        if (currentlyDisplayedChipState?.isMidTransfer == true
+                && removalReason != MediaTttRemovalReason.REASON_TIMEOUT) {
             return
         }
         super.removeChip(removalReason)
         currentlyDisplayedChipState = null
     }
 
-    private fun stateIntToString(@StatusBarManager.MediaTransferSenderState state: Int): String {
-        return when(state) {
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST ->
-                "ALMOST_CLOSE_TO_START_CAST"
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST ->
-                "ALMOST_CLOSE_TO_END_CAST"
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED ->
-                "TRANSFER_TO_RECEIVER_TRIGGERED"
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED ->
-                "TRANSFER_TO_THIS_DEVICE_TRIGGERED"
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED ->
-                "TRANSFER_TO_RECEIVER_SUCCEEDED"
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED ->
-                "TRANSFER_TO_THIS_DEVICE_SUCCEEDED"
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED ->
-                "TRANSFER_TO_RECEIVER_FAILED"
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED ->
-                "TRANSFER_TO_THIS_DEVICE_FAILED"
-            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER ->
-                FAR_FROM_RECEIVER
-            else -> "INVALID: $state"
+    private fun Boolean.visibleIfTrue(): Int {
+        return if (this) {
+            View.VISIBLE
+        } else {
+            View.GONE
         }
     }
 }
 
+data class ChipSenderInfo(
+    val state: ChipStateSender,
+    val routeInfo: MediaRoute2Info,
+    val undoCallback: IUndoMediaTransferCallback? = null
+) : ChipInfoCommon {
+    override fun getTimeoutMs() = state.timeout
+}
+
 const val SENDER_TAG = "MediaTapToTransferSender"
-private const val FAR_FROM_RECEIVER = "FAR_FROM_RECEIVER"
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
new file mode 100644
index 0000000..af3c1b6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
@@ -0,0 +1,82 @@
+/*
+ * 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.taptotransfer.sender
+
+import android.util.Log
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/** A class for analytics logging for the media tap-to-transfer chip on the sender device. */
+@SysUISingleton
+class MediaTttSenderUiEventLogger @Inject constructor(private val logger: UiEventLogger) {
+    /** Logs that the sender chip has changed states. */
+    fun logSenderStateChange(chipState: ChipStateSender) {
+        logger.log(chipState.uiEvent)
+    }
+
+    /**
+     * Logs that the undo button was clicked.
+     *
+     * @param undoUiEvent the uiEvent specific to which undo button was clicked.
+     */
+    fun logUndoClicked(undoUiEvent: UiEventLogger.UiEventEnum) {
+        val isUndoEvent =
+            undoUiEvent == MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED
+                    || undoUiEvent ==
+                    MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
+        if (!isUndoEvent) {
+            Log.w(
+                MediaTttSenderUiEventLogger::class.simpleName!!,
+            "Must pass an undo-specific UiEvent."
+            )
+            return
+        }
+        logger.log(undoUiEvent)
+    }
+}
+
+enum class MediaTttSenderUiEvents(val metricId: Int) : UiEventLogger.UiEventEnum {
+    @UiEvent(doc = "The undo button on the media ttt chip on the sender device was clicked " +
+            "to undo the transfer to the receiver device")
+    MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED(971),
+    @UiEvent(doc = "The undo button on the media ttt chip on the sender device was clicked " +
+            "to undo the transfer back to this device")
+    MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED(972),
+
+    @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+    MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST(973),
+    @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+    MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST(974),
+    @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+    MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED(975),
+    @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+    MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED(976),
+    @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+    MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED(977),
+    @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+    MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED(978),
+    @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+    MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED(979),
+    @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+    MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED(980),
+    @UiEvent(doc = "See android.app.StatusBarManager.MEDIA_TRANSFER_SENDER_* docs")
+    MEDIA_TTT_SENDER_FAR_FROM_RECEIVER(981);
+
+    override fun getId() = metricId
+}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 039c333..2ac34b2 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -60,6 +60,7 @@
 import com.android.settingslib.utils.PowerUtil;
 import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
+import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
@@ -97,7 +98,7 @@
         "SHOWING_AUTO_SAVER_SUGGESTION",
     };
 
-    private static final String ACTION_SHOW_BATTERY_SETTINGS = "PNW.batterySettings";
+    private static final String ACTION_SHOW_BATTERY_SAVER_SETTINGS = "PNW.batterySaverSettings";
     private static final String ACTION_START_SAVER = "PNW.startSaver";
     private static final String ACTION_DISMISSED_WARNING = "PNW.dismissedWarning";
     private static final String ACTION_CLICKED_TEMP_WARNING = "PNW.clickedTempWarning";
@@ -120,8 +121,6 @@
 
     private static final String ACTION_ENABLE_SEVERE_BATTERY_DIALOG = "PNW.enableSevereDialog";
 
-    private static final String SETTINGS_ACTION_OPEN_BATTERY_SAVER_SETTING =
-            "android.settings.BATTERY_SAVER_SETTINGS";
     public static final String BATTERY_SAVER_SCHEDULE_SCREEN_INTENT_ACTION =
             "com.android.settings.BATTERY_SAVER_SCHEDULE_SETTINGS";
 
@@ -140,6 +139,9 @@
     private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final Receiver mReceiver = new Receiver();
     private final Intent mOpenBatterySettings = settings(Intent.ACTION_POWER_USAGE_SUMMARY);
+    private final Intent mOpenBatterySaverSettings =
+            settings(Settings.ACTION_BATTERY_SAVER_SETTINGS);
+    private final boolean mUseSevereDialog;
 
     private int mBatteryLevel;
     private int mBucket;
@@ -159,17 +161,21 @@
     @VisibleForTesting SystemUIDialog mUsbHighTempDialog;
     private BatteryStateSnapshot mCurrentBatterySnapshot;
     private ActivityStarter mActivityStarter;
+    private final BroadcastSender mBroadcastSender;
 
     /**
      */
     @Inject
-    public PowerNotificationWarnings(Context context, ActivityStarter activityStarter) {
+    public PowerNotificationWarnings(Context context, ActivityStarter activityStarter,
+            BroadcastSender broadcastSender) {
         mContext = context;
         mNoMan = mContext.getSystemService(NotificationManager.class);
         mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mKeyguard = mContext.getSystemService(KeyguardManager.class);
         mReceiver.init();
         mActivityStarter = activityStarter;
+        mBroadcastSender = broadcastSender;
+        mUseSevereDialog = mContext.getResources().getBoolean(R.bool.config_severe_battery_dialog);
     }
 
     @Override
@@ -256,7 +262,7 @@
 
     protected void showWarningNotification() {
         if (showSevereLowBatteryDialog()) {
-            mContext.sendBroadcast(new Intent(ACTION_ENABLE_SEVERE_BATTERY_DIALOG)
+            mBroadcastSender.sendBroadcast(new Intent(ACTION_ENABLE_SEVERE_BATTERY_DIALOG)
                     .setPackage(mContext.getPackageName())
                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                             | Intent.FLAG_RECEIVER_FOREGROUND));
@@ -283,11 +289,11 @@
                         .setContentText(contentText)
                         .setContentTitle(title)
                         .setOnlyAlertOnce(true)
-                        .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_WARNING))
+                        .setOngoing(true)
                         .setStyle(new Notification.BigTextStyle().bigText(contentText))
                         .setVisibility(Notification.VISIBILITY_PUBLIC);
         if (hasBatterySettings()) {
-            nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
+            nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SAVER_SETTINGS));
         }
         // Make the notification red if the percentage goes below a certain amount or the time
         // remaining estimate is disabled
@@ -298,6 +304,8 @@
         }
 
         if (!mPowerMan.isPowerSaveMode()) {
+            nb.addAction(0, mContext.getString(R.string.battery_saver_dismiss_action),
+                    pendingBroadcast(ACTION_DISMISSED_WARNING));
             nb.addAction(0,
                     mContext.getString(R.string.battery_saver_start_action),
                     pendingBroadcast(ACTION_START_SAVER));
@@ -312,9 +320,7 @@
 
     private boolean showSevereLowBatteryDialog() {
         final boolean isSevereState = !mCurrentBatterySnapshot.isHybrid() || mBucket < -1;
-        final boolean useSevereDialog = mContext.getResources().getBoolean(
-                R.bool.config_severe_battery_dialog);
-        return isSevereState && useSevereDialog;
+        return isSevereState && mUseSevereDialog;
     }
 
     private void showAutoSaverSuggestionNotification() {
@@ -714,9 +720,9 @@
                         mSaverConfirmation.dismiss();
                     }
                     // Also close the notification shade, if it's open.
-                    mContext.sendBroadcast(
+                    mBroadcastSender.sendBroadcast(
                             new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
-                            .setFlags(Intent.FLAG_RECEIVER_FOREGROUND));
+                                    .setFlags(Intent.FLAG_RECEIVER_FOREGROUND));
 
                     final Uri uri = Uri.parse(getURL());
                     Context context = widget.getContext();
@@ -748,7 +754,7 @@
 
         public void init() {
             IntentFilter filter = new IntentFilter();
-            filter.addAction(ACTION_SHOW_BATTERY_SETTINGS);
+            filter.addAction(ACTION_SHOW_BATTERY_SAVER_SETTINGS);
             filter.addAction(ACTION_START_SAVER);
             filter.addAction(ACTION_DISMISSED_WARNING);
             filter.addAction(ACTION_CLICKED_TEMP_WARNING);
@@ -768,9 +774,9 @@
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
             Slog.i(TAG, "Received " + action);
-            if (action.equals(ACTION_SHOW_BATTERY_SETTINGS)) {
+            if (action.equals(ACTION_SHOW_BATTERY_SAVER_SETTINGS)) {
                 dismissLowBatteryNotification();
-                mContext.startActivityAsUser(mOpenBatterySettings, UserHandle.CURRENT);
+                mContext.startActivityAsUser(mOpenBatterySaverSettings, UserHandle.CURRENT);
             } else if (action.equals(ACTION_START_SAVER)) {
                 setSaverMode(true, true);
                 dismissLowBatteryNotification();
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 56528c9..61b434d 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -51,7 +51,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.time.Duration;
 import java.util.Arrays;
 import java.util.Optional;
 import java.util.concurrent.Future;
@@ -70,7 +69,6 @@
     private static final int MAX_RECENT_TEMPS = 125; // TEMPERATURE_LOGGING_INTERVAL plus a buffer
     static final long THREE_HOURS_IN_MILLIS = DateUtils.HOUR_IN_MILLIS * 3;
     private static final int CHARGE_CYCLE_PERCENT_RESET = 30;
-    private static final long SIX_HOURS_MILLIS = Duration.ofHours(6).toMillis();
     public static final int NO_ESTIMATE_AVAILABLE = -1;
     private static final String BOOT_COUNT_KEY = "boot_count";
     private static final String PREFS = "powerui_prefs";
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index 9cd97ff8..2a6ca1a 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -22,13 +22,14 @@
 import android.widget.LinearLayout
 import com.android.settingslib.Utils
 import com.android.systemui.R
+import com.android.systemui.statusbar.events.BackgroundAnimatableView
 
 class OngoingPrivacyChip @JvmOverloads constructor(
     context: Context,
     attrs: AttributeSet? = null,
     defStyleAttrs: Int = 0,
     defStyleRes: Int = 0
-) : FrameLayout(context, attrs, defStyleAttrs, defStyleRes) {
+) : FrameLayout(context, attrs, defStyleAttrs, defStyleRes), BackgroundAnimatableView {
 
     private var iconMargin = 0
     private var iconSize = 0
@@ -50,6 +51,16 @@
         updateResources()
     }
 
+    /**
+     * When animating as a chip in the status bar, we want to animate the width for the container
+     * of the privacy items. We have to subtract our own top and left offset because the bounds
+     * come to us as absolute on-screen bounds, and `iconsContainer` is laid out relative to the
+     * frame layout's bounds.
+     */
+    override fun setBoundsForAnimation(l: Int, t: Int, r: Int, b: Int) {
+        iconsContainer.setLeftTopRightBottom(l - left, t - top, r - left, b - top)
+    }
+
     // Should only be called if the builder icons or app changed
     private fun updateView(builder: PrivacyChipBuilder) {
         fun setIcons(chipBuilder: PrivacyChipBuilder, iconsContainer: ViewGroup) {
diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java b/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java
index e26c768..8000bdc 100644
--- a/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java
+++ b/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java
@@ -160,14 +160,15 @@
      * Returns true if lock screen entry point for QR Code Scanner is to be enabled.
      */
     public boolean isEnabledForLockScreenButton() {
-        return mQRCodeScannerEnabled && mIntent != null && mConfigEnableLockScreenButton;
+        return mQRCodeScannerEnabled && mIntent != null && mConfigEnableLockScreenButton
+                && isActivityCallable(mIntent);
     }
 
     /**
      * Returns true if quick settings entry point for QR Code Scanner is to be enabled.
      */
     public boolean isEnabledForQuickSettings() {
-        return mIntent != null;
+        return mIntent != null && isActivityCallable(mIntent);
     }
 
     /**
@@ -278,7 +279,7 @@
             intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
         }
 
-        if (isActivityCallable(intent)) {
+        if (isActivityAvailable(intent)) {
             mQRCodeScannerActivity = qrCodeScannerActivity;
             mComponentName = componentName;
             mIntent = intent;
@@ -293,7 +294,7 @@
         }
     }
 
-    private boolean isActivityCallable(Intent intent) {
+    private boolean isActivityAvailable(Intent intent) {
         // Our intent should always be explicit and should have a component set
         if (intent.getComponent() == null) return false;
 
@@ -307,6 +308,17 @@
                 flags).isEmpty();
     }
 
+    private boolean isActivityCallable(Intent intent) {
+        // Our intent should always be explicit and should have a component set
+        if (intent.getComponent() == null) return false;
+
+        int flags = PackageManager.MATCH_DIRECT_BOOT_AWARE
+                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+                | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
+        return !mContext.getPackageManager().queryIntentActivities(intent,
+                flags).isEmpty();
+    }
+
     private void unregisterUserChangeObservers() {
         mUserTracker.removeCallback(mUserChangedListener);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index 5d9361d..e0d158c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -18,7 +18,10 @@
 
 import android.app.IActivityManager
 import android.app.IForegroundServiceObserver
+import android.content.BroadcastReceiver
 import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
 import android.content.pm.PackageManager
 import android.graphics.drawable.Drawable
 import android.os.IBinder
@@ -42,6 +45,7 @@
 import com.android.systemui.Dumpable
 import com.android.systemui.R
 import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
@@ -67,6 +71,7 @@
     private val packageManager: PackageManager,
     private val deviceConfigProxy: DeviceConfigProxy,
     private val dialogLaunchAnimator: DialogLaunchAnimator,
+    private val broadcastDispatcher: BroadcastDispatcher,
     private val dumpManager: DumpManager
 ) : IForegroundServiceObserver.Stub(), Dumpable {
 
@@ -125,6 +130,18 @@
 
             dumpManager.registerDumpable(this)
 
+            broadcastDispatcher.registerReceiver(
+                    object : BroadcastReceiver() {
+                        override fun onReceive(context: Context, intent: Intent) {
+                            if (intent.action == Intent.ACTION_SHOW_FOREGROUND_SERVICE_MANAGER) {
+                                showDialog(null)
+                            }
+                        }
+                    },
+                    IntentFilter(Intent.ACTION_SHOW_FOREGROUND_SERVICE_MANAGER),
+                    executor = mainExecutor,
+                    flags = Context.RECEIVER_NOT_EXPORTED)
+
             initialized = true
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index d1b569f..4640205 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -241,7 +241,13 @@
 
     private void addNonFirstPageAnimators(int page) {
         Pair<HeightExpansionAnimator, TouchAnimator> pair = createSecondaryPageAnimators(page);
-        mNonFirstPageQSAnimators.put(page, pair);
+        if (pair != null) {
+            // pair is null in one of two cases:
+            // * mPagedTileLayout is null, meaning we are still setting up.
+            // * the page has no tiles
+            // In either case, don't add the animators to the map.
+            mNonFirstPageQSAnimators.put(page, pair);
+        }
     }
 
     @Override
@@ -518,6 +524,13 @@
         SideLabelTileLayout qqsLayout = (SideLabelTileLayout) mQuickQsPanel.getTileLayout();
         View view = mQs.getView();
         List<String> specs = mPagedLayout.getSpecsForPage(page);
+        if (specs.isEmpty()) {
+            // specs should not be empty in a valid secondary page, as we scrolled to it.
+            // We may crash later on because there's a null animator.
+            specs = mQsPanelController.getHost().mTileSpecs;
+            Log.e(TAG, "Trying to create animators for empty page " + page + ". Tiles: " + specs);
+            // return null;
+        }
 
         int row = -1;
         int lastTileTop = -1;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 3ef7220..fe8c309 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -573,6 +573,7 @@
         if (mQSAnimator != null) {
             mQSAnimator.setPosition(expansion);
         }
+        mQqsMediaHost.setSquishFraction(mSquishinessFraction);
         updateMediaPositions();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index 0014279..865f093 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -199,9 +199,7 @@
 
     /** */
     public void setListening(boolean listening, boolean expanded) {
-        // TODO(218268829): checking for split shade is workaround but when proper fix lands
-        //  "|| mShouldUseSplitNotificationShade" should be removed
-        setListening(listening && (expanded || mShouldUseSplitNotificationShade));
+        setListening(listening && expanded);
         if (mView.isListening()) {
             refreshAllTiles();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 8c08873..f2dd770 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -102,7 +102,7 @@
     private int mTopViewMeasureHeight;
 
     @NonNull
-    private List<String> mRssiIgnoredSlots;
+    private List<String> mRssiIgnoredSlots = List.of();
     private boolean mIsSingleCarrier;
 
     private boolean mHasCenterCutout;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 32515a2..4cacbba 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -15,26 +15,22 @@
  */
 package com.android.systemui.qs.external;
 
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.graphics.drawable.Icon;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.quicksettings.IQSService;
 import android.service.quicksettings.Tile;
-import android.service.quicksettings.TileService;
 import android.util.ArrayMap;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.internal.statusbar.StatusBarIcon;
@@ -42,6 +38,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
@@ -51,6 +48,7 @@
 import java.util.Objects;
 
 import javax.inject.Inject;
+import javax.inject.Provider;
 
 /**
  * Runs the day-to-day operations of which tiles should be bound and when.
@@ -64,11 +62,12 @@
     private final ArrayMap<ComponentName, CustomTile> mTiles = new ArrayMap<>();
     private final ArrayMap<IBinder, CustomTile> mTokenMap = new ArrayMap<>();
     private final Context mContext;
-    private final Handler mHandler;
     private final Handler mMainHandler;
+    private final Provider<Handler> mHandlerProvider;
     private final QSTileHost mHost;
     private final KeyguardStateController mKeyguardStateController;
     private final BroadcastDispatcher mBroadcastDispatcher;
+    private final CommandQueue mCommandQueue;
     private final UserTracker mUserTracker;
 
     private int mMaxBound = DEFAULT_MAX_BOUND;
@@ -76,23 +75,20 @@
     @Inject
     public TileServices(
             QSTileHost host,
-            @Main Looper looper,
+            @Main Provider<Handler> handlerProvider,
             BroadcastDispatcher broadcastDispatcher,
             UserTracker userTracker,
-            KeyguardStateController keyguardStateController) {
+            KeyguardStateController keyguardStateController,
+            CommandQueue commandQueue) {
         mHost = host;
         mKeyguardStateController = keyguardStateController;
         mContext = mHost.getContext();
         mBroadcastDispatcher = broadcastDispatcher;
-        mHandler = new Handler(looper);
-        mMainHandler = new Handler(Looper.getMainLooper());
+        mHandlerProvider = handlerProvider;
+        mMainHandler = mHandlerProvider.get();
         mUserTracker = userTracker;
-        mBroadcastDispatcher.registerReceiver(
-                mRequestListeningReceiver,
-                new IntentFilter(TileService.ACTION_REQUEST_LISTENING),
-                null, // Use the default Executor
-                UserHandle.ALL
-        );
+        mCommandQueue = commandQueue;
+        mCommandQueue.addCallback(mRequestListeningCallback);
     }
 
     public Context getContext() {
@@ -118,7 +114,7 @@
 
     protected TileServiceManager onCreateTileService(ComponentName component,
             BroadcastDispatcher broadcastDispatcher) {
-        return new TileServiceManager(this, mHandler, component,
+        return new TileServiceManager(this, mHandlerProvider.get(), component,
                 broadcastDispatcher, mUserTracker);
     }
 
@@ -354,21 +350,14 @@
     public void destroy() {
         synchronized (mServices) {
             mServices.values().forEach(service -> service.handleDestroy());
-            mBroadcastDispatcher.unregisterReceiver(mRequestListeningReceiver);
         }
+        mCommandQueue.removeCallback(mRequestListeningCallback);
     }
 
-    private final BroadcastReceiver mRequestListeningReceiver = new BroadcastReceiver() {
+    private final CommandQueue.Callbacks mRequestListeningCallback = new CommandQueue.Callbacks() {
         @Override
-        public void onReceive(Context context, Intent intent) {
-            if (TileService.ACTION_REQUEST_LISTENING.equals(intent.getAction())) {
-                try {
-                    ComponentName c = intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME);
-                    requestListening(c);
-                } catch (ClassCastException ex) {
-                    Log.e(TAG, "Bad component name", ex);
-                }
-            }
+        public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
+            mMainHandler.post(() -> requestListening(componentName));
         }
     };
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java
index b658025..b415022 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java
@@ -117,7 +117,6 @@
         state.icon = ResourceIcon.get(R.drawable.ic_qr_code_scanner);
         state.state = mQRCodeScannerController.isEnabledForQuickSettings() ? Tile.STATE_ACTIVE
                 : Tile.STATE_UNAVAILABLE;
-        state.secondaryLabel = mContext.getString(R.string.qr_code_scanner_description);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
index e1d2070..8bad2de 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
@@ -47,9 +47,6 @@
 public class InternetAdapter extends RecyclerView.Adapter<InternetAdapter.InternetViewHolder> {
 
     private static final String TAG = "InternetAdapter";
-    private static final String ACTION_WIFI_DIALOG = "com.android.settings.WIFI_DIALOG";
-    private static final String EXTRA_CHOSEN_WIFI_ENTRY_KEY = "key_chosen_wifientry_key";
-    private static final String EXTRA_CONNECT_FOR_CALLER = "connect_for_caller";
 
     private final InternetDialogController mInternetDialogController;
     @Nullable
@@ -169,11 +166,10 @@
             }
             mWifiListLayout.setOnClickListener(v -> {
                 if (wifiEntry.shouldEditBeforeConnect()) {
-                    final Intent intent = new Intent(ACTION_WIFI_DIALOG);
+                    final Intent intent = WifiUtils.getWifiDialogIntent(wifiEntry.getKey(),
+                            true /* connectForCaller */);
                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                     intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
-                    intent.putExtra(EXTRA_CHOSEN_WIFI_ENTRY_KEY, wifiEntry.getKey());
-                    intent.putExtra(EXTRA_CONNECT_FOR_CALLER, false);
                     mContext.startActivity(intent);
                 }
                 mInternetDialogController.connect(wifiEntry);
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 b3bc3be..b322cbf 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
@@ -112,7 +112,6 @@
             "android.settings.NETWORK_PROVIDER_SETTINGS";
     private static final String ACTION_WIFI_SCANNING_SETTINGS =
             "android.settings.WIFI_SCANNING_SETTINGS";
-    private static final String EXTRA_CHOSEN_WIFI_ENTRY_KEY = "key_chosen_wifientry_key";
     public static final Drawable EMPTY_DRAWABLE = new ColorDrawable(Color.TRANSPARENT);
     public static final int NO_CELL_DATA_TYPE_ICON = 0;
     private static final int SUBTITLE_TEXT_WIFI_IS_OFF = R.string.wifi_is_off;
@@ -853,8 +852,8 @@
             }
 
             if (status == WifiEntry.ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG) {
-                final Intent intent = new Intent("com.android.settings.WIFI_DIALOG")
-                        .putExtra(EXTRA_CHOSEN_WIFI_ENTRY_KEY, mWifiEntry.getKey());
+                final Intent intent = WifiUtils.getWifiDialogIntent(mWifiEntry.getKey(),
+                        true /* connectForCaller */);
                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 mActivityStarter.startActivity(intent, false /* dismissShade */);
             } else if (status == CONNECT_STATUS_FAILURE_UNKNOWN) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java b/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java
new file mode 100644
index 0000000..0b98767
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot;
+
+import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM;
+import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.MathUtils;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewTreeObserver;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.android.systemui.R;
+
+/**
+ * ConstraintLayout that is draggable when touched in a specific region
+ */
+public class DraggableConstraintLayout extends ConstraintLayout
+        implements ViewTreeObserver.OnComputeInternalInsetsListener {
+
+    private final SwipeDismissHandler mSwipeDismissHandler;
+    private final GestureDetector mSwipeDetector;
+    private View mActionsContainer;
+    private SwipeDismissCallbacks mCallbacks;
+
+    /**
+     * Stores the callbacks when the view is interacted with or dismissed.
+     */
+    public interface SwipeDismissCallbacks {
+        /**
+         * Run when the view is interacted with (touched)
+         */
+        default void onInteraction() {
+
+        }
+
+        /**
+         * Run when the view is dismissed (the distance threshold is met), pre-dismissal animation
+         */
+        default void onSwipeDismissInitiated(Animator animator) {
+
+        }
+
+        /**
+         * Run when the view is dismissed (the distance threshold is met), post-dismissal animation
+         */
+        default void onDismissComplete() {
+
+        }
+    }
+
+    public DraggableConstraintLayout(Context context) {
+        this(context, null);
+    }
+
+    public DraggableConstraintLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public DraggableConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+
+        mSwipeDismissHandler = new SwipeDismissHandler(mContext, this);
+        setOnTouchListener(mSwipeDismissHandler);
+
+        mSwipeDetector = new GestureDetector(mContext,
+                new GestureDetector.SimpleOnGestureListener() {
+                    final Rect mActionsRect = new Rect();
+
+                    @Override
+                    public boolean onScroll(
+                            MotionEvent ev1, MotionEvent ev2, float distanceX, float distanceY) {
+                        mActionsContainer.getBoundsOnScreen(mActionsRect);
+                        // return true if we aren't in the actions bar, or if we are but it isn't
+                        // scrollable in the direction of movement
+                        return !mActionsRect.contains((int) ev2.getRawX(), (int) ev2.getRawY())
+                                || !mActionsContainer.canScrollHorizontally((int) distanceX);
+                    }
+                });
+        mSwipeDetector.setIsLongpressEnabled(false);
+    }
+
+    public void setCallbacks(SwipeDismissCallbacks callbacks) {
+        mCallbacks = callbacks;
+    }
+
+    @Override // View
+    protected void onFinishInflate() {
+        mActionsContainer = findViewById(R.id.actions_container_background);
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
+            mSwipeDismissHandler.onTouch(this, ev);
+        }
+        return mSwipeDetector.onTouchEvent(ev);
+    }
+
+    public int getVisibleRight() {
+        return mActionsContainer.getRight();
+    }
+
+    /**
+     * Cancel current dismissal animation, if any
+     */
+    public void cancelDismissal() {
+        mSwipeDismissHandler.cancel();
+    }
+
+    /**
+     * Return whether the view is currently dismissing
+     */
+    public boolean isDismissing() {
+        return mSwipeDismissHandler.isDismissing();
+    }
+
+    /**
+     * Dismiss the view, with animation controlled by SwipeDismissHandler
+     */
+    public void dismiss() {
+        mSwipeDismissHandler.dismiss();
+    }
+
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        getViewTreeObserver().addOnComputeInternalInsetsListener(this);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
+    }
+
+    @Override
+    public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
+        // Only child views are touchable.
+        Region r = new Region();
+        Rect rect = new Rect();
+        for (int i = 0; i < getChildCount(); i++) {
+            getChildAt(i).getGlobalVisibleRect(rect);
+            r.op(rect, Region.Op.UNION);
+        }
+        inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+        inoutInfo.touchableRegion.set(r);
+    }
+
+    /**
+     * Allows a view to be swipe-dismissed, or returned to its location if distance threshold is not
+     * met
+     */
+    private class SwipeDismissHandler implements OnTouchListener {
+        private static final String TAG = "SwipeDismissHandler";
+
+        // distance needed to register a dismissal
+        private static final float DISMISS_DISTANCE_THRESHOLD_DP = 20;
+
+        private final DraggableConstraintLayout mView;
+        private final GestureDetector mGestureDetector;
+        private final DisplayMetrics mDisplayMetrics;
+        private ValueAnimator mDismissAnimation;
+
+        private float mStartX;
+        // Keeps track of the most recent direction (between the last two move events).
+        // -1 for left; +1 for right.
+        private int mDirectionX;
+        private float mPreviousX;
+
+        SwipeDismissHandler(Context context, DraggableConstraintLayout view) {
+            mView = view;
+            GestureDetector.OnGestureListener gestureListener = new SwipeDismissGestureListener();
+            mGestureDetector = new GestureDetector(context, gestureListener);
+            mDisplayMetrics = new DisplayMetrics();
+            context.getDisplay().getRealMetrics(mDisplayMetrics);
+            mCallbacks = new SwipeDismissCallbacks() {
+            }; // default to unimplemented callbacks
+        }
+
+        @Override
+        public boolean onTouch(View view, MotionEvent event) {
+            boolean gestureResult = mGestureDetector.onTouchEvent(event);
+            mCallbacks.onInteraction();
+            if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+                mStartX = event.getRawX();
+                mPreviousX = mStartX;
+                return true;
+            } else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+                if (mDismissAnimation != null && mDismissAnimation.isRunning()) {
+                    return true;
+                }
+                if (isPastDismissThreshold()) {
+                    dismiss();
+                } else {
+                    // if we've moved, but not past the threshold, start the return animation
+                    if (DEBUG_DISMISS) {
+                        Log.d(TAG, "swipe gesture abandoned");
+                    }
+                    createSwipeReturnAnimation().start();
+                }
+                return true;
+            }
+            return gestureResult;
+        }
+
+        class SwipeDismissGestureListener extends GestureDetector.SimpleOnGestureListener {
+            @Override
+            public boolean onScroll(
+                    MotionEvent ev1, MotionEvent ev2, float distanceX, float distanceY) {
+                mView.setTranslationX(ev2.getRawX() - mStartX);
+                mDirectionX = (ev2.getRawX() < mPreviousX) ? -1 : 1;
+                mPreviousX = ev2.getRawX();
+                return true;
+            }
+
+            @Override
+            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
+                    float velocityY) {
+                if (mView.getTranslationX() * velocityX > 0
+                        && (mDismissAnimation == null || !mDismissAnimation.isRunning())) {
+                    ValueAnimator dismissAnimator =
+                            createSwipeDismissAnimation(velocityX / (float) 1000);
+                    mCallbacks.onSwipeDismissInitiated(dismissAnimator);
+                    dismiss(dismissAnimator);
+                    return true;
+                }
+                return false;
+            }
+        }
+
+        private boolean isPastDismissThreshold() {
+            float translationX = mView.getTranslationX();
+            // Determines whether the absolute translation from the start is in the same direction
+            // as the current movement. For example, if the user moves most of the way to the right,
+            // but then starts dragging back left, we do not dismiss even though the absolute
+            // distance is greater than the threshold.
+            if (translationX * mDirectionX > 0) {
+                return Math.abs(translationX) >= FloatingWindowUtil.dpToPx(mDisplayMetrics,
+                        DISMISS_DISTANCE_THRESHOLD_DP);
+            }
+            return false;
+        }
+
+        boolean isDismissing() {
+            return (mDismissAnimation != null && mDismissAnimation.isRunning());
+        }
+
+        void cancel() {
+            if (isDismissing()) {
+                if (DEBUG_ANIM) {
+                    Log.d(TAG, "cancelling dismiss animation");
+                }
+                mDismissAnimation.cancel();
+            }
+        }
+
+        void dismiss() {
+            ValueAnimator anim = createSwipeDismissAnimation(3);
+            mCallbacks.onSwipeDismissInitiated(anim);
+            dismiss(anim);
+        }
+
+        private void dismiss(ValueAnimator animator) {
+            mDismissAnimation = animator;
+            mDismissAnimation.addListener(new AnimatorListenerAdapter() {
+                private boolean mCancelled;
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    super.onAnimationCancel(animation);
+                    mCancelled = true;
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    super.onAnimationEnd(animation);
+                    if (!mCancelled) {
+                        mCallbacks.onDismissComplete();
+                    }
+                }
+            });
+            mDismissAnimation.start();
+        }
+
+        private ValueAnimator createSwipeDismissAnimation(float velocity) {
+            // velocity is measured in pixels per millisecond
+            velocity = Math.min(3, Math.max(1, velocity));
+            ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+            float startX = mView.getTranslationX();
+            // make sure the UI gets all the way off the screen in the direction of movement
+            // (the actions container background is guaranteed to be both the leftmost and
+            // rightmost UI element in LTR and RTL)
+            float finalX;
+            int layoutDir =
+                    mView.getContext().getResources().getConfiguration().getLayoutDirection();
+            if (startX > 0 || (startX == 0 && layoutDir == LAYOUT_DIRECTION_RTL)) {
+                finalX = mDisplayMetrics.widthPixels;
+            } else {
+                finalX = -1 * mActionsContainer.getRight();
+            }
+            float distance = Math.abs(finalX - startX);
+
+            anim.addUpdateListener(animation -> {
+                float translation = MathUtils.lerp(startX, finalX, animation.getAnimatedFraction());
+                mView.setTranslationX(translation);
+                mView.setAlpha(1 - animation.getAnimatedFraction());
+            });
+            anim.setDuration((long) (distance / Math.abs(velocity)));
+            return anim;
+        }
+
+        private ValueAnimator createSwipeReturnAnimation() {
+            ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+            float startX = mView.getTranslationX();
+            float finalX = 0;
+
+            anim.addUpdateListener(animation -> {
+                float translation = MathUtils.lerp(
+                        startX, finalX, animation.getAnimatedFraction());
+                mView.setTranslationX(translation);
+            });
+
+            return anim;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 50765f2..009d4b9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -88,10 +88,12 @@
 import com.android.internal.policy.PhoneWindow;
 import com.android.settingslib.applications.InterestingConfigChanges;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.clipboardoverlay.ClipboardOverlayController;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition;
 import com.android.systemui.screenshot.TakeScreenshotService.RequestCallback;
+import com.android.systemui.util.Assert;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
@@ -247,6 +249,7 @@
     private final ImageExporter mImageExporter;
     private final Executor mMainExecutor;
     private final ExecutorService mBgExecutor;
+    private final BroadcastSender mBroadcastSender;
 
     private final WindowManager mWindowManager;
     private final WindowManager.LayoutParams mWindowLayoutParams;
@@ -271,7 +274,6 @@
     private String mPackageName = "";
     private BroadcastReceiver mCopyBroadcastReceiver;
 
-
     /** Tracks config changes that require re-creating UI */
     private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
             ActivityInfo.CONFIG_ORIENTATION
@@ -293,7 +295,8 @@
             ScrollCaptureController scrollCaptureController,
             LongScreenshotData longScreenshotHolder,
             ActivityManager activityManager,
-            TimeoutHandler timeoutHandler) {
+            TimeoutHandler timeoutHandler,
+            BroadcastSender broadcastSender) {
         mScreenshotSmartActions = screenshotSmartActions;
         mNotificationsController = screenshotNotificationsController;
         mScrollCaptureClient = scrollCaptureClient;
@@ -304,6 +307,7 @@
         mLongScreenshotHolder = longScreenshotHolder;
         mIsLowRamDevice = activityManager.isLowRamDevice();
         mBgExecutor = Executors.newSingleThreadExecutor();
+        mBroadcastSender = broadcastSender;
 
         mScreenshotHandler = timeoutHandler;
         mScreenshotHandler.setDefaultTimeoutMillis(SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS);
@@ -355,8 +359,10 @@
                 ClipboardOverlayController.SELF_PERMISSION, null, Context.RECEIVER_NOT_EXPORTED);
     }
 
+    @MainThread
     void takeScreenshotFullscreen(ComponentName topComponent, Consumer<Uri> finisher,
             RequestCallback requestCallback) {
+        Assert.isMainThread();
         mCurrentRequestCallback = requestCallback;
         DisplayMetrics displayMetrics = new DisplayMetrics();
         getDefaultDisplay().getRealMetrics(displayMetrics);
@@ -365,11 +371,12 @@
                 new Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels));
     }
 
+    @MainThread
     void handleImageAsScreenshot(Bitmap screenshot, Rect screenshotScreenBounds,
             Insets visibleInsets, int taskId, int userId, ComponentName topComponent,
             Consumer<Uri> finisher, RequestCallback requestCallback) {
         // TODO: use task Id, userId, topComponent for smart handler
-
+        Assert.isMainThread();
         if (screenshot == null) {
             Log.e(TAG, "Got null bitmap from screenshot message");
             mNotificationsController.notifyScreenshotError(
@@ -392,8 +399,10 @@
     /**
      * Displays a screenshot selector
      */
+    @MainThread
     void takeScreenshotPartial(ComponentName topComponent,
             final Consumer<Uri> finisher, RequestCallback requestCallback) {
+        Assert.isMainThread();
         mScreenshotView.reset();
         mCurrentRequestCallback = requestCallback;
 
@@ -517,7 +526,7 @@
 
         saveScreenshot(screenshot, finisher, screenRect, Insets.NONE, topComponent, true);
 
-        mContext.sendBroadcast(new Intent(ClipboardOverlayController.SCREENSHOT_ACTION),
+        mBroadcastSender.sendBroadcast(new Intent(ClipboardOverlayController.SCREENSHOT_ACTION),
                 ClipboardOverlayController.SELF_PERMISSION);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 1241e1d..6af6e36 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -141,7 +141,7 @@
 
     private ScreenshotSelectorView mScreenshotSelectorView;
     private ImageView mScrollingScrim;
-    private View mScreenshotStatic;
+    private DraggableConstraintLayout mScreenshotStatic;
     private ImageView mScreenshotPreview;
     private View mScreenshotPreviewBorder;
     private ImageView mScrollablePreview;
@@ -159,7 +159,6 @@
     private UiEventLogger mUiEventLogger;
     private ScreenshotViewCallback mCallbacks;
     private boolean mPendingSharedTransition;
-    private SwipeDismissHandler mSwipeDismissHandler;
     private InputMonitorCompat mInputMonitor;
     private InputChannelCompat.InputEventReceiver mInputEventReceiver;
     private boolean mShowScrollablePreview;
@@ -332,19 +331,6 @@
         }
     }
 
-    @Override // ViewGroup
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        // scrolling scrim should not be swipeable; return early if we're on the scrim
-        if (!getSwipeRegion().contains((int) ev.getRawX(), (int) ev.getRawY())) {
-            return false;
-        }
-        // always pass through the down event so the swipe handler knows the initial state
-        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
-            mSwipeDismissHandler.onTouch(this, ev);
-        }
-        return mSwipeDetector.onTouchEvent(ev);
-    }
-
     @Override // View
     protected void onFinishInflate() {
         mScrollingScrim = requireNonNull(findViewById(R.id.screenshot_scrolling_scrim));
@@ -356,8 +342,8 @@
         mScreenshotPreview.setClipToOutline(true);
 
         mActionsContainerBackground = requireNonNull(findViewById(
-                R.id.screenshot_actions_container_background));
-        mActionsContainer = requireNonNull(findViewById(R.id.screenshot_actions_container));
+                R.id.actions_container_background));
+        mActionsContainer = requireNonNull(findViewById(R.id.actions_container));
         mActionsView = requireNonNull(findViewById(R.id.screenshot_actions));
         mBackgroundProtection = requireNonNull(
                 findViewById(R.id.screenshot_actions_background));
@@ -395,27 +381,34 @@
         setFocusableInTouchMode(true);
         requestFocus();
 
-        mSwipeDismissHandler = new SwipeDismissHandler(mContext, mScreenshotStatic,
-                new SwipeDismissHandler.SwipeDismissCallbacks() {
-                    @Override
-                    public void onInteraction() {
-                        mCallbacks.onUserInteraction();
-                    }
+        mScreenshotStatic.setCallbacks(new DraggableConstraintLayout.SwipeDismissCallbacks() {
+            @Override
+            public void onInteraction() {
+                mCallbacks.onUserInteraction();
+            }
 
+            @Override
+            public void onSwipeDismissInitiated(Animator animator) {
+                if (DEBUG_DISMISS) {
+                    Log.d(ScreenshotView.TAG, "dismiss triggered via swipe gesture");
+                }
+                mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SWIPE_DISMISSED, 0,
+                        mPackageName);
+                animator.addListener(new AnimatorListenerAdapter() {
                     @Override
-                    public void onSwipeDismissInitiated(Animator animator) {
-                        if (DEBUG_DISMISS) {
-                            Log.d(ScreenshotView.TAG, "dismiss triggered via swipe gesture");
-                        }
-                        mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SWIPE_DISMISSED, 0,
-                                mPackageName);
-                    }
-
-                    @Override
-                    public void onDismissComplete() {
-                        mCallbacks.onDismiss();
+                    public void onAnimationStart(Animator animation) {
+                        super.onAnimationStart(animation);
+                        mBackgroundProtection.animate()
+                                .alpha(0).setDuration(animation.getDuration()).start();
                     }
                 });
+            }
+
+            @Override
+            public void onDismissComplete() {
+                mCallbacks.onDismiss();
+            }
+        });
     }
 
     View getScreenshotPreview() {
@@ -640,8 +633,6 @@
                 requestLayout();
 
                 createScreenshotActionsShadeAnimation().start();
-
-                setOnTouchListener(mSwipeDismissHandler);
             }
         });
 
@@ -950,7 +941,7 @@
     }
 
     boolean isDismissing() {
-        return mSwipeDismissHandler.isDismissing();
+        return mScreenshotStatic.isDismissing();
     }
 
     boolean isPendingSharedTransition() {
@@ -958,15 +949,14 @@
     }
 
     void animateDismissal() {
-        mSwipeDismissHandler.dismiss();
+        mScreenshotStatic.dismiss();
     }
 
     void reset() {
         if (DEBUG_UI) {
             Log.d(TAG, "reset screenshot view");
         }
-
-        mSwipeDismissHandler.cancel();
+        mScreenshotStatic.cancelDismissal();
         if (DEBUG_WINDOW) {
             Log.d(TAG, "removing OnComputeInternalInsetsListener");
         }
@@ -999,6 +989,7 @@
         mSmartChips.clear();
         mQuickShareChip = null;
         setAlpha(1);
+        mScreenshotStatic.setAlpha(1);
         mScreenshotSelectorView.stop();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SwipeDismissHandler.java b/packages/SystemUI/src/com/android/systemui/screenshot/SwipeDismissHandler.java
deleted file mode 100644
index 24b1249..0000000
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SwipeDismissHandler.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.screenshot;
-
-import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM;
-import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.MathUtils;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.View;
-
-/**
- * Allows a view to be swipe-dismissed, or returned to its location if distance threshold is not met
- */
-public class SwipeDismissHandler implements View.OnTouchListener {
-    private static final String TAG = "SwipeDismissHandler";
-
-    // distance needed to register a dismissal
-    private static final float DISMISS_DISTANCE_THRESHOLD_DP = 20;
-
-    /**
-     * Stores the callbacks when the view is interacted with or dismissed.
-     */
-    public interface SwipeDismissCallbacks {
-        /**
-         * Run when the view is interacted with (touched)
-         */
-        void onInteraction();
-
-        /**
-         * Run when the view is dismissed (the distance threshold is met), pre-dismissal animation
-         */
-        void onSwipeDismissInitiated(Animator animator);
-
-        /**
-         * Run when the view is dismissed (the distance threshold is met), post-dismissal animation
-         */
-        void onDismissComplete();
-    }
-
-    private final View mView;
-    private final SwipeDismissCallbacks mCallbacks;
-    private final GestureDetector mGestureDetector;
-    private DisplayMetrics mDisplayMetrics;
-    private ValueAnimator mDismissAnimation;
-
-
-    private float mStartX;
-    // Keeps track of the most recent direction (between the last two move events).
-    // -1 for left; +1 for right.
-    private int mDirectionX;
-    private float mPreviousX;
-
-    public SwipeDismissHandler(Context context, View view, SwipeDismissCallbacks callbacks) {
-        mView = view;
-        mCallbacks = callbacks;
-        GestureDetector.OnGestureListener gestureListener = new SwipeDismissGestureListener();
-        mGestureDetector = new GestureDetector(context, gestureListener);
-        mDisplayMetrics = new DisplayMetrics();
-        context.getDisplay().getRealMetrics(mDisplayMetrics);
-    }
-
-    @Override
-    public boolean onTouch(View view, MotionEvent event) {
-        boolean gestureResult = mGestureDetector.onTouchEvent(event);
-        mCallbacks.onInteraction();
-        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
-            mStartX = event.getRawX();
-            mPreviousX = mStartX;
-            return true;
-        } else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
-            if (mDismissAnimation != null && mDismissAnimation.isRunning()) {
-                return true;
-            }
-            if (isPastDismissThreshold()) {
-                ValueAnimator dismissAnimator = createSwipeDismissAnimation(1);
-                mCallbacks.onSwipeDismissInitiated(dismissAnimator);
-                dismiss(dismissAnimator);
-            } else {
-                // if we've moved, but not past the threshold, start the return animation
-                if (DEBUG_DISMISS) {
-                    Log.d(TAG, "swipe gesture abandoned");
-                }
-                createSwipeReturnAnimation().start();
-            }
-            return true;
-        }
-        return gestureResult;
-    }
-
-    class SwipeDismissGestureListener extends GestureDetector.SimpleOnGestureListener {
-        @Override
-        public boolean onScroll(
-                MotionEvent ev1, MotionEvent ev2, float distanceX, float distanceY) {
-            mView.setTranslationX(ev2.getRawX() - mStartX);
-            mDirectionX = (ev2.getRawX() < mPreviousX) ? -1 : 1;
-            mPreviousX = ev2.getRawX();
-            return true;
-        }
-
-        @Override
-        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
-                float velocityY) {
-            if (mView.getTranslationX() * velocityX > 0
-                    && (mDismissAnimation == null || !mDismissAnimation.isRunning())) {
-                ValueAnimator dismissAnimator =
-                        createSwipeDismissAnimation(velocityX / (float) 1000);
-                mCallbacks.onSwipeDismissInitiated(dismissAnimator);
-                dismiss(dismissAnimator);
-                return true;
-            }
-            return false;
-        }
-    }
-
-    private boolean isPastDismissThreshold() {
-        float translationX = mView.getTranslationX();
-        // Determines whether the absolute translation from the start is in the same direction
-        // as the current movement. For example, if the user moves most of the way to the right,
-        // but then starts dragging back left, we do not dismiss even though the absolute
-        // distance is greater than the threshold.
-        if (translationX * mDirectionX > 0) {
-            return Math.abs(translationX) >= FloatingWindowUtil.dpToPx(mDisplayMetrics,
-                    DISMISS_DISTANCE_THRESHOLD_DP);
-        }
-        return false;
-    }
-
-    /**
-     * Return whether the view is currently being dismissed
-     */
-    public boolean isDismissing() {
-        return (mDismissAnimation != null && mDismissAnimation.isRunning());
-    }
-
-    /**
-     * Cancel the currently-running dismissal animation, if any.
-     */
-    public void cancel() {
-        if (isDismissing()) {
-            if (DEBUG_ANIM) {
-                Log.d(TAG, "cancelling dismiss animation");
-            }
-            mDismissAnimation.cancel();
-        }
-    }
-
-    /**
-     * Start dismissal animation (will run onDismiss callback when animation complete)
-     */
-    public void dismiss() {
-        dismiss(createSwipeDismissAnimation(1));
-    }
-
-    private void dismiss(ValueAnimator animator) {
-        mDismissAnimation = animator;
-        mDismissAnimation.addListener(new AnimatorListenerAdapter() {
-            private boolean mCancelled;
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                super.onAnimationCancel(animation);
-                mCancelled = true;
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                super.onAnimationEnd(animation);
-                if (!mCancelled) {
-                    mCallbacks.onDismissComplete();
-                }
-            }
-        });
-        mDismissAnimation.start();
-    }
-
-    private ValueAnimator createSwipeDismissAnimation(float velocity) {
-        // velocity is measured in pixels per millisecond
-        velocity = Math.min(3, Math.max(1, velocity));
-        ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
-        float startX = mView.getTranslationX();
-        // make sure the UI gets all the way off the screen in the direction of movement
-        // (the actions container background is guaranteed to be both the leftmost and
-        // rightmost UI element in LTR and RTL)
-        float finalX;
-        int layoutDir = mView.getContext().getResources().getConfiguration().getLayoutDirection();
-        if (startX > 0 || (startX == 0 && layoutDir == View.LAYOUT_DIRECTION_RTL)) {
-            finalX = mDisplayMetrics.widthPixels;
-        } else {
-            finalX = -1 * mView.getRight();
-        }
-        float distance = Math.abs(finalX - startX);
-
-        anim.addUpdateListener(animation -> {
-            float translation = MathUtils.lerp(startX, finalX, animation.getAnimatedFraction());
-            mView.setTranslationX(translation);
-            mView.setAlpha(1 - animation.getAnimatedFraction());
-        });
-        anim.setDuration((long) (distance / Math.abs(velocity)));
-        return anim;
-    }
-
-    private ValueAnimator createSwipeReturnAnimation() {
-        ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
-        float startX = mView.getTranslationX();
-        float finalX = 0;
-
-        anim.addUpdateListener(animation -> {
-            float translation = MathUtils.lerp(
-                    startX, finalX, animation.getAnimatedFraction());
-            mView.setTranslationX(translation);
-        });
-
-        return anim;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 98e6bd1..924351d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -51,7 +51,6 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.util.ScreenshotHelper;
 import com.android.systemui.R;
-import com.android.systemui.shared.recents.utilities.BitmapUtil;
 
 import java.util.function.Consumer;
 
@@ -208,7 +207,7 @@
                 if (DEBUG_SERVICE) {
                     Log.d(TAG, "handleMessage: TAKE_SCREENSHOT_PROVIDED_IMAGE");
                 }
-                Bitmap screenshot = BitmapUtil.bundleToHardwareBitmap(
+                Bitmap screenshot = ScreenshotHelper.HardwareBitmapBundler.bundleToHardwareBitmap(
                         screenshotRequest.getBitmapBundle());
                 Rect screenBounds = screenshotRequest.getBoundsInScreen();
                 Insets insets = screenshotRequest.getInsets();
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/SmartspacePrecondition.kt b/packages/SystemUI/src/com/android/systemui/smartspace/SmartspacePrecondition.kt
new file mode 100644
index 0000000..aa2bcec
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/SmartspacePrecondition.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.smartspace
+
+/**
+ * A {@link SmartspacePrecondition} captures the conditions that must be met for Smartspace to be
+ * used in a particular setting.
+ */
+interface SmartspacePrecondition {
+    /**
+     * A callback for receiving updates when conditions have changed.
+     */
+    interface Listener {
+        fun onCriteriaChanged()
+    }
+
+    /**
+     * Adds a listener to receive future updates. {@link Listener#onCriteriaChanged} will be called
+     * immediately upon adding.
+     */
+    fun addListener(listener: Listener)
+
+    /**
+     * Removes a listener from receiving future updates.
+     */
+    fun removeListener(listener: Listener)
+
+    /**
+     * Returns whether all conditions have been met.
+     */
+    fun conditionsMet(): Boolean
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/SmartspaceTargetFilter.kt b/packages/SystemUI/src/com/android/systemui/smartspace/SmartspaceTargetFilter.kt
new file mode 100644
index 0000000..7228550
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/SmartspaceTargetFilter.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.smartspace
+
+import android.app.smartspace.SmartspaceTarget
+
+/**
+ * {@link SmartspaceTargetFilter} defines a way to locally filter targets from inclusion. This
+ * should be used for filtering that isn't available further upstream.
+ */
+interface SmartspaceTargetFilter {
+    /**
+     * An interface implemented by clients to receive updates when the filtering criteria changes.
+     * When this happens, the client should refresh their target set.
+     */
+    interface Listener {
+        fun onCriteriaChanged()
+    }
+
+    /**
+     * Adds a listener to receive future updates. {@link Listener#onCriteriaChanged} will be
+     * invoked immediately after.
+     */
+    fun addListener(listener: Listener)
+
+    /**
+     * Removes listener from receiving future updates.
+     */
+    fun removeListener(listener: Listener)
+
+    /**
+     * Returns {@code true} if the {@link SmartspaceTarget} should be included in the current
+     * target set, {@code false} otherwise.
+     */
+    fun filterSmartspaceTarget(t: SmartspaceTarget): Boolean
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
new file mode 100644
index 0000000..1b74ac3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
@@ -0,0 +1,72 @@
+/*
+ * 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.smartspace.dagger
+
+import com.android.systemui.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.smartspace.SmartspacePrecondition
+import com.android.systemui.smartspace.SmartspaceTargetFilter
+import com.android.systemui.smartspace.filters.LockscreenTargetFilter
+import com.android.systemui.smartspace.preconditions.LockscreenPrecondition
+import dagger.Binds
+import dagger.BindsOptionalOf
+import dagger.Module
+import javax.inject.Named
+
+@Module(subcomponents = [SmartspaceViewComponent::class])
+abstract class SmartspaceModule {
+    @Module
+    companion object {
+        /**
+         * The BcSmartspaceDataProvider for dreams.
+         */
+        const val DREAM_SMARTSPACE_DATA_PLUGIN = "dreams_smartspace_data_plugin"
+
+        /**
+         * The lockscreen smartspace target filter.
+         */
+        const val LOCKSCREEN_SMARTSPACE_TARGET_FILTER = "lockscreen_smartspace_target_filter"
+
+        /**
+         * The dream smartspace target filter.
+         */
+        const val DREAM_SMARTSPACE_TARGET_FILTER = "dream_smartspace_target_filter"
+
+        /**
+         * The precondition for dream smartspace
+         */
+        const val DREAM_SMARTSPACE_PRECONDITION = "dream_smartspace_precondition"
+    }
+
+    @BindsOptionalOf
+    @Named(DREAM_SMARTSPACE_TARGET_FILTER)
+    abstract fun optionalDreamSmartspaceTargetFilter(): SmartspaceTargetFilter?
+
+    @BindsOptionalOf
+    @Named(DREAM_SMARTSPACE_DATA_PLUGIN)
+    abstract fun optionalDreamsBcSmartspaceDataPlugin(): BcSmartspaceDataPlugin?
+
+    @Binds
+    @Named(LOCKSCREEN_SMARTSPACE_TARGET_FILTER)
+    abstract fun provideLockscreenSmartspaceTargetFilter(
+        filter: LockscreenTargetFilter?
+    ): SmartspaceTargetFilter?
+
+    @Binds
+    @Named(DREAM_SMARTSPACE_PRECONDITION)
+    abstract fun bindSmartspacePrecondition(
+        lockscreenPrecondition: LockscreenPrecondition?
+    ): SmartspacePrecondition?
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
new file mode 100644
index 0000000..d3ae198
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
@@ -0,0 +1,84 @@
+/*
+ * 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.smartspace.dagger
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.smartspace.dagger.SmartspaceViewComponent.SmartspaceViewModule.PLUGIN
+import dagger.BindsInstance
+import dagger.Module
+import dagger.Provides
+import dagger.Subcomponent
+import javax.inject.Named
+
+@Subcomponent(modules = [SmartspaceViewComponent.SmartspaceViewModule::class])
+interface SmartspaceViewComponent {
+    @Subcomponent.Factory
+    interface Factory {
+        fun create(
+            @BindsInstance parent: ViewGroup,
+            @BindsInstance @Named(PLUGIN) plugin: BcSmartspaceDataPlugin,
+            @BindsInstance onAttachListener: View.OnAttachStateChangeListener
+        ): SmartspaceViewComponent
+    }
+
+    fun getView(): BcSmartspaceDataPlugin.SmartspaceView
+
+    @Module
+    object SmartspaceViewModule {
+        const val PLUGIN = "plugin"
+
+        @Provides
+        fun providesSmartspaceView(
+            activityStarter: ActivityStarter,
+            falsingManager: FalsingManager,
+            parent: ViewGroup,
+            @Named(PLUGIN) plugin: BcSmartspaceDataPlugin,
+            onAttachListener: View.OnAttachStateChangeListener
+        ):
+                BcSmartspaceDataPlugin.SmartspaceView {
+            val ssView = plugin.getView(parent)
+            ssView.registerDataProvider(plugin)
+
+            ssView.setIntentStarter(object : BcSmartspaceDataPlugin.IntentStarter {
+                override fun startIntent(view: View, intent: Intent, showOnLockscreen: Boolean) {
+                    activityStarter.startActivity(
+                            intent,
+                            true, /* dismissShade */
+                            null, /* launch animator */
+                            showOnLockscreen
+                    )
+                }
+
+                override fun startPendingIntent(pi: PendingIntent, showOnLockscreen: Boolean) {
+                    if (showOnLockscreen) {
+                        pi.send()
+                    } else {
+                        activityStarter.startPendingIntentDismissingKeyguard(pi)
+                    }
+                }
+            })
+            (ssView as View).addOnAttachStateChangeListener(onAttachListener)
+            ssView.setFalsingManager(falsingManager)
+            return ssView
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenTargetFilter.kt b/packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenTargetFilter.kt
new file mode 100644
index 0000000..6ad4901
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenTargetFilter.kt
@@ -0,0 +1,152 @@
+/*
+ * 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.smartspace.filters
+
+import android.app.smartspace.SmartspaceTarget
+import android.content.ContentResolver
+import android.content.Context
+import android.database.ContentObserver
+import android.net.Uri
+import android.os.Handler
+import android.os.UserHandle
+import android.provider.Settings
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.smartspace.SmartspaceTargetFilter
+import com.android.systemui.util.concurrency.Execution
+import com.android.systemui.util.settings.SecureSettings
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+/**
+ * {@link SmartspaceTargetFilter} for smartspace targets that show above the lockscreen.
+ */
+class LockscreenTargetFilter @Inject constructor(
+    private val secureSettings: SecureSettings,
+    private val userTracker: UserTracker,
+    private val execution: Execution,
+    @Main private val handler: Handler,
+    private val contentResolver: ContentResolver,
+    @Main private val uiExecutor: Executor
+) : SmartspaceTargetFilter {
+    private var listeners: MutableSet<SmartspaceTargetFilter.Listener> = mutableSetOf()
+    private var showSensitiveContentForCurrentUser = false
+        set(value) {
+            val existing = field
+            field = value
+            if (existing != field) {
+                listeners.forEach { it.onCriteriaChanged() }
+            }
+        }
+    private var showSensitiveContentForManagedUser = false
+        set(value) {
+            val existing = field
+            field = value
+            if (existing != field) {
+                listeners.forEach { it.onCriteriaChanged() }
+            }
+        }
+
+    private val settingsObserver = object : ContentObserver(handler) {
+        override fun onChange(selfChange: Boolean, uri: Uri?) {
+            execution.assertIsMainThread()
+            updateUserContentSettings()
+        }
+    }
+
+    private var managedUserHandle: UserHandle? = null
+
+    override fun addListener(listener: SmartspaceTargetFilter.Listener) {
+        listeners.add(listener)
+
+        if (listeners.size != 1) {
+            return
+        }
+
+        userTracker.addCallback(userTrackerCallback, uiExecutor)
+
+        contentResolver.registerContentObserver(
+                secureSettings.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
+                true,
+                settingsObserver,
+                UserHandle.USER_ALL
+        )
+
+        updateUserContentSettings()
+    }
+
+    override fun removeListener(listener: SmartspaceTargetFilter.Listener) {
+        listeners.remove(listener)
+
+        if (listeners.isNotEmpty()) {
+            return
+        }
+
+        userTracker.removeCallback(userTrackerCallback)
+        contentResolver.unregisterContentObserver(settingsObserver)
+    }
+
+    override fun filterSmartspaceTarget(t: SmartspaceTarget): Boolean {
+        return when (t.userHandle) {
+            userTracker.userHandle -> {
+                !t.isSensitive || showSensitiveContentForCurrentUser
+            }
+            managedUserHandle -> {
+                // Really, this should be "if this managed profile is associated with the current
+                // active user", but we don't have a good way to check that, so instead we cheat:
+                // Only the primary user can have an associated managed profile, so only show
+                // content for the managed profile if the primary user is active
+                userTracker.userHandle.identifier == UserHandle.USER_SYSTEM &&
+                        (!t.isSensitive || showSensitiveContentForManagedUser)
+            }
+            else -> {
+                false
+            }
+        }
+    }
+
+    private val userTrackerCallback = object : UserTracker.Callback {
+        override fun onUserChanged(newUser: Int, userContext: Context) {
+            execution.assertIsMainThread()
+            updateUserContentSettings()
+        }
+    }
+
+    private fun getWorkProfileUser(): UserHandle? {
+        for (userInfo in userTracker.userProfiles) {
+            if (userInfo.isManagedProfile) {
+                return userInfo.userHandle
+            }
+        }
+        return null
+    }
+
+    private fun updateUserContentSettings() {
+        val setting = Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
+
+        showSensitiveContentForCurrentUser =
+                secureSettings.getIntForUser(setting, 0, userTracker.userId) == 1
+
+        managedUserHandle = getWorkProfileUser()
+        val managedId = managedUserHandle?.identifier
+        if (managedId != null) {
+            showSensitiveContentForManagedUser =
+                    secureSettings.getIntForUser(setting, 0, managedId) == 1
+        }
+
+        listeners.forEach { it.onCriteriaChanged() }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/preconditions/LockscreenPrecondition.kt b/packages/SystemUI/src/com/android/systemui/smartspace/preconditions/LockscreenPrecondition.kt
new file mode 100644
index 0000000..1302ec9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/preconditions/LockscreenPrecondition.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.smartspace.preconditions
+
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.smartspace.SmartspacePrecondition
+import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.util.concurrency.Execution
+import javax.inject.Inject
+
+/**
+ * {@link LockscreenPrecondition} covers the conditions that must be met before Smartspace can be
+ * used over lockscreen. These conditions include the device being provisioned with a setup user
+ * and the Smartspace feature flag enabled.
+ */
+class LockscreenPrecondition @Inject constructor(
+    private val featureFlags: FeatureFlags,
+    private val deviceProvisionedController: DeviceProvisionedController,
+    private val execution: Execution
+) : SmartspacePrecondition {
+    private var listeners = mutableSetOf<SmartspacePrecondition.Listener>()
+
+    private val deviceProvisionedListener =
+            object : DeviceProvisionedController.DeviceProvisionedListener {
+                override fun onDeviceProvisionedChanged() {
+                    updateDeviceReadiness()
+                }
+
+                override fun onUserSetupChanged() {
+                    updateDeviceReadiness()
+                }
+            }
+
+    init {
+        deviceProvisionedController.addCallback(deviceProvisionedListener)
+    }
+
+    var deviceReady: Boolean = false
+        private set
+
+    init {
+        updateDeviceReadiness()
+    }
+
+    private fun updateDeviceReadiness() {
+        if (deviceReady) {
+            return
+        }
+
+        deviceReady = deviceProvisionedController.isDeviceProvisioned &&
+                deviceProvisionedController.isCurrentUserSetup
+
+        if (!deviceReady) {
+            return
+        }
+
+        deviceProvisionedController.removeCallback(deviceProvisionedListener)
+        synchronized(listeners) {
+            listeners.forEach { it.onCriteriaChanged() }
+        }
+    }
+
+    override fun addListener(listener: SmartspacePrecondition.Listener) {
+        synchronized(listeners) {
+            listeners += listener
+        }
+        // Always trigger a targeted callback upon addition of listener.
+        listener.onCriteriaChanged()
+    }
+
+    override fun removeListener(listener: SmartspacePrecondition.Listener) {
+        synchronized(listeners) {
+            listeners -= listener
+        }
+    }
+
+    override fun conditionsMet(): Boolean {
+        execution.assertIsMainThread()
+        return featureFlags.isEnabled(Flags.SMARTSPACE) && deviceReady
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 5932a64..d9a98b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -163,6 +163,7 @@
     private static final int MSG_MEDIA_TRANSFER_RECEIVER_STATE = 65 << MSG_SHIFT;
     private static final int MSG_REGISTER_NEARBY_MEDIA_DEVICE_PROVIDER = 66 << MSG_SHIFT;
     private static final int MSG_UNREGISTER_NEARBY_MEDIA_DEVICE_PROVIDER = 67 << MSG_SHIFT;
+    private static final int MSG_TILE_SERVICE_REQUEST_LISTENING_STATE = 68 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -433,6 +434,11 @@
         default void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {}
 
         /**
+         * @see IStatusBar#requestTileServiceListeningState
+         */
+        default void requestTileServiceListeningState(@NonNull ComponentName componentName) {}
+
+        /**
          * @see IStatusBar#requestAddTile
          */
         default void requestAddTile(
@@ -1190,6 +1196,12 @@
     }
 
     @Override
+    public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
+        mHandler.obtainMessage(MSG_TILE_SERVICE_REQUEST_LISTENING_STATE, componentName)
+                .sendToTarget();
+    }
+
+    @Override
     public void requestAddTile(
             @NonNull ComponentName componentName,
             @NonNull CharSequence appName,
@@ -1686,6 +1698,12 @@
                         mCallbacks.get(i).unregisterNearbyMediaDevicesProvider(provider);
                     }
                     break;
+                case MSG_TILE_SERVICE_REQUEST_LISTENING_STATE:
+                    ComponentName component = (ComponentName) msg.obj;
+                    for (int i = 0; i < mCallbacks.size(); i++) {
+                        mCallbacks.get(i).requestTileServiceListeningState(component);
+                    }
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index ccec0c2..16ddb0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -293,6 +293,14 @@
         }
     }
 
+    /**
+     * Cleanup
+     */
+    public void destroy() {
+        mHandler.removeCallbacksAndMessages(null);
+        mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
+    }
+
     private void handleAlignStateChanged(int alignState) {
         String alignmentIndication = "";
         if (alignState == DockManager.ALIGN_STATE_POOR) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 17f42b1..ab4d0dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -99,15 +99,57 @@
     internal var pulseHeightAnimator: ValueAnimator? = null
 
     /**
-     * Distance that the full shade transition takes in order for scrim to fully transition to
-     * the shade (in alpha)
+     * Distance that the full shade transition takes in order to complete.
+     */
+    private var fullTransitionDistance = 0
+
+    /**
+     * Distance that the full transition takes in order for us to fully transition to the shade by
+     * tapping on a button, such as "expand".
+     */
+    private var fullTransitionDistanceByTap = 0
+
+    /**
+     * Distance that the full shade transition takes in order for scrim to fully transition to the
+     * shade (in alpha)
      */
     private var scrimTransitionDistance = 0
 
     /**
-     * Distance that the full transition takes in order for us to fully transition to the shade
+     * Distance that the full shade transition takes in order for the notification shelf to fully
+     * expand.
      */
-    private var fullTransitionDistance = 0
+    private var notificationShelfTransitionDistance = 0
+
+    /**
+     * Distance that the full shade transition takes in order for the Quick Settings to fully fade
+     * and expand.
+     */
+    private var qsTransitionDistance = 0
+
+    /**
+     * Distance that the full shade transition takes in order for the keyguard content on
+     * NotificationPanelViewController to fully fade (e.g. Clock & Smartspace).
+     */
+    private var npvcKeyguardContentAlphaTransitionDistance = 0
+
+    /**
+     * Distance that the full shade transition takes in order for depth of the wallpaper to fully
+     * change.
+     */
+    private var depthControllerTransitionDistance = 0
+
+    /**
+     * Distance that the full shade transition takes in order for the UDFPS Keyguard View to fully
+     * fade.
+     */
+    private var udfpsTransitionDistance = 0
+
+    /**
+     * Used for StatusBar to know that a transition is in progress. At the moment it only checks
+     * whether the progress is > 0, therefore this value is not very important.
+     */
+    private var statusBarTransitionDistance = 0
 
     /**
      * Flag to make sure that the dragDownAmount is applied to the listeners even when in the
@@ -130,7 +172,7 @@
      * The distance until we're showing the notifications when pulsing
      */
     val distanceUntilShowingPulsingNotifications
-        get() = scrimTransitionDistance
+        get() = fullTransitionDistance
 
     /**
      * The udfpsKeyguardViewController if it exists.
@@ -177,10 +219,24 @@
     }
 
     private fun updateResources() {
+        fullTransitionDistance = context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_full_transition_distance)
+        fullTransitionDistanceByTap = context.resources.getDimensionPixelSize(
+            R.dimen.lockscreen_shade_transition_by_tap_distance)
         scrimTransitionDistance = context.resources.getDimensionPixelSize(
                 R.dimen.lockscreen_shade_scrim_transition_distance)
-        fullTransitionDistance = context.resources.getDimensionPixelSize(
+        notificationShelfTransitionDistance = context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_notif_shelf_transition_distance)
+        qsTransitionDistance = context.resources.getDimensionPixelSize(
                 R.dimen.lockscreen_shade_qs_transition_distance)
+        npvcKeyguardContentAlphaTransitionDistance = context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
+        depthControllerTransitionDistance = context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_depth_controller_transition_distance)
+        udfpsTransitionDistance = context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_udfps_keyguard_transition_distance)
+        statusBarTransitionDistance = context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_status_bar_transition_distance)
         useSplitShade = Utils.shouldUseSplitNotificationShade(context.resources)
     }
 
@@ -248,6 +304,7 @@
                         // override that
                         forceApplyAmount = true
                         // Reset the behavior. At this point the animation is already started
+                        logger.logDragDownAmountReset()
                         dragDownAmount = 0f
                         forceApplyAmount = false
                     }
@@ -337,13 +394,19 @@
             if (field != value || forceApplyAmount) {
                 field = value
                 if (!nsslController.isInLockedDownShade() || field == 0f || forceApplyAmount) {
-                    qSDragProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
-                    nsslController.setTransitionToFullShadeAmount(field, qSDragProgress)
+                    val notificationShelfProgress =
+                        MathUtils.saturate(dragDownAmount / notificationShelfTransitionDistance)
+                    nsslController.setTransitionToFullShadeAmount(field, notificationShelfProgress)
+
+                    qSDragProgress = MathUtils.saturate(dragDownAmount / qsTransitionDistance)
                     qS.setTransitionToFullShadeAmount(field, qSDragProgress)
+
                     notificationPanelController.setTransitionToFullShadeAmount(field,
                             false /* animate */, 0 /* delay */)
+
                     mediaHierarchyManager.setTransitionToFullShadeAmount(field)
                     transitionToShadeAmountCommon(field)
+                    transitionToShadeAmountKeyguard(field)
                 }
             }
         }
@@ -357,11 +420,34 @@
     private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
         val scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
         scrimController.setTransitionToFullShadeProgress(scrimProgress)
+
+        if (depthControllerTransitionDistance > 0) {
+            val depthProgress =
+                MathUtils.saturate(dragDownAmount / depthControllerTransitionDistance)
+            depthController.transitionToFullShadeProgress = depthProgress
+        }
+
+        val udfpsProgress = MathUtils.saturate(dragDownAmount / udfpsTransitionDistance)
+        udfpsKeyguardViewController?.setTransitionToFullShadeProgress(udfpsProgress)
+
+        val statusBarProgress = MathUtils.saturate(dragDownAmount / statusBarTransitionDistance)
+        centralSurfaces.setTransitionToFullShadeProgress(statusBarProgress)
+    }
+
+    private fun transitionToShadeAmountKeyguard(dragDownAmount: Float) {
         // Fade out all content only visible on the lockscreen
-        notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - scrimProgress)
-        depthController.transitionToFullShadeProgress = scrimProgress
-        udfpsKeyguardViewController?.setTransitionToFullShadeProgress(scrimProgress)
-        centralSurfaces.setTransitionToFullShadeProgress(scrimProgress)
+        val keyguardAlphaProgress =
+            MathUtils.saturate(dragDownAmount / npvcKeyguardContentAlphaTransitionDistance)
+        val keyguardAlpha = 1f - keyguardAlphaProgress
+        val keyguardTranslationY = if (useSplitShade) {
+            // On split-shade, the translationY of the keyguard should stay in sync with the
+            // translation of media.
+            mediaHierarchyManager.getGuidedTransformationTranslationY()
+        } else {
+            0
+        }
+        notificationPanelController
+            .setKeyguardTransitionProgress(keyguardAlpha, keyguardTranslationY)
     }
 
     private fun setDragDownAmountAnimated(
@@ -404,9 +490,10 @@
         // be a couple of frames later. if we're setting it to 0, it will use the
         // default inset and therefore flicker
         dragDownAmount = 1f
-        setDragDownAmountAnimated(fullTransitionDistance.toFloat(), delay = delay) {
+        setDragDownAmountAnimated(fullTransitionDistanceByTap.toFloat(), delay = delay) {
             // End listener:
             // Reset
+            logger.logDragDownAmountReset()
             dragDownAmount = 0f
             forceApplyAmount = false
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 94a6d3e..66c1d87 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -507,12 +507,11 @@
                 Math.max(cx + cy, cx + (h - cy)),
                 Math.max((w - cx) + cy, (w - cx) + (h - cy)));
 
-        riv.setRevealParameters(cx, cy, r);
-        riv.setPendingIntent(pendingIntent);
+        riv.getController().setRevealParams(new RemoteInputView.RevealParams(cx, cy, r));
         riv.getController().setPendingIntent(pendingIntent);
-        riv.setRemoteInput(inputs, input, editedSuggestionInfo);
         riv.getController().setRemoteInput(input);
         riv.getController().setRemoteInputs(inputs);
+        riv.getController().setEditedSuggestionInfo(editedSuggestionInfo);
         riv.focusAnimated();
         if (userMessageContent != null) {
             riv.setEditTextContent(userMessageContent);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 267ee6d..a0388de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -259,6 +259,7 @@
                 addListener(object : AnimatorListenerAdapter() {
                     override fun onAnimationEnd(animation: Animator?) {
                         keyguardAnimator = null
+                        wakeAndUnlockBlurRadius = 0f
                         scheduleUpdate()
                     }
                 })
@@ -439,7 +440,7 @@
             it.println("StatusBarWindowBlurController:")
             it.increaseIndent()
             it.println("shadeExpansion: $shadeExpansion")
-            it.println("shouldApplyShaeBlur: ${shouldApplyShadeBlur()}")
+            it.println("shouldApplyShadeBlur: ${shouldApplyShadeBlur()}")
             it.println("shadeAnimation: ${shadeAnimation.radius}")
             it.println("brightnessMirrorRadius: ${brightnessMirrorSpring.radius}")
             it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
index d4d84c1..4e1404d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.events
 
+import android.annotation.SuppressLint
 import android.content.Context
 import android.graphics.Color
 import android.graphics.drawable.ColorDrawable
@@ -27,13 +28,15 @@
 import com.android.systemui.privacy.OngoingPrivacyChip
 import com.android.systemui.privacy.PrivacyItem
 
+typealias ViewCreator = (context: Context) -> BackgroundAnimatableView
+
 interface StatusEvent {
     val priority: Int
     // Whether or not to force the status bar open and show a dot
     val forceVisible: Boolean
     // Whether or not to show an animation for this event
     val showAnimation: Boolean
-    val viewCreator: (context: Context) -> View
+    val viewCreator: ViewCreator
     var contentDescription: String?
 
     // Update this event with values from another event.
@@ -47,14 +50,37 @@
     }
 }
 
+class BGView(
+    context: Context
+) : View(context), BackgroundAnimatableView {
+    override val view: View
+        get() = this
+
+    override fun setBoundsForAnimation(l: Int, t: Int, r: Int, b: Int) {
+        setLeftTopRightBottom(l, t, r, b)
+    }
+}
+
+@SuppressLint("AppCompatCustomView")
+class BGImageView(
+    context: Context
+) : ImageView(context), BackgroundAnimatableView {
+    override val view: View
+        get() = this
+
+    override fun setBoundsForAnimation(l: Int, t: Int, r: Int, b: Int) {
+        setLeftTopRightBottom(l, t, r, b)
+    }
+}
+
 class BatteryEvent : StatusEvent {
     override val priority = 50
     override val forceVisible = false
     override val showAnimation = true
     override var contentDescription: String? = ""
 
-    override val viewCreator: (context: Context) -> View = { context ->
-        val iv = ImageView(context)
+    override val viewCreator: (context: Context) -> BGImageView = { context ->
+        val iv = BGImageView(context)
         iv.setImageDrawable(ThemedBatteryDrawable(context, Color.WHITE))
         iv.setBackgroundDrawable(ColorDrawable(Color.GREEN))
         iv
@@ -72,7 +98,7 @@
     var privacyItems: List<PrivacyItem> = listOf()
     private var privacyChip: OngoingPrivacyChip? = null
 
-    override val viewCreator: (context: Context) -> View = { context ->
+    override val viewCreator: ViewCreator = { context ->
         val v = LayoutInflater.from(context)
                 .inflate(R.layout.ongoing_privacy_chip, null) as OngoingPrivacyChip
         v.privacyList = privacyItems
@@ -82,7 +108,7 @@
     }
 
     override fun toString(): String {
-        return javaClass.simpleName
+        return "${javaClass.simpleName}(forceVisible=$forceVisible, privacyItems=$privacyItems)"
     }
 
     override fun shouldUpdateFromEvent(other: StatusEvent?): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
index d5a0467..9795dcf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
@@ -18,14 +18,16 @@
 
 import android.animation.ValueAnimator
 import android.content.Context
+import android.graphics.Point
 import android.view.Gravity
 import android.view.LayoutInflater
 import android.view.View
+import android.view.View.MeasureSpec.AT_MOST
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import android.widget.FrameLayout
 import com.android.systemui.R
-import com.android.systemui.statusbar.phone.StatusBarLocationPublisher
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import javax.inject.Inject
 
@@ -35,44 +37,73 @@
 class SystemEventChipAnimationController @Inject constructor(
     private val context: Context,
     private val statusBarWindowController: StatusBarWindowController,
-    private val locationPublisher: StatusBarLocationPublisher
+    private val contentInsetsProvider: StatusBarContentInsetsProvider
 ) : SystemStatusChipAnimationCallback {
-    var showPersistentDot = false
-        set(value) {
-            field = value
-            statusBarWindowController.setForceStatusBarVisible(value)
-            maybeUpdateShowDot()
-        }
 
     private lateinit var animationWindowView: FrameLayout
-    private lateinit var animationDotView: View
-    private var currentAnimatedView: View? = null
+
+    private var currentAnimatedView: BackgroundAnimatableView? = null
+
+    // Left for LTR, Right for RTL
+    private var animationDirection = LEFT
+    private var chipRight = 0
+    private var chipLeft = 0
+    private var chipWidth = 0
+    private var dotCenter = Point(0, 0)
+    private var dotSize = context.resources.getDimensionPixelSize(
+            R.dimen.ongoing_appops_dot_diameter)
+    // If the chip animates away to a persistent dot, then we modify the CHIP_OUT animation
+    private var isAnimatingToDot = false
 
     // TODO: move to dagger
     private var initialized = false
 
     override fun onChipAnimationStart(
-        viewCreator: (context: Context) -> View,
+        viewCreator: ViewCreator,
         @SystemAnimationState state: Int
     ) {
         if (!initialized) init()
 
         if (state == ANIMATING_IN) {
-            currentAnimatedView = viewCreator(context)
-            animationWindowView.addView(currentAnimatedView, layoutParamsDefault())
+            animationDirection = if (animationWindowView.isLayoutRtl) RIGHT else LEFT
 
-            // We are animating IN; chip comes in from View.END
+            // Initialize the animated view
+            val insets = contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()
+            currentAnimatedView = viewCreator(context).also {
+                animationWindowView.addView(
+                        it.view,
+                        layoutParamsDefault(
+                                if (animationWindowView.isLayoutRtl) insets.first
+                                else insets.second))
+                it.view.alpha = 0f
+                // For some reason, the window view's measured width is always 0 here, so use the
+                // parent (status bar)
+                it.view.measure(
+                        View.MeasureSpec.makeMeasureSpec(
+                                (animationWindowView.parent as View).width, AT_MOST),
+                        View.MeasureSpec.makeMeasureSpec(animationWindowView.height, AT_MOST))
+                chipWidth = it.chipWidth
+            }
+
+            // decide which direction we're animating from, and then set some screen coordinates
+            val contentRect = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation()
+            when (animationDirection) {
+                LEFT -> {
+                    chipRight = contentRect.right
+                    chipLeft = contentRect.right - chipWidth
+                }
+                else /* RIGHT */ -> {
+                    chipLeft = contentRect.left
+                    chipRight = contentRect.left + chipWidth
+                }
+            }
+
             currentAnimatedView?.apply {
-                val translation = width.toFloat()
-                translationX = if (isLayoutRtl) -translation else translation
-                alpha = 0f
-                visibility = View.VISIBLE
-                setPadding(locationPublisher.marginLeft, 0, locationPublisher.marginRight, 0)
+                updateAnimatedViewBoundsForAmount(0.1f, this)
             }
         } else {
             // We are animating away
-            currentAnimatedView?.apply {
-                translationX = 0f
+            currentAnimatedView!!.view.apply {
                 alpha = 1f
             }
         }
@@ -82,15 +113,14 @@
         if (state == ANIMATING_IN) {
             // Finished animating in
             currentAnimatedView?.apply {
-                translationX = 0f
-                alpha = 1f
+                updateAnimatedViewBoundsForAmount(1f, this)
             }
         } else {
             // Finished animating away
-            currentAnimatedView?.apply {
+            currentAnimatedView!!.view.apply {
                 visibility = View.INVISIBLE
             }
-            animationWindowView.removeView(currentAnimatedView)
+            animationWindowView.removeView(currentAnimatedView!!.view)
         }
     }
 
@@ -98,22 +128,10 @@
         animator: ValueAnimator,
         @SystemAnimationState state: Int
     ) {
-        // Alpha is parameterized 0,1, and translation from (width, 0)
         currentAnimatedView?.apply {
-            val amt = animator.animatedValue as Float
-
-            alpha = amt
-
-            val w = width
-            val translation = (1 - amt) * w
-            translationX = if (isLayoutRtl) -translation else translation
-        }
-    }
-
-    private fun maybeUpdateShowDot() {
-        if (!initialized) return
-        if (!showPersistentDot && currentAnimatedView == null) {
-            animationDotView.visibility = View.INVISIBLE
+            val amt = (animator.animatedValue as Float).amt()
+            view.alpha = (animator.animatedValue as Float)
+            updateAnimatedViewBoundsForAmount(amt, this)
         }
     }
 
@@ -121,19 +139,56 @@
         initialized = true
         animationWindowView = LayoutInflater.from(context)
                 .inflate(R.layout.system_event_animation_window, null) as FrameLayout
-        animationDotView = animationWindowView.findViewById(R.id.dot_view)
         val lp = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
         lp.gravity = Gravity.END or Gravity.CENTER_VERTICAL
         statusBarWindowController.addViewToWindow(animationWindowView, lp)
+        animationWindowView.clipToPadding = false
+        animationWindowView.clipChildren = false
+        animationWindowView.measureAllChildren = true
+    }
+
+    private fun layoutParamsDefault(marginEnd: Int): FrameLayout.LayoutParams =
+            FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).also {
+                it.gravity = Gravity.END or Gravity.CENTER_VERTICAL
+                it.marginEnd = marginEnd
+            }
+
+    private fun updateAnimatedViewBoundsForAmount(amt: Float, chip: BackgroundAnimatableView) {
+        when (animationDirection) {
+            LEFT -> {
+                chip.setBoundsForAnimation(
+                        (chipRight - (chipWidth * amt)).toInt(),
+                        chip.view.top,
+                        chipRight,
+                        chip.view.bottom)
+            }
+            else /* RIGHT */ -> {
+                chip.setBoundsForAnimation(
+                        chipLeft,
+                        chip.view.top,
+                        (chipLeft + (chipWidth * amt)).toInt(),
+                        chip.view.bottom)
+            }
+        }
     }
 
     private fun start() = if (animationWindowView.isLayoutRtl) right() else left()
-    private fun right() = locationPublisher.marginRight
-    private fun left() = locationPublisher.marginLeft
-
-    private fun layoutParamsDefault(): FrameLayout.LayoutParams =
-        FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).also {
-            it.gravity = Gravity.END or Gravity.CENTER_VERTICAL
-            it.marginStart = start()
-    }
+    private fun right() = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation().right
+    private fun left() = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation().left
+    private fun Float.amt() = 0.01f.coerceAtLeast(this)
 }
+
+/**
+ * Chips should provide a view that can be animated with something better than a fade-in
+ */
+interface BackgroundAnimatableView {
+    val view: View // Since this can't extend View, add a view prop
+        get() = this as View
+    val chipWidth: Int
+        get() = view.measuredWidth
+    fun setBoundsForAnimation(l: Int, t: Int, r: Int, b: Int)
+}
+
+// Animation directions
+private const val LEFT = 1
+private const val RIGHT = 2
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
index 04f7492..fde5d39 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
@@ -70,11 +70,11 @@
     fun notifyPrivacyItemsChanged(showAnimation: Boolean = true) {
         val event = PrivacyEvent(showAnimation)
         event.privacyItems = privacyStateListener.currentPrivacyItems
-        event.contentDescription = {
+        event.contentDescription = run {
             val items = PrivacyChipBuilder(context, event.privacyItems).joinTypes()
             context.getString(
                     R.string.ongoing_privacy_chip_content_multiple_apps, items)
-        }()
+        }
         scheduler.onStatusEvent(event)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
index 5a27329..947f3eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -21,12 +21,12 @@
 import android.animation.AnimatorSet
 import android.animation.ValueAnimator
 import android.annotation.IntDef
-import android.content.Context
 import android.os.Process
 import android.provider.DeviceConfig
 import android.util.Log
-import android.view.View
 import com.android.systemui.Dumpable
+import com.android.systemui.animation.Interpolators.STANDARD_ACCELERATE
+import com.android.systemui.animation.Interpolators.STANDARD_DECELERATE
 
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
@@ -45,7 +45,7 @@
  * Dead-simple scheduler for system status events. Obeys the following principles (all values TBD):
  *      - Avoiding log spam by only allowing 12 events per minute (1event/5s)
  *      - Waits 100ms to schedule any event for debouncing/prioritization
- *      - Simple prioritization: Privacy > Battery > connectivity (encoded in StatusEvent)
+ *      - Simple prioritization: Privacy > Battery > connectivity (encoded in [StatusEvent])
  *      - Only schedules a single event, and throws away lowest priority events
  *
  * There are 4 basic stages of animation at play here:
@@ -111,7 +111,7 @@
             scheduleEvent(event)
         } else if (scheduledEvent?.shouldUpdateFromEvent(event) == true) {
             if (DEBUG) {
-                Log.d(TAG, "updating current event from: $event")
+                Log.d(TAG, "updating current event from: $event. animationState=$animationState")
             }
             scheduledEvent?.updateFromEvent(event)
             if (event.forceVisible) {
@@ -172,12 +172,14 @@
             entranceAnimator.duration = ENTRANCE_ANIM_LENGTH
             entranceAnimator.addListener(systemAnimatorAdapter)
             entranceAnimator.addUpdateListener(systemUpdateListener)
+            entranceAnimator.interpolator = STANDARD_ACCELERATE
 
             val chipAnimator = ValueAnimator.ofFloat(0f, 1f)
             chipAnimator.duration = CHIP_ANIM_LENGTH
             chipAnimator.addListener(
                     ChipAnimatorAdapter(RUNNING_CHIP_ANIM, scheduledEvent!!.viewCreator))
             chipAnimator.addUpdateListener(chipUpdateListener)
+            chipAnimator.interpolator = STANDARD_DECELERATE
 
             val aSet2 = AnimatorSet()
             aSet2.playSequentially(entranceAnimator, chipAnimator)
@@ -190,6 +192,12 @@
                 systemAnimator.duration = ENTRANCE_ANIM_LENGTH
                 systemAnimator.addListener(systemAnimatorAdapter)
                 systemAnimator.addUpdateListener(systemUpdateListener)
+                systemAnimator.interpolator = STANDARD_DECELERATE
+                systemAnimator.addListener(object : AnimatorListenerAdapter() {
+                    override fun onAnimationEnd(animation: Animator?) {
+                        statusBarWindowController.setForceStatusBarVisible(false)
+                    }
+                })
 
                 val chipAnimator = ValueAnimator.ofFloat(1f, 0f)
                 chipAnimator.duration = CHIP_ANIM_LENGTH
@@ -201,6 +209,7 @@
                 chipAnimator.addListener(
                     ChipAnimatorAdapter(endState, scheduledEvent!!.viewCreator))
                 chipAnimator.addUpdateListener(chipUpdateListener)
+                chipAnimator.interpolator = STANDARD_ACCELERATE
 
                 val aSet2 = AnimatorSet()
 
@@ -212,7 +221,6 @@
 
                 aSet2.start()
 
-                statusBarWindowController.setForceStatusBarVisible(false)
                 scheduledEvent = null
             }, DISPLAY_LENGTH)
         }, DELAY)
@@ -313,7 +321,7 @@
 
     inner class ChipAnimatorAdapter(
         @SystemAnimationState val endState: Int,
-        val viewCreator: (context: Context) -> View
+        val viewCreator: ViewCreator
     ) : AnimatorListenerAdapter() {
         override fun onAnimationEnd(p0: Animator?) {
             chipAnimationController.onChipAnimationEnd(animationState)
@@ -359,7 +367,7 @@
     fun onChipAnimationUpdate(animator: ValueAnimator, @SystemAnimationState state: Int) {}
 
     fun onChipAnimationStart(
-        viewCreator: (context: Context) -> View,
+        viewCreator: ViewCreator,
         @SystemAnimationState state: Int
     ) {}
 
@@ -371,7 +379,7 @@
 @Retention(AnnotationRetention.SOURCE)
 @IntDef(
         value = [
-            IDLE, ANIMATING_IN, RUNNING_CHIP_ANIM, ANIMATING_OUT
+            IDLE, ANIMATING_IN, RUNNING_CHIP_ANIM, ANIMATING_OUT, SHOWING_PERSISTENT_DOT
         ]
 )
 annotation class SystemAnimationState
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
index 5b7d90b..df412ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -16,11 +16,9 @@
 
 package com.android.systemui.statusbar.notification;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 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_SPLIT_SCREEN_PRIMARY;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -182,25 +180,6 @@
     }
 
     /**
-     * Posts an instant app notification if the top activity of the primary container in the
-     * splitted screen is an instant app and the corresponding instant app notification is not
-     * posted yet. If the notification already exists, this method removes it from {@code
-     * notifs} in the arguments.
-     */
-    private void checkAndPostForPrimaryScreen(
-            @NonNull ArraySet<Pair<String, Integer>> notifs,
-            @NonNull NotificationManager noMan,
-            @NonNull IPackageManager pm) {
-        try {
-            final RootTaskInfo info = ActivityTaskManager.getService().getRootTaskInfo(
-                    WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
-            checkAndPostForStack(info, notifs, noMan, pm);
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Posts an instant app notification if the top activity of the given stack is an instant app
      * and the corresponding instant app notification is not posted yet. If the notification already
      * exists, this method removes it from {@code notifs} in the arguments.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
index 2c1296f..7fbb0f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
@@ -22,15 +22,18 @@
     private val headsUpManager: HeadsUpManagerPhone,
     private val jankMonitor: InteractionJankMonitor
 ) {
+    @JvmOverloads
     fun getAnimatorController(
-        notification: ExpandableNotificationRow
+        notification: ExpandableNotificationRow,
+        onFinishAnimationCallback: Runnable = Runnable {}
     ): NotificationLaunchAnimatorController {
         return NotificationLaunchAnimatorController(
             notificationShadeWindowViewController,
             notificationListContainer,
             headsUpManager,
             notification,
-            jankMonitor
+            jankMonitor,
+            onFinishAnimationCallback
         )
     }
 }
@@ -45,7 +48,8 @@
     private val notificationListContainer: NotificationListContainer,
     private val headsUpManager: HeadsUpManagerPhone,
     private val notification: ExpandableNotificationRow,
-    private val jankMonitor: InteractionJankMonitor
+    private val jankMonitor: InteractionJankMonitor,
+    private val onFinishAnimationCallback: Runnable
 ) : ActivityLaunchAnimator.Controller {
 
     companion object {
@@ -119,6 +123,7 @@
 
         if (!willAnimate) {
             removeHun(animate = true)
+            onFinishAnimationCallback.run()
         }
     }
 
@@ -137,6 +142,7 @@
         notificationShadeWindowViewController.setExpandAnimationRunning(false)
         notificationEntry.isExpandAnimationRunning = false
         removeHun(animate = true)
+        onFinishAnimationCallback.run()
     }
 
     override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
@@ -156,6 +162,7 @@
         notificationListContainer.setExpandingNotification(null)
         applyParams(null)
         removeHun(animate = false)
+        onFinishAnimationCallback.run()
     }
 
     private fun applyParams(params: ExpandAnimationParameters?) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 369ef34..2baa079 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -230,7 +230,13 @@
         mPipelineState.requireState(STATE_IDLE);
 
         mNotifSections.clear();
+        NotifSectioner lastSection = null;
         for (NotifSectioner sectioner : sectioners) {
+            if (lastSection != null && lastSection.getBucket() > sectioner.getBucket()) {
+                throw new IllegalArgumentException("setSectioners with non contiguous sections "
+                        + lastSection.getName() + " - " + lastSection.getBucket() + " & "
+                        + sectioner.getName() + " - " + sectioner.getBucket());
+            }
             final NotifSection section = new NotifSection(sectioner, mNotifSections.size());
             final NotifComparator sectionComparator = section.getComparator();
             mNotifSections.add(section);
@@ -238,6 +244,7 @@
             if (sectionComparator != null) {
                 sectionComparator.setInvalidationListener(this::onNotifComparatorInvalidated);
             }
+            lastSection = sectioner;
         }
 
         mNotifSections.add(new NotifSection(DEFAULT_SECTIONER, mNotifSections.size()));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinator.kt
new file mode 100644
index 0000000..b54163d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinator.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.coordinator
+
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender.OnEndLifetimeExtensionCallback
+import com.android.systemui.statusbar.phone.NotifActivityLaunchEvents
+import dagger.Binds
+import dagger.Module
+import javax.inject.Inject
+
+/** Extends the lifetime of notifications while their activity launch animation is playing. */
+interface ActivityLaunchAnimCoordinator : Coordinator
+
+/** Provides an [ActivityLaunchAnimCoordinator] to [CoordinatorScope]. */
+@Module(includes = [PrivateActivityStarterCoordinatorModule::class])
+object ActivityLaunchAnimCoordinatorModule
+
+@Module
+private interface PrivateActivityStarterCoordinatorModule {
+    @Binds
+    fun bindCoordinator(impl: ActivityLaunchAnimCoordinatorImpl): ActivityLaunchAnimCoordinator
+}
+
+/**
+ * Listens for [NotifActivityLaunchEvents], and then extends the lifetimes of any notifs while their
+ * launch animation is playing.
+ */
+@CoordinatorScope
+private class ActivityLaunchAnimCoordinatorImpl @Inject constructor(
+    private val activityLaunchEvents: NotifActivityLaunchEvents
+) : ActivityLaunchAnimCoordinator {
+    // Tracks notification launches, and whether or not their lifetimes are extended.
+    private val notifsLaunchingActivities = mutableMapOf<String, Boolean>()
+
+    private var onEndLifetimeExtensionCallback: OnEndLifetimeExtensionCallback? = null
+
+    override fun attach(pipeline: NotifPipeline) {
+        activityLaunchEvents.registerListener(activityStartEventListener)
+        pipeline.addNotificationLifetimeExtender(extender)
+    }
+
+    private val activityStartEventListener = object : NotifActivityLaunchEvents.Listener {
+        override fun onStartLaunchNotifActivity(entry: NotificationEntry) {
+            notifsLaunchingActivities[entry.key] = false
+        }
+
+        override fun onFinishLaunchNotifActivity(entry: NotificationEntry) {
+            if (notifsLaunchingActivities.remove(entry.key) == true) {
+                // If we were extending the lifetime of this notification, stop.
+                onEndLifetimeExtensionCallback?.onEndLifetimeExtension(extender, entry)
+            }
+        }
+    }
+
+    private val extender = object : NotifLifetimeExtender {
+        override fun getName(): String = "ActivityStarterCoordinator"
+
+        override fun setCallback(callback: OnEndLifetimeExtensionCallback) {
+            onEndLifetimeExtensionCallback = callback
+        }
+
+        override fun maybeExtendLifetime(entry: NotificationEntry, reason: Int): Boolean {
+            if (entry.key in notifsLaunchingActivities) {
+                // Track that we're now extending this notif
+                notifsLaunchingActivities[entry.key] = true
+                return true
+            }
+            return false
+        }
+
+        override fun cancelLifetimeExtension(entry: NotificationEntry) {
+            if (entry.key in notifsLaunchingActivities) {
+                notifsLaunchingActivities[entry.key] = false
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java
deleted file mode 100644
index 5396b86..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.collection.coordinator;
-
-import androidx.annotation.NonNull;
-
-import com.android.systemui.communal.CommunalStateController;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotifPipeline;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
-import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
-
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-
-/**
- * {@link CommunalCoordinator} prevents notifications from showing on the keyguard when the communal
- * view is present.
- */
-@CoordinatorScope
-public class CommunalCoordinator implements Coordinator {
-    final Executor mExecutor;
-    final CommunalStateController mCommunalStateController;
-    final NotificationEntryManager mNotificationEntryManager;
-    final NotificationLockscreenUserManager mNotificationLockscreenUserManager;
-
-    @Inject
-    public CommunalCoordinator(@Main Executor executor,
-            NotificationEntryManager notificationEntryManager,
-            NotificationLockscreenUserManager notificationLockscreenUserManager,
-            CommunalStateController communalStateController) {
-        mExecutor = executor;
-        mNotificationEntryManager = notificationEntryManager;
-        mNotificationLockscreenUserManager = notificationLockscreenUserManager;
-        mCommunalStateController = communalStateController;
-    }
-
-    final NotifFilter mFilter = new NotifFilter("CommunalCoordinator") {
-        @Override
-        public boolean shouldFilterOut(@NonNull NotificationEntry entry, long now) {
-            return mCommunalStateController.getCommunalViewShowing();
-        }
-    };
-
-    final CommunalStateController.Callback mStateCallback = new CommunalStateController.Callback() {
-        @Override
-        public void onCommunalViewShowingChanged() {
-            mExecutor.execute(() -> {
-                mFilter.invalidateList();
-                mNotificationEntryManager.updateNotifications("Communal mode state changed");
-            });
-        }
-    };
-
-    @Override
-    public void attach(@NonNull NotifPipeline pipeline) {
-        pipeline.addPreGroupFilter(mFilter);
-        mCommunalStateController.addCallback(mStateCallback);
-        if (!pipeline.isNewPipelineEnabled()) {
-            mNotificationLockscreenUserManager.addKeyguardNotificationSuppressor(
-                    entry -> mCommunalStateController.getCommunalViewShowing());
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
index 41b0706..da0169b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
@@ -72,9 +72,10 @@
     private var mEndLifetimeExtension: OnEndLifetimeExtensionCallback? = null
     private lateinit var mNotifPipeline: NotifPipeline
     private var mNow: Long = -1
+    private val mPostedEntries = LinkedHashMap<String, PostedEntry>()
 
-    // notifs we've extended the lifetime for
-    private val mNotifsExtendingLifetime = ArraySet<NotificationEntry>()
+    // notifs we've extended the lifetime for with cancellation callbacks
+    private val mNotifsExtendingLifetime = ArrayMap<NotificationEntry, Runnable?>()
 
     override fun attach(pipeline: NotifPipeline) {
         mNotifPipeline = pipeline
@@ -101,10 +102,12 @@
             return
         }
         // Process all non-group adds/updates
-        mPostedEntries.values.toList().forEach { posted ->
-            if (!posted.entry.sbn.isGroup) {
-                handlePostedEntry(posted, "non-group")
-                mPostedEntries.remove(posted.key)
+        mHeadsUpManager.modifyHuns { hunMutator ->
+            mPostedEntries.values.toList().forEach { posted ->
+                if (!posted.entry.sbn.isGroup) {
+                    handlePostedEntry(posted, hunMutator, "non-group")
+                    mPostedEntries.remove(posted.key)
+                }
             }
         }
     }
@@ -114,10 +117,10 @@
      * we know that stability and [NotifPromoter]s have been applied, so we can use the location of
      * notifications in this list to determine what kind of group alert behavior should happen.
      */
-    fun onBeforeFinalizeFilter(list: List<ListEntry>) {
+    fun onBeforeFinalizeFilter(list: List<ListEntry>) = mHeadsUpManager.modifyHuns { hunMutator ->
         // Nothing to do if there are no other adds/updates
         if (mPostedEntries.isEmpty()) {
-            return
+            return@modifyHuns
         }
         // Calculate a bunch of information about the logical group and the locations of group
         // entries in the nearly-finalized shade list.  These may be used in the per-group loop.
@@ -138,13 +141,17 @@
 
             // If there is no logical summary, then there is no alert to transfer
             if (logicalSummary == null) {
-                postedEntries.forEach { handlePostedEntry(it, "logical-summary-missing") }
+                postedEntries.forEach {
+                    handlePostedEntry(it, hunMutator, scenario = "logical-summary-missing")
+                }
                 return@forEach
             }
 
             // If summary isn't wanted to be heads up, then there is no alert to transfer
             if (!isGoingToShowHunStrict(logicalSummary)) {
-                postedEntries.forEach { handlePostedEntry(it, "logical-summary-not-alerting") }
+                postedEntries.forEach {
+                    handlePostedEntry(it, hunMutator, scenario = "logical-summary-not-alerting")
+                }
                 return@forEach
             }
 
@@ -177,7 +184,9 @@
             // If there is no child to receive the parent alert, then just handle the posted entries
             // and return.
             if (childToReceiveParentAlert == null) {
-                postedEntries.forEach { handlePostedEntry(it, "no-transfer-target") }
+                postedEntries.forEach {
+                    handlePostedEntry(it, hunMutator, scenario = "no-transfer-target")
+                }
                 return@forEach
             }
 
@@ -189,51 +198,66 @@
             if (!isSummaryAttached) {
                 val summaryUpdateForRemoval = summaryUpdate?.also {
                     it.shouldHeadsUpEver = false
-                } ?: PostedEntry(logicalSummary,
-                    wasAdded = false,
-                    wasUpdated = false,
-                    shouldHeadsUpEver = false,
-                    shouldHeadsUpAgain = false,
-                    isAlerting = mHeadsUpManager.isAlerting(logicalSummary.key),
-                    isBinding = isEntryBinding(logicalSummary),
+                } ?: PostedEntry(
+                        logicalSummary,
+                        wasAdded = false,
+                        wasUpdated = false,
+                        shouldHeadsUpEver = false,
+                        shouldHeadsUpAgain = false,
+                        isAlerting = mHeadsUpManager.isAlerting(logicalSummary.key),
+                        isBinding = isEntryBinding(logicalSummary),
                 )
                 // If we transfer the alert and the summary isn't even attached, that means we
                 // should ensure the summary is no longer alerting, so we remove it here.
-                handlePostedEntry(summaryUpdateForRemoval, "detached-summary-remove-alert")
-            } else if (summaryUpdate!=null) {
-                mLogger.logPostedEntryWillNotEvaluate(summaryUpdate, "attached-summary-transferred")
+                handlePostedEntry(
+                        summaryUpdateForRemoval,
+                        hunMutator,
+                        scenario = "detached-summary-remove-alert")
+            } else if (summaryUpdate != null) {
+                mLogger.logPostedEntryWillNotEvaluate(
+                        summaryUpdate,
+                        reason = "attached-summary-transferred")
             }
 
             // Handle all posted entries -- if the child receiving the parent's alert is in the
             // list, then set its flags to ensure it alerts.
             var didAlertChildToReceiveParentAlert = false
             postedEntries.asSequence()
-                .filter { it.key != logicalSummary.key }
-                .forEach { postedEntry ->
-                    if (childToReceiveParentAlert.key == postedEntry.key) {
-                        // Update the child's posted update so that it
-                        postedEntry.shouldHeadsUpEver = true
-                        postedEntry.shouldHeadsUpAgain = true
-                        handlePostedEntry(postedEntry, "child-alert-transfer-target-$targetType")
-                        didAlertChildToReceiveParentAlert = true
-                    } else {
-                        handlePostedEntry(postedEntry, "child-alert-non-target")
+                    .filter { it.key != logicalSummary.key }
+                    .forEach { postedEntry ->
+                        if (childToReceiveParentAlert.key == postedEntry.key) {
+                            // Update the child's posted update so that it
+                            postedEntry.shouldHeadsUpEver = true
+                            postedEntry.shouldHeadsUpAgain = true
+                            handlePostedEntry(
+                                    postedEntry,
+                                    hunMutator,
+                                    scenario = "child-alert-transfer-target-$targetType")
+                            didAlertChildToReceiveParentAlert = true
+                        } else {
+                            handlePostedEntry(
+                                    postedEntry,
+                                    hunMutator,
+                                    scenario = "child-alert-non-target")
+                        }
                     }
-                }
 
             // If the child receiving the alert was not updated on this tick (which can happen in a
             // standard alert transfer scenario), then construct an update so that we can apply it.
             if (!didAlertChildToReceiveParentAlert) {
                 val posted = PostedEntry(
-                    childToReceiveParentAlert,
-                    wasAdded = false,
-                    wasUpdated = false,
-                    shouldHeadsUpEver = true,
-                    shouldHeadsUpAgain = true,
-                    isAlerting = mHeadsUpManager.isAlerting(childToReceiveParentAlert.key),
-                    isBinding = isEntryBinding(childToReceiveParentAlert),
+                        childToReceiveParentAlert,
+                        wasAdded = false,
+                        wasUpdated = false,
+                        shouldHeadsUpEver = true,
+                        shouldHeadsUpAgain = true,
+                        isAlerting = mHeadsUpManager.isAlerting(childToReceiveParentAlert.key),
+                        isBinding = isEntryBinding(childToReceiveParentAlert),
                 )
-                handlePostedEntry(posted, "non-posted-child-alert-transfer-target-$targetType")
+                handlePostedEntry(
+                        posted,
+                        hunMutator,
+                        scenario = "non-posted-child-alert-transfer-target-$targetType")
             }
         }
         // After this method runs, all posted entries should have been handled (or skipped).
@@ -292,9 +316,7 @@
             }
         }
 
-    private val mPostedEntries = LinkedHashMap<String, PostedEntry>()
-
-    fun handlePostedEntry(posted: PostedEntry, scenario: String) {
+    private fun handlePostedEntry(posted: PostedEntry, hunMutator: HunMutator, scenario: String) {
         mLogger.logPostedEntryWillEvaluate(posted, scenario)
         if (posted.wasAdded) {
             if (posted.shouldHeadsUpEver) {
@@ -308,12 +330,12 @@
                     // If alerting, we need to post an update.  Otherwise we're still binding,
                     // and we can just let that finish.
                     if (posted.isAlerting) {
-                        mHeadsUpManager.updateNotification(posted.key, posted.shouldHeadsUpAgain)
+                        hunMutator.updateNotification(posted.key, posted.shouldHeadsUpAgain)
                     }
                 } else {
                     if (posted.isAlerting) {
                         // We don't want this to be interrupting anymore, let's remove it
-                        mHeadsUpManager.removeNotification(posted.key, false /*removeImmediately*/)
+                        hunMutator.removeNotification(posted.key, false /*removeImmediately*/)
                     } else {
                         // Don't let the bind finish
                         cancelHeadsUpBind(posted.entry)
@@ -366,7 +388,7 @@
             val shouldHeadsUpAgain = shouldHunAgain(entry)
             val isAlerting = mHeadsUpManager.isAlerting(entry.key)
             val isBinding = isEntryBinding(entry)
-            mPostedEntries.compute(entry.key) { _, value ->
+            val posted = mPostedEntries.compute(entry.key) { _, value ->
                 value?.also { update ->
                     update.wasUpdated = true
                     update.shouldHeadsUpEver = update.shouldHeadsUpEver || shouldHeadsUpEver
@@ -383,6 +405,18 @@
                     isBinding = isBinding,
                 )
             }
+            // Handle cancelling alerts here, rather than in the OnBeforeFinalizeFilter, so that
+            // work can be done before the ShadeListBuilder is run. This prevents re-entrant
+            // behavior between this Coordinator, HeadsUpManager, and VisualStabilityManager.
+            if (posted?.shouldHeadsUpEver == false) {
+                if (posted.isAlerting) {
+                    // We don't want this to be interrupting anymore, let's remove it
+                    mHeadsUpManager.removeNotification(posted.key, false /*removeImmediately*/)
+                } else if (posted.isBinding) {
+                    // Don't let the bind finish
+                    cancelHeadsUpBind(posted.entry)
+                }
+            }
         }
 
         /**
@@ -427,23 +461,20 @@
             }
             if (isSticky(entry)) {
                 val removeAfterMillis = mHeadsUpManager.getEarliestRemovalTime(entry.key)
-                mExecutor.executeDelayed({
-                    val canStillRemove = mHeadsUpManager.canRemoveImmediately(entry.key)
-                    if (mNotifsExtendingLifetime.contains(entry) && canStillRemove) {
-                        mHeadsUpManager.removeNotification(entry.key, /* releaseImmediately */ true)
-                    }
+                mNotifsExtendingLifetime[entry] = mExecutor.executeDelayed({
+                    mHeadsUpManager.removeNotification(entry.key, /* releaseImmediately */ true)
                 }, removeAfterMillis)
             } else {
                 mExecutor.execute {
                     mHeadsUpManager.removeNotification(entry.key, /* releaseImmediately */ false)
                 }
+                mNotifsExtendingLifetime[entry] = null
             }
-            mNotifsExtendingLifetime.add(entry)
             return true
         }
 
         override fun cancelLifetimeExtension(entry: NotificationEntry) {
-            mNotifsExtendingLifetime.remove(entry)
+            mNotifsExtendingLifetime.remove(entry)?.run()
         }
     }
 
@@ -510,7 +541,8 @@
         mPostedEntries[entry.key]?.calculateShouldBeHeadsUpStrict ?: isAttemptingToShowHun(entry)
 
     private fun endNotifLifetimeExtensionIfExtended(entry: NotificationEntry) {
-        if (mNotifsExtendingLifetime.remove(entry)) {
+        if (mNotifsExtendingLifetime.contains(entry)) {
+            mNotifsExtendingLifetime.remove(entry)?.run()
             mEndLifetimeExtension?.onEndLifetimeExtension(mLifetimeExtender, entry)
         }
     }
@@ -543,3 +575,43 @@
 
 private fun Map<String, GroupLocation>.getLocation(key: String): GroupLocation =
     getOrDefault(key, GroupLocation.Detached)
+
+/**
+ * Invokes the given block with a [HunMutator] that defers all HUN removals. This ensures that the
+ * HeadsUpManager is notified of additions before removals, which prevents a glitch where the
+ * HeadsUpManager temporarily believes that nothing is alerting, causing bad re-entrant behavior.
+ */
+private fun <R> HeadsUpManager.modifyHuns(block: (HunMutator) -> R): R {
+    val mutator = HunMutatorImpl(this)
+    return block(mutator).also { mutator.commitModifications() }
+}
+
+/** Mutates the HeadsUp state of notifications. */
+private interface HunMutator {
+    fun updateNotification(key: String, alert: Boolean)
+    fun removeNotification(key: String, releaseImmediately: Boolean)
+}
+
+/**
+ * [HunMutator] implementation that defers removing notifications from the HeadsUpManager until
+ * after additions/updates.
+ */
+private class HunMutatorImpl(private val headsUpManager: HeadsUpManager) : HunMutator {
+    private val deferred = mutableListOf<Pair<String, Boolean>>()
+
+    override fun updateNotification(key: String, alert: Boolean) {
+        headsUpManager.updateNotification(key, alert)
+    }
+
+    override fun removeNotification(key: String, releaseImmediately: Boolean) {
+        val args = Pair(key, releaseImmediately)
+        deferred.add(args)
+    }
+
+    fun commitModifications() {
+        deferred.forEach { (key, releaseImmediately) ->
+            headsUpManager.removeNotification(key, releaseImmediately)
+        }
+        deferred.clear()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
index 22300d8..1237c70 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
@@ -16,36 +16,16 @@
 
 package com.android.systemui.statusbar.notification.collection.coordinator;
 
-import static android.app.Notification.VISIBILITY_SECRET;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.service.notification.StatusBarNotification;
-
-import androidx.annotation.MainThread;
-
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider;
-import com.android.systemui.statusbar.notification.collection.GroupEntry;
-import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
 
 import javax.inject.Inject;
 
@@ -56,171 +36,48 @@
 @CoordinatorScope
 public class KeyguardCoordinator implements Coordinator {
     private static final String TAG = "KeyguardCoordinator";
-
-    private final Context mContext;
-    private final Handler mMainHandler;
-    private final KeyguardStateController mKeyguardStateController;
-    private final NotificationLockscreenUserManager mLockscreenUserManager;
-    private final BroadcastDispatcher mBroadcastDispatcher;
     private final StatusBarStateController mStatusBarStateController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final HighPriorityProvider mHighPriorityProvider;
     private final SectionHeaderVisibilityProvider mSectionHeaderVisibilityProvider;
-
-    private boolean mHideSilentNotificationsOnLockscreen;
+    private final KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;
 
     @Inject
     public KeyguardCoordinator(
-            Context context,
-            @MainThread Handler mainThreadHandler,
-            KeyguardStateController keyguardStateController,
-            NotificationLockscreenUserManager lockscreenUserManager,
-            BroadcastDispatcher broadcastDispatcher,
             StatusBarStateController statusBarStateController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             HighPriorityProvider highPriorityProvider,
-            SectionHeaderVisibilityProvider sectionHeaderVisibilityProvider) {
-        mContext = context;
-        mMainHandler = mainThreadHandler;
-        mKeyguardStateController = keyguardStateController;
-        mLockscreenUserManager = lockscreenUserManager;
-        mBroadcastDispatcher = broadcastDispatcher;
+            SectionHeaderVisibilityProvider sectionHeaderVisibilityProvider,
+            KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider) {
         mStatusBarStateController = statusBarStateController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mHighPriorityProvider = highPriorityProvider;
         mSectionHeaderVisibilityProvider = sectionHeaderVisibilityProvider;
+        mKeyguardNotificationVisibilityProvider = keyguardNotificationVisibilityProvider;
     }
 
     @Override
     public void attach(NotifPipeline pipeline) {
-        readShowSilentNotificationSetting();
 
         setupInvalidateNotifListCallbacks();
         // Filter at the "finalize" stage so that views remain bound by PreparationCoordinator
         pipeline.addFinalizeFilter(mNotifFilter);
-
+        mKeyguardNotificationVisibilityProvider
+                .addOnStateChangedListener(this::invalidateListFromFilter);
         updateSectionHeadersVisibility();
     }
 
     private final NotifFilter mNotifFilter = new NotifFilter(TAG) {
         @Override
         public boolean shouldFilterOut(NotificationEntry entry, long now) {
-            final StatusBarNotification sbn = entry.getSbn();
-
-            // FILTER OUT the notification when the keyguard is showing and...
-            if (mKeyguardStateController.isShowing()) {
-                // ... user settings or the device policy manager doesn't allow lockscreen
-                // notifications;
-                if (!mLockscreenUserManager.shouldShowLockscreenNotifications()) {
-                    return true;
-                }
-
-                final int currUserId = mLockscreenUserManager.getCurrentUserId();
-                final int notifUserId = (sbn.getUser().getIdentifier() == UserHandle.USER_ALL)
-                        ? currUserId : sbn.getUser().getIdentifier();
-
-                // ... user is in lockdown
-                if (mKeyguardUpdateMonitor.isUserInLockdown(currUserId)
-                        || mKeyguardUpdateMonitor.isUserInLockdown(notifUserId)) {
-                    return true;
-                }
-
-                // ... device is in public mode and the user's settings doesn't allow
-                // notifications to show in public mode
-                if (mLockscreenUserManager.isLockscreenPublicMode(currUserId)
-                        || mLockscreenUserManager.isLockscreenPublicMode(notifUserId)) {
-                    if (entry.getRanking().getLockscreenVisibilityOverride() == VISIBILITY_SECRET) {
-                        return true;
-                    }
-
-                    if (!mLockscreenUserManager.userAllowsNotificationsInPublic(currUserId)
-                            || !mLockscreenUserManager.userAllowsNotificationsInPublic(
-                            notifUserId)) {
-                        return true;
-                    }
-                }
-
-                // ... neither this notification nor its group have high enough priority
-                // to be shown on the lockscreen
-                if (entry.getParent() != null) {
-                    final GroupEntry parent = entry.getParent();
-                    if (priorityExceedsLockscreenShowingThreshold(parent)) {
-                        return false;
-                    }
-                }
-                return !priorityExceedsLockscreenShowingThreshold(entry);
-            }
-            return false;
+            return mKeyguardNotificationVisibilityProvider.hideNotification(entry);
         }
     };
 
-    private boolean priorityExceedsLockscreenShowingThreshold(ListEntry entry) {
-        if (entry == null) {
-            return false;
-        }
-        if (mHideSilentNotificationsOnLockscreen) {
-            return mHighPriorityProvider.isHighPriority(entry);
-        } else {
-            return entry.getRepresentativeEntry() != null
-                    && !entry.getRepresentativeEntry().getRanking().isAmbient();
-        }
-    }
-
     // TODO(b/206118999): merge this class with SensitiveContentCoordinator which also depends on
     // these same updates
     private void setupInvalidateNotifListCallbacks() {
-        // register onKeyguardShowing callback
-        mKeyguardStateController.addCallback(mKeyguardCallback);
-        mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
 
-        // register lockscreen settings changed callbacks:
-        final ContentObserver settingsObserver = new ContentObserver(mMainHandler) {
-            @Override
-            public void onChange(boolean selfChange, Uri uri) {
-                if (uri.equals(Settings.Secure.getUriFor(
-                        Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS))) {
-                    readShowSilentNotificationSetting();
-                }
-
-                if (mKeyguardStateController.isShowing()) {
-                    invalidateListFromFilter("Settings " + uri + " changed");
-                }
-            }
-        };
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS),
-                false,
-                settingsObserver,
-                UserHandle.USER_ALL);
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
-                true,
-                settingsObserver,
-                UserHandle.USER_ALL);
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.ZEN_MODE),
-                false,
-                settingsObserver);
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS),
-                false,
-                settingsObserver,
-                UserHandle.USER_ALL);
-
-        // register (maybe) public mode changed callbacks:
-        mStatusBarStateController.addCallback(mStatusBarStateListener);
-        mBroadcastDispatcher.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                if (mKeyguardStateController.isShowing()) {
-                    // maybe public mode changed
-                    invalidateListFromFilter(intent.getAction());
-                }
-            }}, new IntentFilter(Intent.ACTION_USER_SWITCHED));
     }
 
     private void invalidateListFromFilter(String reason) {
@@ -228,49 +85,10 @@
         mNotifFilter.invalidateList();
     }
 
-    private void readShowSilentNotificationSetting() {
-        mHideSilentNotificationsOnLockscreen =
-                Settings.Secure.getInt(
-                        mContext.getContentResolver(),
-                        Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS,
-                        1) == 0;
-    }
-
     private void updateSectionHeadersVisibility() {
         boolean onKeyguard = mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
         boolean neverShowSections = mSectionHeaderVisibilityProvider.getNeverShowSectionHeaders();
         boolean showSections = !onKeyguard && !neverShowSections;
         mSectionHeaderVisibilityProvider.setSectionHeadersVisible(showSections);
     }
-
-    private final KeyguardStateController.Callback mKeyguardCallback =
-            new KeyguardStateController.Callback() {
-        @Override
-        public void onUnlockedChanged() {
-            invalidateListFromFilter("onUnlockedChanged");
-        }
-
-        @Override
-        public void onKeyguardShowingChanged() {
-            invalidateListFromFilter("onKeyguardShowingChanged");
-        }
-    };
-
-    private final StatusBarStateController.StateListener mStatusBarStateListener =
-            new StatusBarStateController.StateListener() {
-                @Override
-                public void onStateChanged(int newState) {
-                    // maybe public mode changed
-                    invalidateListFromFilter("onStatusBarStateChanged");
-                }
-    };
-
-    private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
-            new KeyguardUpdateMonitorCallback() {
-        @Override
-        public void onStrongAuthStateChanged(int userId) {
-            // maybe lockdown mode changed
-            invalidateListFromFilter("onStrongAuthStateChanged");
-        }
-    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
index 757fb5a..985914a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
@@ -45,7 +45,6 @@
     bubbleCoordinator: BubbleCoordinator,
     headsUpCoordinator: HeadsUpCoordinator,
     gutsCoordinator: GutsCoordinator,
-    communalCoordinator: CommunalCoordinator,
     conversationCoordinator: ConversationCoordinator,
     debugModeCoordinator: DebugModeCoordinator,
     groupCountCoordinator: GroupCountCoordinator,
@@ -58,7 +57,8 @@
     smartspaceDedupingCoordinator: SmartspaceDedupingCoordinator,
     viewConfigCoordinator: ViewConfigCoordinator,
     visualStabilityCoordinator: VisualStabilityCoordinator,
-    sensitiveContentCoordinator: SensitiveContentCoordinator
+    sensitiveContentCoordinator: SensitiveContentCoordinator,
+    activityLaunchAnimCoordinator: ActivityLaunchAnimCoordinator
 ) : NotifCoordinators {
 
     private val mCoordinators: MutableList<Coordinator> = ArrayList()
@@ -86,7 +86,6 @@
         mCoordinators.add(appOpsCoordinator)
         mCoordinators.add(deviceProvisionedCoordinator)
         mCoordinators.add(bubbleCoordinator)
-        mCoordinators.add(communalCoordinator)
         mCoordinators.add(debugModeCoordinator)
         mCoordinators.add(conversationCoordinator)
         mCoordinators.add(groupCountCoordinator)
@@ -97,6 +96,7 @@
         mCoordinators.add(viewConfigCoordinator)
         mCoordinators.add(visualStabilityCoordinator)
         mCoordinators.add(sensitiveContentCoordinator)
+        mCoordinators.add(activityLaunchAnimCoordinator)
         if (notifPipelineFlags.isSmartspaceDedupingEnabled()) {
             mCoordinators.add(smartspaceDedupingCoordinator)
         }
@@ -144,4 +144,4 @@
     companion object {
         private const val TAG = "NotifCoordinators"
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
index 72d0918..3f8a39f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
@@ -34,11 +34,11 @@
 import dagger.Module
 import javax.inject.Inject
 
-@Module(includes = [PrivateModule::class])
+@Module(includes = [PrivateSensitiveContentCoordinatorModule::class])
 interface SensitiveContentCoordinatorModule
 
 @Module
-private interface PrivateModule {
+private interface PrivateSensitiveContentCoordinatorModule {
     @Binds
     fun bindCoordinator(impl: SensitiveContentCoordinatorImpl): SensitiveContentCoordinator
 }
@@ -121,4 +121,4 @@
         if (listEntry is GroupEntry) {
             yieldAll(extractAllRepresentativeEntries(listEntry.children))
         }
-    }
\ No newline at end of file
+    }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
index 3aa3549..699c4e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
@@ -32,7 +32,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
-import com.android.systemui.statusbar.notification.collection.render.NotifPanelEventSource;
+import com.android.systemui.statusbar.phone.NotifPanelEvents;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 
@@ -53,10 +53,10 @@
 // TODO(b/204468557): Move to @CoordinatorScope
 @SysUISingleton
 public class VisualStabilityCoordinator implements Coordinator, Dumpable,
-        NotifPanelEventSource.Callbacks {
+        NotifPanelEvents.Listener {
     private final DelayableExecutor mDelayableExecutor;
     private final HeadsUpManager mHeadsUpManager;
-    private final NotifPanelEventSource mNotifPanelEventSource;
+    private final NotifPanelEvents mNotifPanelEvents;
     private final StatusBarStateController mStatusBarStateController;
     private final VisualStabilityProvider mVisualStabilityProvider;
     private final WakefulnessLifecycle mWakefulnessLifecycle;
@@ -87,7 +87,7 @@
             DelayableExecutor delayableExecutor,
             DumpManager dumpManager,
             HeadsUpManager headsUpManager,
-            NotifPanelEventSource notifPanelEventSource,
+            NotifPanelEvents notifPanelEvents,
             StatusBarStateController statusBarStateController,
             VisualStabilityProvider visualStabilityProvider,
             WakefulnessLifecycle wakefulnessLifecycle) {
@@ -96,7 +96,7 @@
         mWakefulnessLifecycle = wakefulnessLifecycle;
         mStatusBarStateController = statusBarStateController;
         mDelayableExecutor = delayableExecutor;
-        mNotifPanelEventSource = notifPanelEventSource;
+        mNotifPanelEvents = notifPanelEvents;
 
         dumpManager.registerDumpable(this);
     }
@@ -109,7 +109,7 @@
 
         mStatusBarStateController.addCallback(mStatusBarStateControllerListener);
         mPulsing = mStatusBarStateController.isPulsing();
-        mNotifPanelEventSource.registerCallbacks(this);
+        mNotifPanelEvents.registerListener(this);
 
         pipeline.setVisualStabilityManager(mNotifStabilityManager);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt
index a26d50d..274affd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.notification.collection.coordinator.dagger
 
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.collection.coordinator.ActivityLaunchAnimCoordinatorModule
 import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators
 import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinatorsImpl
 import com.android.systemui.statusbar.notification.collection.coordinator.SensitiveContentCoordinatorModule
@@ -47,7 +48,10 @@
     }
 }
 
-@Module(includes = [SensitiveContentCoordinatorModule::class])
+@Module(includes = [
+    ActivityLaunchAnimCoordinatorModule::class,
+    SensitiveContentCoordinatorModule::class,
+])
 private abstract class InternalCoordinatorsModule {
     @Binds
     @Internal
@@ -62,4 +66,4 @@
 @Scope
 @MustBeDocumented
 @Retention(AnnotationRetention.RUNTIME)
-annotation class CoordinatorScope
\ No newline at end of file
+annotation class CoordinatorScope
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
index cd2affe..7c4e449 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
@@ -73,7 +73,7 @@
         GroupExpansionManager,
         Dumpable {
 
-    private static final String TAG = "NotifGroupManager";
+    private static final String TAG = "LegacyNotifGroupManager";
     private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
     private static final boolean SPEW = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
index c35b77c..6db544c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
@@ -57,6 +57,7 @@
 
         var currentSection: NotifSection? = null
         val prevSections = mutableSetOf<NotifSection?>()
+        var lastSection: NotifSection? = null
         val showHeaders = sectionHeaderVisibilityProvider.sectionHeadersVisible
         val sectionOrder = mutableListOf<NotifSection?>()
         val sectionHeaders = mutableMapOf<NotifSection?, NodeController?>()
@@ -65,6 +66,14 @@
         for (entry in notifList) {
             val section = entry.section!!
 
+            lastSection?.let {
+                if (it.bucket > section.bucket) {
+                    throw IllegalStateException("buildNodeSpec with non contiguous section " +
+                            "buckets ${it.sectioner.name} - ${it.bucket} & " +
+                            "${it.sectioner.name} - ${it.bucket}")
+                }
+            }
+            lastSection = section
             if (prevSections.contains(section)) {
                 throw java.lang.RuntimeException("Section ${section.label} has been duplicated")
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifPanelEventSource.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifPanelEventSource.kt
deleted file mode 100644
index 470737e..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifPanelEventSource.kt
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.statusbar.notification.collection.render
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.phone.NotificationPanelViewController
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
-import com.android.systemui.util.ListenerSet
-import dagger.Binds
-import dagger.Module
-import dagger.Provides
-import dagger.multibindings.IntoSet
-
-/** Provides certain notification panel events.  */
-interface NotifPanelEventSource {
-
-    /** Registers callbacks to be invoked when notification panel events occur.  */
-    fun registerCallbacks(callbacks: Callbacks)
-
-    /** Unregisters callbacks previously registered via [.registerCallbacks]  */
-    fun unregisterCallbacks(callbacks: Callbacks)
-
-    /** Callbacks for certain notification panel events. */
-    interface Callbacks {
-
-        /** Invoked when the notification panel starts or stops collapsing. */
-        fun onPanelCollapsingChanged(isCollapsing: Boolean)
-
-        /**
-         * Invoked when the notification panel starts or stops launching an [android.app.Activity].
-         */
-        fun onLaunchingActivityChanged(isLaunchingActivity: Boolean)
-    }
-}
-
-@Module
-abstract class NotifPanelEventSourceModule {
-
-    @Binds
-    @SysUISingleton
-    abstract fun bindEventSource(manager: NotifPanelEventSourceManager): NotifPanelEventSource
-
-    @Module
-    companion object {
-        @JvmStatic
-        @Provides
-        fun provideManager(): NotifPanelEventSourceManager = NotifPanelEventSourceManagerImpl()
-    }
-}
-
-@Module
-object StatusBarNotifPanelEventSourceModule {
-    @JvmStatic
-    @Provides
-    @IntoSet
-    @CentralSurfacesScope
-    fun bindStartable(
-        manager: NotifPanelEventSourceManager,
-        notifPanelController: NotificationPanelViewController
-    ): CentralSurfacesComponent.Startable =
-            EventSourceStatusBarStartableImpl(manager, notifPanelController)
-}
-
-/**
- * Management layer that bridges [SysUiSingleton] and [CentralSurfacesScope]. Necessary because code
- * that wants to listen to [NotifPanelEventSource] lives in [SysUiSingleton], but the events
- * themselves come from [NotificationPanelViewController] in [CentralSurfacesScope].
- */
-interface NotifPanelEventSourceManager : NotifPanelEventSource {
-    var eventSource: NotifPanelEventSource?
-}
-
-private class NotifPanelEventSourceManagerImpl
-    : NotifPanelEventSourceManager, NotifPanelEventSource.Callbacks {
-
-    private val callbackSet = ListenerSet<NotifPanelEventSource.Callbacks>()
-
-    override var eventSource: NotifPanelEventSource? = null
-        set(value) {
-            field?.unregisterCallbacks(this)
-            value?.registerCallbacks(this)
-            field = value
-        }
-
-    override fun registerCallbacks(callbacks: NotifPanelEventSource.Callbacks) {
-        callbackSet.addIfAbsent(callbacks)
-    }
-
-    override fun unregisterCallbacks(callbacks: NotifPanelEventSource.Callbacks) {
-        callbackSet.remove(callbacks)
-    }
-
-    override fun onPanelCollapsingChanged(isCollapsing: Boolean) {
-        callbackSet.forEach { it.onPanelCollapsingChanged(isCollapsing) }
-    }
-
-    override fun onLaunchingActivityChanged(isLaunchingActivity: Boolean) {
-        callbackSet.forEach { it.onLaunchingActivityChanged(isLaunchingActivity) }
-    }
-}
-
-private class EventSourceStatusBarStartableImpl(
-    private val manager: NotifPanelEventSourceManager,
-    private val notifPanelController: NotificationPanelViewController
-) : CentralSurfacesComponent.Startable {
-
-    override fun start() {
-        manager.eventSource = notifPanelController
-    }
-
-    override fun stop() {
-        manager.eventSource = null
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 51bbf1c..efe88e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -68,7 +68,6 @@
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl;
 import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
-import com.android.systemui.statusbar.notification.collection.render.NotifPanelEventSourceModule;
 import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
@@ -84,9 +83,11 @@
 import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
 import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager;
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.NotifActivityLaunchEventsModule;
+import com.android.systemui.statusbar.phone.NotifPanelEventsModule;
+import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.util.leak.LeakDetector;
 import com.android.systemui.wmshell.BubblesManager;
@@ -106,8 +107,9 @@
  */
 @Module(includes = {
         CoordinatorsModule.class,
+        NotifActivityLaunchEventsModule.class,
         NotifPipelineChoreographerModule.class,
-        NotifPanelEventSourceModule.class,
+        NotifPanelEventsModule.class,
         NotificationSectionHeadersModule.class,
 })
 public interface NotificationsModule {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt
new file mode 100644
index 0000000..70c9a16
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt
@@ -0,0 +1,186 @@
+package com.android.systemui.statusbar.notification.interruption
+
+import android.app.Notification
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.database.ContentObserver
+import android.net.Uri
+import android.os.Handler
+import android.os.UserHandle
+import android.provider.Settings
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.CoreStartable
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.util.ListenerSet
+import java.util.function.Consumer
+import javax.inject.Inject
+
+/**
+ * Determines if notifications should be visible based on the state of the keyguard
+ */
+class KeyguardNotificationVisibilityProvider @Inject constructor(
+    context: Context,
+    @Main private val handler: Handler,
+    private val keyguardStateController: KeyguardStateController,
+    private val lockscreenUserManager: NotificationLockscreenUserManager,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    private val highPriorityProvider: HighPriorityProvider,
+    private val statusBarStateController: StatusBarStateController,
+    private val broadcastDispatcher: BroadcastDispatcher
+) : CoreStartable(context) {
+    private val onStateChangedListeners = ListenerSet<Consumer<String>>()
+    private var hideSilentNotificationsOnLockscreen: Boolean = false
+
+    override fun start() {
+        readShowSilentNotificationSetting()
+        keyguardStateController.addCallback(object : KeyguardStateController.Callback {
+            override fun onUnlockedChanged() {
+                notifyStateChanged("onUnlockedChanged")
+            }
+
+            override fun onKeyguardShowingChanged() {
+                notifyStateChanged("onKeyguardShowingChanged")
+            }
+        })
+        keyguardUpdateMonitor.registerCallback(object : KeyguardUpdateMonitorCallback() {
+            override fun onStrongAuthStateChanged(userId: Int) {
+                notifyStateChanged("onStrongAuthStateChanged")
+            }
+        })
+
+        // register lockscreen settings changed callbacks:
+        val settingsObserver: ContentObserver = object : ContentObserver(handler) {
+            override fun onChange(selfChange: Boolean, uri: Uri) {
+                if (keyguardStateController.isShowing) {
+                    notifyStateChanged("Settings $uri changed")
+                }
+            }
+        }
+
+        mContext.contentResolver.registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS),
+                false,
+                settingsObserver,
+                UserHandle.USER_ALL)
+
+        mContext.contentResolver.registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
+                true,
+                settingsObserver,
+                UserHandle.USER_ALL)
+
+        mContext.contentResolver.registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.ZEN_MODE),
+                false,
+                settingsObserver)
+
+        mContext.contentResolver.registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS),
+                false,
+                settingsObserver,
+                UserHandle.USER_ALL)
+
+        // register (maybe) public mode changed callbacks:
+        statusBarStateController.addCallback(object : StatusBarStateController.StateListener {
+            override fun onStateChanged(state: Int) {
+                notifyStateChanged("onStatusBarStateChanged")
+            }
+        })
+        broadcastDispatcher.registerReceiver(object : BroadcastReceiver() {
+            override fun onReceive(context: Context, intent: Intent) {
+                if (keyguardStateController.isShowing()) {
+                    // maybe public mode changed
+                    notifyStateChanged(intent.action)
+                }
+            }
+        }, IntentFilter(Intent.ACTION_USER_SWITCHED))
+    }
+
+    fun addOnStateChangedListener(listener: Consumer<String>) {
+        onStateChangedListeners.addIfAbsent(listener)
+    }
+
+    fun removeOnStateChangedListener(listener: Consumer<String>) {
+        onStateChangedListeners.remove(listener)
+    }
+
+    private fun notifyStateChanged(reason: String) {
+        onStateChangedListeners.forEach({ it.accept(reason) })
+    }
+
+    /**
+     * Determines if the given notification should be hidden based on the current keyguard state.
+     * If Listener#onKeyguardStateChanged is invoked, the results of this method may no longer
+     * be valid, and so should be re-queried
+     */
+    fun hideNotification(entry: NotificationEntry): Boolean {
+        val sbn = entry.sbn
+        // FILTER OUT the notification when the keyguard is showing and...
+        if (keyguardStateController.isShowing()) {
+            // ... user settings or the device policy manager doesn't allow lockscreen
+            // notifications;
+            if (!lockscreenUserManager.shouldShowLockscreenNotifications()) {
+                return true
+            }
+            val currUserId: Int = lockscreenUserManager.getCurrentUserId()
+            val notifUserId =
+                    if (sbn.user.identifier == UserHandle.USER_ALL) currUserId
+                    else sbn.user.identifier
+
+            // ... user is in lockdown
+            if (keyguardUpdateMonitor.isUserInLockdown(currUserId) ||
+                    keyguardUpdateMonitor.isUserInLockdown(notifUserId)) {
+                return true
+            }
+
+            // ... device is in public mode and the user's settings doesn't allow
+            // notifications to show in public mode
+            if (lockscreenUserManager.isLockscreenPublicMode(currUserId) ||
+                    lockscreenUserManager.isLockscreenPublicMode(notifUserId)) {
+                if (entry.ranking.lockscreenVisibilityOverride == Notification.VISIBILITY_SECRET) {
+                    return true
+                }
+                if (!lockscreenUserManager.userAllowsNotificationsInPublic(currUserId) ||
+                        !lockscreenUserManager.userAllowsNotificationsInPublic(
+                                notifUserId)) {
+                    return true
+                }
+            }
+
+            // ... neither this notification nor its group have high enough priority
+            // to be shown on the lockscreen
+            if (entry.parent != null) {
+                val parent = entry.parent
+                if (priorityExceedsLockscreenShowingThreshold(parent)) {
+                    return false
+                }
+            }
+            return !priorityExceedsLockscreenShowingThreshold(entry)
+        }
+        return false
+    }
+
+    private fun priorityExceedsLockscreenShowingThreshold(entry: ListEntry?): Boolean =
+        when {
+            entry == null -> false
+            hideSilentNotificationsOnLockscreen -> highPriorityProvider.isHighPriority(entry)
+            else -> entry.representativeEntry?.ranking?.isAmbient == false
+        }
+
+    private fun readShowSilentNotificationSetting() {
+        hideSilentNotificationsOnLockscreen = Settings.Secure.getInt(
+                mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS,
+                1) == 0
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
index c991376..6c99e3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
@@ -211,6 +211,14 @@
             "Pulsing: $str1"
         })
     }
+
+    fun keyguardHideNotification(key: String) {
+        hunBuffer.log(TAG, DEBUG, {
+            str1 = key
+        }, {
+            "Keyguard Hide Notification: $str1"
+        })
+    }
 }
 
 private const val TAG = "InterruptionStateProvider"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
index 7ed2699..c1771cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
@@ -36,6 +36,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationFilter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -66,6 +67,8 @@
     private final ContentObserver mHeadsUpObserver;
     private final HeadsUpManager mHeadsUpManager;
     private final NotificationInterruptLogger mLogger;
+    private final NotifPipelineFlags mFlags;
+    private final KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;
 
     @VisibleForTesting
     protected boolean mUseHeadsUp = false;
@@ -81,7 +84,9 @@
             StatusBarStateController statusBarStateController,
             HeadsUpManager headsUpManager,
             NotificationInterruptLogger logger,
-            @Main Handler mainHandler) {
+            @Main Handler mainHandler,
+            NotifPipelineFlags flags,
+            KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider) {
         mContentResolver = contentResolver;
         mPowerManager = powerManager;
         mDreamManager = dreamManager;
@@ -91,6 +96,8 @@
         mStatusBarStateController = statusBarStateController;
         mHeadsUpManager = headsUpManager;
         mLogger = logger;
+        mFlags = flags;
+        mKeyguardNotificationVisibilityProvider = keyguardNotificationVisibilityProvider;
         mHeadsUpObserver = new ContentObserver(mainHandler) {
             @Override
             public void onChange(boolean selfChange) {
@@ -282,7 +289,7 @@
     private boolean canAlertCommon(NotificationEntry entry) {
         StatusBarNotification sbn = entry.getSbn();
 
-        if (mNotificationFilter.shouldFilterOut(entry)) {
+        if (!mFlags.isNewPipelineEnabled() && mNotificationFilter.shouldFilterOut(entry)) {
             mLogger.logNoAlertingFilteredOut(sbn);
             return false;
         }
@@ -305,6 +312,11 @@
             return false;
         }
 
+        if (mKeyguardNotificationVisibilityProvider.hideNotification(entry)) {
+            mLogger.keyguardHideNotification(entry.getKey());
+            return false;
+        }
+
         return true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 9cb5dc5..adb4ce6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -413,7 +413,10 @@
             if (mExpandedRemoteInput != null) {
                 mExpandedRemoteInput.onNotificationUpdateOrReset();
                 if (mExpandedRemoteInput.isActive()) {
-                    mPreviousExpandedRemoteInputIntent = mExpandedRemoteInput.getPendingIntent();
+                    if (mExpandedRemoteInputController != null) {
+                        mPreviousExpandedRemoteInputIntent =
+                                mExpandedRemoteInputController.getPendingIntent();
+                    }
                     mCachedExpandedRemoteInput = mExpandedRemoteInput;
                     mCachedExpandedRemoteInputViewController = mExpandedRemoteInputController;
                     mExpandedRemoteInput.dispatchStartTemporaryDetach();
@@ -460,7 +463,10 @@
             if (mHeadsUpRemoteInput != null) {
                 mHeadsUpRemoteInput.onNotificationUpdateOrReset();
                 if (mHeadsUpRemoteInput.isActive()) {
-                    mPreviousHeadsUpRemoteInputIntent = mHeadsUpRemoteInput.getPendingIntent();
+                    if (mHeadsUpRemoteInputController != null) {
+                        mPreviousHeadsUpRemoteInputIntent =
+                                mHeadsUpRemoteInputController.getPendingIntent();
+                    }
                     mCachedHeadsUpRemoteInput = mHeadsUpRemoteInput;
                     mCachedHeadsUpRemoteInputViewController = mHeadsUpRemoteInputController;
                     mHeadsUpRemoteInput.dispatchStartTemporaryDetach();
@@ -961,14 +967,16 @@
 
     private void transferRemoteInputFocus(int visibleType) {
         if (visibleType == VISIBLE_TYPE_HEADSUP
-                && mHeadsUpRemoteInput != null
-                && (mExpandedRemoteInput != null && mExpandedRemoteInput.isActive())) {
-            mHeadsUpRemoteInput.stealFocusFrom(mExpandedRemoteInput);
+                && mHeadsUpRemoteInputController != null
+                && mExpandedRemoteInputController != null
+                && mExpandedRemoteInputController.isActive()) {
+            mHeadsUpRemoteInputController.stealFocusFrom(mExpandedRemoteInputController);
         }
         if (visibleType == VISIBLE_TYPE_EXPANDED
-                && mExpandedRemoteInput != null
-                && (mHeadsUpRemoteInput != null && mHeadsUpRemoteInput.isActive())) {
-            mExpandedRemoteInput.stealFocusFrom(mHeadsUpRemoteInput);
+                && mExpandedRemoteInputController != null
+                && mHeadsUpRemoteInputController != null
+                && mHeadsUpRemoteInputController.isActive()) {
+            mExpandedRemoteInputController.stealFocusFrom(mHeadsUpRemoteInputController);
         }
     }
 
@@ -1313,7 +1321,6 @@
                     // If we find a matching action in the new notification, focus, otherwise close.
                     Notification.Action[] actions = entry.getSbn().getNotification().actions;
                     if (existingPendingIntent != null) {
-                        result.mView.setPendingIntent(existingPendingIntent);
                         result.mController.setPendingIntent(existingPendingIntent);
                     }
                     if (result.mController.updatePendingIntentFromActions(actions)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index f40a3c7..3b22f2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -102,6 +102,16 @@
     /** Whether we are swiping up. */
     private boolean mIsSwipingUp;
 
+    /** Whether we are flinging the shade open or closed. */
+    private boolean mIsFlinging;
+
+    /**
+     * Whether we need to do a fling down after swiping up on lockscreen.
+     * True right after we swipe up on lockscreen and have not finished the fling down that follows.
+     * False when we stop flinging or leave lockscreen.
+     */
+    private boolean mNeedFlingAfterLockscreenSwipeUp = false;
+
     /**
      * @return Height of the notifications panel without top padding when expansion completes.
      */
@@ -142,6 +152,10 @@
      * @param isSwipingUp Whether we are swiping up.
      */
     public void setSwipingUp(boolean isSwipingUp) {
+        if (!isSwipingUp && mIsSwipingUp) {
+            // Just stopped swiping up.
+            mNeedFlingAfterLockscreenSwipeUp = true;
+        }
         mIsSwipingUp = isSwipingUp;
     }
 
@@ -153,6 +167,17 @@
     }
 
     /**
+     * @param isFlinging Whether we are flinging the shade open or closed.
+     */
+    public void setIsFlinging(boolean isFlinging) {
+        if (isOnKeyguard() && !isFlinging && mIsFlinging) {
+            // Just stopped flinging.
+            mNeedFlingAfterLockscreenSwipeUp = false;
+        }
+        mIsFlinging = isFlinging;
+    }
+
+    /**
      * @return Fraction of shade expansion.
      */
     public float getExpansionFraction() {
@@ -459,6 +484,9 @@
     }
 
     public void setStatusBarState(int statusBarState) {
+        if (mStatusBarState != StatusBarState.KEYGUARD) {
+            mNeedFlingAfterLockscreenSwipeUp = false;
+        }
         mStatusBarState = statusBarState;
     }
 
@@ -522,6 +550,13 @@
     }
 
     /**
+     * @return Whether we need to do a fling down after swiping up on lockscreen.
+     */
+    public boolean isFlingingAfterSwipeUpOnLockscreen() {
+        return mIsFlinging && mNeedFlingAfterLockscreenSwipeUp;
+    }
+
+    /**
      * @return whether a view is dozing and not pulsing right now
      */
     public boolean isDozingAndNotPulsing(ExpandableView view) {
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 efe559a..27cc326 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
@@ -202,9 +202,6 @@
     private float mQsExpansionFraction;
     private final int mSplitShadeMinContentHeight;
 
-    /** Whether we are flinging the shade open or closed. */
-    private boolean mIsFlinging;
-
     /**
      * The algorithm which calculates the properties for our children
      */
@@ -407,7 +404,12 @@
      */
     private float mBackgroundXFactor = 1f;
 
-    private boolean mQsExpanded;
+    /**
+     * Indicates QS are full screen and pushing notifications out of the screen.
+     * It's different from QS just being expanded as in split shade QS can be expanded and
+     * still don't take full screen nor influence notifications.
+     */
+    private boolean mQsFullScreen;
     private boolean mForwardScrollable;
     private boolean mBackwardScrollable;
     private NotificationShelf mShelf;
@@ -756,29 +758,30 @@
             mDebugTextUsedYPositions.clear();
         }
         int y = mTopPadding;
-        drawDebugInfo(canvas, y, Color.RED, /* label= */ "mTopPadding");
+        drawDebugInfo(canvas, y, Color.RED, /* label= */ "mTopPadding = "+y);
 
         y = getLayoutHeight();
-        drawDebugInfo(canvas, y, Color.YELLOW, /* label= */ "getLayoutHeight()");
+        drawDebugInfo(canvas, y, Color.YELLOW, /* label= */ "getLayoutHeight() = "+y);
 
         y = (int) mMaxLayoutHeight;
-        drawDebugInfo(canvas, y, Color.MAGENTA, /* label= */ "mMaxLayoutHeight");
+        drawDebugInfo(canvas, y, Color.MAGENTA, /* label= */ "mMaxLayoutHeight = "+y);
 
         if (mKeyguardBottomPadding >= 0) {
             y = getHeight() - (int) mKeyguardBottomPadding;
             drawDebugInfo(canvas, y, Color.GRAY,
-                    /* label= */ "getHeight() - mKeyguardBottomPadding");
+                    /* label= */ "getHeight() - mKeyguardBottomPadding = "+y);
         }
 
         y = getHeight() - getEmptyBottomMargin();
-        drawDebugInfo(canvas, y, Color.GREEN, /* label= */ "getHeight() - getEmptyBottomMargin()");
+        drawDebugInfo(canvas, y, Color.GREEN,
+                /* label= */ "getHeight() - getEmptyBottomMargin() = "+y);
 
         y = (int) (mAmbientState.getStackY());
-        drawDebugInfo(canvas, y, Color.CYAN, /* label= */ "mAmbientState.getStackY()");
+        drawDebugInfo(canvas, y, Color.CYAN, /* label= */ "mAmbientState.getStackY() = "+y);
 
         y = (int) (mAmbientState.getStackY() + mAmbientState.getStackHeight());
         drawDebugInfo(canvas, y, Color.BLUE,
-                /* label= */ "mAmbientState.getStackY() + mAmbientState.getStackHeight()");
+                /* label= */ "mAmbientState.getStackY() + mAmbientState.getStackHeight() = "+y);
     }
 
     private void drawDebugInfo(Canvas canvas, int y, int color, String label) {
@@ -1133,7 +1136,7 @@
 
     @ShadeViewRefactor(RefactorComponent.LAYOUT_ALGORITHM)
     private void updateAlgorithmLayoutMinHeight() {
-        mAmbientState.setLayoutMinHeight(mQsExpanded || isHeadsUpTransition()
+        mAmbientState.setLayoutMinHeight(mQsFullScreen || isHeadsUpTransition()
                 ? getLayoutMinHeight() : 0);
     }
 
@@ -1263,13 +1266,16 @@
     }
 
     /**
-     * @return Whether we should skip stack height update for lockscreen swipe-up or unlock hint.
+     * @return Whether we should skip stack height updates.
+     * True when
+     *      1) Unlock hint is running
+     *      2) Swiping up on lockscreen or flinging down after swipe up
      */
     private boolean shouldSkipHeightUpdate() {
-        // After the user swipes up on lockscreen and lets go,
-        // {@link PanelViewController) flings the shade back down.
-        return mAmbientState.isOnKeyguard() && (
-                mAmbientState.isUnlockHintRunning() || mAmbientState.isSwipingUp() || mIsFlinging);
+        return mAmbientState.isOnKeyguard()
+                && (mAmbientState.isUnlockHintRunning()
+                        || mAmbientState.isSwipingUp()
+                        || mAmbientState.isFlingingAfterSwipeUpOnLockscreen());
     }
 
     /**
@@ -1327,12 +1333,7 @@
      */
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
     public void setExpandedHeight(float height) {
-        final float shadeBottom = getHeight() - getEmptyBottomMargin();
         final boolean skipHeightUpdate = shouldSkipHeightUpdate();
-        if (!skipHeightUpdate) {
-            final float expansionFraction = MathUtils.saturate(height / shadeBottom);
-            mAmbientState.setExpansionFraction(expansionFraction);
-        }
         updateStackPosition();
 
         if (!skipHeightUpdate) {
@@ -1361,7 +1362,7 @@
             translationY = 0;
             if (mShouldShowShelfOnly) {
                 stackHeight = mTopPadding + mShelf.getIntrinsicHeight();
-            } else if (mQsExpanded) {
+            } else if (mQsFullScreen) {
                 int stackStartPosition = mContentHeight - mTopPadding + mIntrinsicPadding;
                 int stackEndPosition = mMaxTopPadding + mShelf.getIntrinsicHeight();
                 if (stackStartPosition <= stackEndPosition) {
@@ -2318,7 +2319,7 @@
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     private void updateScrollability() {
-        boolean scrollable = !mQsExpanded && getScrollRange() > 0;
+        boolean scrollable = !mQsFullScreen && getScrollRange() > 0;
         if (scrollable != mScrollable) {
             mScrollable = scrollable;
             setFocusable(scrollable);
@@ -4839,14 +4840,14 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void setQsExpanded(boolean qsExpanded) {
-        mQsExpanded = qsExpanded;
+    public void setQsFullScreen(boolean qsFullScreen) {
+        mQsFullScreen = qsFullScreen;
         updateAlgorithmLayoutMinHeight();
         updateScrollability();
     }
 
-    boolean isQsExpanded() {
-        return mQsExpanded;
+    boolean isQsFullScreen() {
+        return mQsFullScreen;
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -5009,13 +5010,6 @@
         mAmbientState.setUnlockHintRunning(running);
     }
 
-    /**
-     * @param isFlinging Whether we are flinging the shade open or closed.
-     */
-    public void setIsFlinging(boolean isFlinging) {
-        mIsFlinging = isFlinging;
-    }
-
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void setHeadsUpGoingAwayAnimationsAllowed(boolean headsUpGoingAwayAnimationsAllowed) {
         mHeadsUpGoingAwayAnimationsAllowed = headsUpGoingAwayAnimationsAllowed;
@@ -5814,10 +5808,6 @@
         mSwipeHelper.resetExposedMenuView(animate, force);
     }
 
-    boolean isUsingSplitNotificationShade() {
-        return mShouldUseSplitNotificationShade;
-    }
-
     static boolean matchesSelection(
             ExpandableNotificationRow row,
             @SelectedRows int selection) {
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 df6b8f5..6bbecc8 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
@@ -111,13 +111,13 @@
 import com.android.systemui.statusbar.notification.row.NotificationGuts;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.row.NotificationSnooze;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -1086,8 +1086,8 @@
         }
     }
 
-    public void setQsExpanded(boolean expanded) {
-        mView.setQsExpanded(expanded);
+    public void setQsFullScreen(boolean fullScreen) {
+        mView.setQsFullScreen(fullScreen);
         updateShowEmptyShadeView();
     }
 
@@ -1181,13 +1181,6 @@
         mView.setUnlockHintRunning(running);
     }
 
-    /**
-     * @param isFlinging Whether we are flinging the shade open or close.
-     */
-    public void setIsFlinging(boolean isFlinging) {
-        mView.setIsFlinging(isFlinging);
-    }
-
     public boolean isFooterViewNotGone() {
         return mView.isFooterViewNotGone();
     }
@@ -1211,7 +1204,7 @@
     public void updateShowEmptyShadeView() {
         Trace.beginSection("NSSLC.updateShowEmptyShadeView");
         mShowEmptyShadeView = mBarState != KEYGUARD
-                && (!mView.isQsExpanded() || mView.isUsingSplitNotificationShade())
+                && !mView.isQsFullScreen()
                 && getVisibleNotificationCount() == 0;
 
         mView.updateEmptyShadeView(
@@ -1240,10 +1233,6 @@
         mView.forceNoOverlappingRendering(force);
     }
 
-    public void setTranslationX(float translation) {
-        mView.setTranslationX(translation);
-    }
-
     public void setExpandingVelocity(float velocity) {
         mView.setExpandingVelocity(velocity);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 952cd9a..e1f8c35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -202,12 +202,10 @@
             float newHeight = state.height;
             float newNotificationEnd = newYTranslation + newHeight;
             boolean isHeadsUp = (child instanceof ExpandableNotificationRow) && child.isPinned();
-            final boolean shadeClosedWithHUN =
-                    ambientState.isShadeOpening() && !ambientState.isShadeExpanded();
             if (mClipNotificationScrollToTop
                     && (!state.inShelf || (isHeadsUp && !firstHeadsUp))
                     && newYTranslation < clipStart
-                    && shadeClosedWithHUN) {
+                    && !ambientState.isShadeExpanded()) {
                 // The previous view is overlapping on top, clip!
                 float overlapAmount = clipStart - newYTranslation;
                 state.clipTopAmount = (int) overlapAmount;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index fe637c1..4bf944a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -20,6 +20,8 @@
 
 import android.annotation.IntDef;
 import android.content.res.Resources;
+import android.hardware.biometrics.BiometricFaceConstants;
+import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricSourceType;
 import android.hardware.fingerprint.FingerprintManager;
 import android.metrics.LogMaker;
@@ -344,7 +346,15 @@
     }
 
     @Override
-    public void onBiometricAcquired(BiometricSourceType biometricSourceType) {
+    public void onBiometricAcquired(BiometricSourceType biometricSourceType,
+            int acquireInfo) {
+        if (BiometricSourceType.FINGERPRINT == biometricSourceType
+                && acquireInfo != BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
+            return;
+        } else if (BiometricSourceType.FACE == biometricSourceType
+                && acquireInfo != BiometricFaceConstants.FACE_ACQUIRED_GOOD) {
+            return;
+        }
         Trace.beginSection("BiometricUnlockController#onBiometricAcquired");
         releaseBiometricWakeLock();
         if (isWakeAndUnlock()) {
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 95a4659..ec2d608 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -2881,8 +2881,7 @@
     }
 
     boolean updateIsKeyguard(boolean forceStateChange) {
-        boolean wakeAndUnlocking = mBiometricUnlockController.getMode()
-                == BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
+        boolean wakeAndUnlocking = mBiometricUnlockController.isWakeAndUnlock();
 
         // For dozing, keyguard needs to be shown whenever the device is non-interactive. Otherwise
         // there's no surface we can show to the user. Note that the device goes fully interactive
@@ -2890,8 +2889,9 @@
         // turned off fully.
         boolean keyguardForDozing = mDozeServiceHost.getDozingRequested()
                 && (!mDeviceInteractive || (isGoingToSleep()
-                    && (isScreenFullyOff() || mKeyguardStateController.isShowing())));
-        boolean isWakingAndOccluded = isOccluded() && isWaking();
+                    && (isScreenFullyOff()
+                        || (mKeyguardStateController.isShowing() && !isOccluded()))));
+        boolean isWakingAndOccluded = isOccluded() && isWakingOrAwake();
         boolean shouldBeKeyguard = (mStatusBarStateController.isKeyguardRequested()
                 || keyguardForDozing) && !wakeAndUnlocking && !isWakingAndOccluded;
         if (keyguardForDozing) {
@@ -3075,7 +3075,6 @@
         mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
         releaseGestureWakeLock();
         mNotificationPanelViewController.onAffordanceLaunchEnded();
-        mNotificationPanelViewController.cancelAnimation();
         mNotificationPanelViewController.resetAlpha();
         mNotificationPanelViewController.resetTranslation();
         mNotificationPanelViewController.resetViewGroupFade();
@@ -3701,8 +3700,9 @@
                 == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
     }
 
-    boolean isWaking() {
-        return mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_WAKING;
+    boolean isWakingOrAwake() {
+        return mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_WAKING
+                || mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_AWAKE;
     }
 
     public void notifyBiometricAuthModeChanged() {
@@ -3769,7 +3769,7 @@
             });
         } else if (mDozing && !unlocking) {
             mScrimController.transitionTo(ScrimState.AOD);
-        } else if (mKeyguardStateController.isShowing() && !unlocking) {
+        } else if (mKeyguardStateController.isShowing() && !isOccluded() && !unlocking) {
             mScrimController.transitionTo(ScrimState.KEYGUARD);
         } else {
             mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 541aeab..7f1611f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -32,7 +32,6 @@
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
 import android.app.admin.DevicePolicyManager;
-import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -556,6 +555,7 @@
         mControlsButton.setImageResource(mControlsComponent.getTileImageId());
         mControlsButton.setContentDescription(getContext()
                 .getString(mControlsComponent.getTileTitleId()));
+        updateAffordanceColors();
 
         boolean hasFavorites = mControlsComponent.getControlsController()
                 .map(c -> c.getFavorites().size() > 0)
@@ -1109,8 +1109,13 @@
         Intent intent = mQRCodeScannerController.getIntent();
         if (intent != null) {
             try {
-                mContext.startActivity(intent);
-            } catch (ActivityNotFoundException e) {
+                ActivityTaskManager.getService().startActivityAsUser(
+                                null, getContext().getBasePackageName(),
+                                getContext().getAttributionTag(), intent,
+                                intent.resolveTypeIfNeeded(getContext().getContentResolver()),
+                                null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null,
+                                UserHandle.CURRENT.getIdentifier());
+            } catch (RemoteException e) {
                 // This is unexpected. Nonetheless, just log the error and prevent the UI from
                 // crashing
                 Log.e(TAG, "Unexpected intent: " + intent
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt
index 868efa0..02b2354 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt
@@ -44,7 +44,7 @@
 
     fun logDragDownAborted() {
         buffer.log(TAG, LogLevel.INFO, {}, {
-            "The drag down was reset"
+            "The drag down was aborted and reset to 0f."
         })
     }
 
@@ -82,6 +82,12 @@
             LockscreenGestureLogger.LockscreenUiEvent.LOCKSCREEN_PULL_SHADE_OPEN)
     }
 
+    fun logDragDownAmountReset() {
+        buffer.log(TAG, LogLevel.DEBUG, {}, {
+            "The drag down amount has been reset to 0f."
+        })
+    }
+
     fun logDefaultGoToFullShadeAnimation(delay: Long) {
         buffer.log(TAG, LogLevel.DEBUG, {
             long1 = delay
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEvents.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEvents.kt
new file mode 100644
index 0000000..f46d073
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEvents.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+
+/** Provides events about [android.app.Activity] launches from Notifications. */
+interface NotifActivityLaunchEvents {
+
+    /** Registers a [Listener] to be invoked when notification activity launch events occur. */
+    fun registerListener(listener: Listener)
+
+    /** Unregisters a [Listener] previously registered via [registerListener] */
+    fun unregisterListener(listener: Listener)
+
+    /** Listener for events about [android.app.Activity] launches from Notifications. */
+    interface Listener {
+
+        /** Invoked when an activity has started launching from a notification. */
+        fun onStartLaunchNotifActivity(entry: NotificationEntry)
+
+        /** Invoked when an activity has finished launching. */
+        fun onFinishLaunchNotifActivity(entry: NotificationEntry)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEventsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEventsModule.java
new file mode 100644
index 0000000..84ff538
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifActivityLaunchEventsModule.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import com.android.systemui.dagger.SysUISingleton;
+
+import dagger.Binds;
+import dagger.Module;
+
+/** Provides a {@link NotifActivityLaunchEvents} in {@link SysUISingleton} scope. */
+@Module
+public abstract class NotifActivityLaunchEventsModule {
+    @Binds
+    abstract NotifActivityLaunchEvents bindLaunchEvents(
+            StatusBarNotificationActivityStarter.LaunchEventsEmitter impl);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt
new file mode 100644
index 0000000..a385e22
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+/** Provides certain notification panel events.  */
+interface NotifPanelEvents {
+
+    /** Registers callbacks to be invoked when notification panel events occur.  */
+    fun registerListener(listener: Listener)
+
+    /** Unregisters callbacks previously registered via [registerListener]  */
+    fun unregisterListener(listener: Listener)
+
+    /** Callbacks for certain notification panel events. */
+    interface Listener {
+
+        /** Invoked when the notification panel starts or stops collapsing. */
+        fun onPanelCollapsingChanged(isCollapsing: Boolean)
+
+        /**
+         * Invoked when the notification panel starts or stops launching an [android.app.Activity].
+         */
+        fun onLaunchingActivityChanged(isLaunchingActivity: Boolean)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
new file mode 100644
index 0000000..2aaf6a5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import com.android.systemui.dagger.SysUISingleton;
+
+import dagger.Binds;
+import dagger.Module;
+
+/** Provides a {@link NotifPanelEvents} in {@link SysUISingleton} scope. */
+@Module
+public abstract class NotifPanelEventsModule {
+    @Binds
+    abstract NotifPanelEvents bindPanelEvents(
+            NotificationPanelViewController.PanelEventsEmitter impl);
+}
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 01860a8..1891ab0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -18,13 +18,9 @@
 
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.view.View.GONE;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
-import static androidx.constraintlayout.widget.ConstraintSet.BOTTOM;
 import static androidx.constraintlayout.widget.ConstraintSet.END;
 import static androidx.constraintlayout.widget.ConstraintSet.PARENT_ID;
-import static androidx.constraintlayout.widget.ConstraintSet.START;
-import static androidx.constraintlayout.widget.ConstraintSet.TOP;
 
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE;
 import static com.android.keyguard.KeyguardClockSwitch.LARGE;
@@ -120,14 +116,8 @@
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.classifier.Classifier;
 import com.android.systemui.classifier.FalsingCollector;
-import com.android.systemui.communal.CommunalHostView;
-import com.android.systemui.communal.CommunalHostViewController;
-import com.android.systemui.communal.CommunalHostViewPositionAlgorithm;
-import com.android.systemui.communal.CommunalSource;
-import com.android.systemui.communal.CommunalSourceMonitor;
-import com.android.systemui.communal.CommunalStateController;
-import com.android.systemui.communal.dagger.CommunalViewComponent;
 import com.android.systemui.controls.dagger.ControlsComponent;
+import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.doze.DozeLog;
@@ -176,7 +166,6 @@
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
-import com.android.systemui.statusbar.notification.collection.render.NotifPanelEventSource;
 import com.android.systemui.statusbar.notification.collection.render.ShadeViewManager;
 import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -209,7 +198,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
@@ -223,8 +211,7 @@
 import javax.inject.Provider;
 
 @CentralSurfacesComponent.CentralSurfacesScope
-public class NotificationPanelViewController extends PanelViewController
-        implements NotifPanelEventSource {
+public class NotificationPanelViewController extends PanelViewController {
 
     private static final boolean DEBUG = false;
 
@@ -309,13 +296,10 @@
     private final PulseExpansionHandler mPulseExpansionHandler;
     private final KeyguardBypassController mKeyguardBypassController;
     private final KeyguardUpdateMonitor mUpdateMonitor;
-    private final CommunalSourceMonitor mCommunalSourceMonitor;
-    private final CommunalStateController mCommunalStateController;
     private final ConversationNotificationManager mConversationNotificationManager;
     private final AuthController mAuthController;
     private final MediaHierarchyManager mMediaHierarchyManager;
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-    private final CommunalViewComponent.Factory mCommunalViewComponentFactory;
     private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
     private final KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
     private final KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
@@ -335,6 +319,7 @@
     private final TapAgainViewController mTapAgainViewController;
     private final SplitShadeHeaderController mSplitShadeHeaderController;
     private final RecordingController mRecordingController;
+    private final PanelEventsEmitter mPanelEventsEmitter;
     private boolean mShouldUseSplitNotificationShade;
     // The bottom padding reserved for elements of the keyguard measuring notifications
     private float mKeyguardNotificationBottomPadding;
@@ -350,8 +335,6 @@
     @VisibleForTesting QS mQs;
     private FrameLayout mQsFrame;
     private QsFrameTranslateController mQsFrameTranslateController;
-    @Nullable
-    private CommunalHostViewController mCommunalViewController;
     private KeyguardStatusViewController mKeyguardStatusViewController;
     private LockIconViewController mLockIconViewController;
     private NotificationsQuickSettingsContainer mNotificationContainerParent;
@@ -364,8 +347,6 @@
     private VelocityTracker mQsVelocityTracker;
     private boolean mQsTracking;
 
-    private CommunalHostView mCommunalView;
-
     /**
      * If set, the ongoing touch gesture might both trigger the expansion in {@link PanelView} and
      * the expansion for quick settings.
@@ -373,6 +354,12 @@
     private boolean mConflictingQsExpansionGesture;
 
     private boolean mPanelExpanded;
+
+    /**
+     * Indicates that QS is in expanded state which can happen by:
+     * - single pane shade: expanding shade and then expanding QS
+     * - split shade: just expanding shade (QS are expanded automatically)
+     */
     private boolean mQsExpanded;
     private boolean mQsExpandedWhenExpandingStarted;
     private boolean mQsFullyExpanded;
@@ -413,16 +400,14 @@
     private final KeyguardClockPositionAlgorithm.Result
             mClockPositionResult =
             new KeyguardClockPositionAlgorithm.Result();
-    private final CommunalHostViewPositionAlgorithm
-            mCommunalPositionAlgorithm =
-            new CommunalHostViewPositionAlgorithm();
-    private final CommunalHostViewPositionAlgorithm.Result
-            mCommunalPositionResult =
-            new CommunalHostViewPositionAlgorithm.Result();
     private boolean mIsExpanding;
 
     private boolean mBlockTouches;
-    // Used for two finger gesture as well as accessibility shortcut to QS.
+
+    /**
+     * Determines if QS should be already expanded when expanding shade.
+     * Used for split shade, two finger gesture as well as accessibility shortcut to QS.
+     */
     private boolean mQsExpandImmediate;
     private boolean mTwoFingerQsExpandPossible;
     private String mHeaderDebugInfo;
@@ -523,10 +508,6 @@
                     mPanelAlphaAnimator.getProperty(), Interpolators.ALPHA_IN);
     private final NotificationEntryManager mEntryManager;
 
-    private final CommunalSourceMonitor.Callback mCommunalSourceMonitorCallback;
-
-    private WeakReference<CommunalSource> mCommunalSource;
-
     private final CommandQueue mCommandQueue;
     private final NotificationLockscreenUserManager mLockscreenUserManager;
     private final UserManager mUserManager;
@@ -635,6 +616,11 @@
      */
     private float mKeyguardOnlyContentAlpha = 1.0f;
 
+    /**
+     * The translationY of the views which only show on the keyguard but in shade / shade locked.
+     */
+    private int mKeyguardOnlyTransitionTranslationY = 0;
+
     private float mUdfpsMaxYBurnInOffset;
 
     /**
@@ -664,8 +650,6 @@
     private Optional<NotificationPanelUnfoldAnimationController>
             mNotificationPanelUnfoldAnimationController;
 
-    private final ListenerSet<Callbacks> mNotifEventSourceCallbacks = new ListenerSet<>();
-
     private final NotificationListContainer mNotificationListContainer;
 
     private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
@@ -688,32 +672,6 @@
         }
     };
 
-    private final CommunalStateController.Callback mCommunalStateCallback =
-            new CommunalStateController.Callback() {
-                @Override
-                public void onCommunalViewShowingChanged() {
-                    mKeyguardStatusViewController.setKeyguardStatusViewVisibility(
-                            mBarState,
-                            mKeyguardStateController.isKeyguardFadingAway(),
-                            mStatusBarStateController.goingToFullShade(),
-                            mBarState);
-                    if (mKeyguardUserSwitcherController != null) {
-                        mKeyguardUserSwitcherController.setKeyguardUserSwitcherVisibility(
-                                mBarState,
-                                mKeyguardStateController.isKeyguardFadingAway(),
-                                mStatusBarStateController.goingToFullShade(),
-                                mBarState);
-                    }
-                    if (mKeyguardQsUserSwitchController != null) {
-                        mKeyguardQsUserSwitchController.setKeyguardQsUserSwitchVisibility(
-                                mBarState,
-                                mKeyguardStateController.isKeyguardFadingAway(),
-                                mStatusBarStateController.goingToFullShade(),
-                                mBarState);
-                    }
-                }
-    };
-
     private final FalsingTapListener mFalsingTapListener = new FalsingTapListener() {
         @Override
         public void onDoubleTapRequired() {
@@ -739,7 +697,6 @@
             FalsingCollector falsingCollector,
             NotificationLockscreenUserManager notificationLockscreenUserManager,
             NotificationEntryManager notificationEntryManager,
-            CommunalStateController communalStateController,
             KeyguardStateController keyguardStateController,
             StatusBarStateController statusBarStateController,
             StatusBarWindowStateController statusBarWindowStateController,
@@ -749,7 +706,7 @@
             LatencyTracker latencyTracker, PowerManager powerManager,
             AccessibilityManager accessibilityManager, @DisplayId int displayId,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
-            CommunalSourceMonitor communalSourceMonitor, MetricsLogger metricsLogger,
+            MetricsLogger metricsLogger,
             ActivityManager activityManager,
             ConfigurationController configurationController,
             Provider<FlingAnimationUtils.Builder> flingAnimationUtilsBuilder,
@@ -763,7 +720,6 @@
             KeyguardQsUserSwitchComponent.Factory keyguardQsUserSwitchComponentFactory,
             KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory,
             KeyguardStatusBarViewComponent.Factory keyguardStatusBarViewComponentFactory,
-            CommunalViewComponent.Factory communalViewComponentFactory,
             LockscreenShadeTransitionController lockscreenShadeTransitionController,
             NotificationGroupManagerLegacy groupManager,
             NotificationIconAreaController notificationIconAreaController,
@@ -796,7 +752,8 @@
             QsFrameTranslateController qsFrameTranslateController,
             SysUiState sysUiState,
             KeyguardUnlockAnimationController keyguardUnlockAnimationController,
-            NotificationListContainer notificationListContainer) {
+            NotificationListContainer notificationListContainer,
+            PanelEventsEmitter panelEventsEmitter) {
         super(view,
                 falsingManager,
                 dozeLog,
@@ -832,8 +789,6 @@
         mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
         mGroupManager = groupManager;
         mNotificationIconAreaController = notificationIconAreaController;
-        mCommunalStateController = communalStateController;
-        mCommunalViewComponentFactory = communalViewComponentFactory;
         mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
         mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory;
         mDepthController = notificationShadeDepthController;
@@ -868,6 +823,7 @@
         mSecureSettings = secureSettings;
         mInteractionJankMonitor = interactionJankMonitor;
         mSysUiState = sysUiState;
+        mPanelEventsEmitter = panelEventsEmitter;
         pulseExpansionHandler.setPulseExpandAbortListener(() -> {
             if (mQs != null) {
                 mQs.animateHeaderSlidingOut();
@@ -877,7 +833,6 @@
         mThemeResId = mView.getContext().getThemeResId();
         mKeyguardBypassController = bypassController;
         mUpdateMonitor = keyguardUpdateMonitor;
-        mCommunalSourceMonitor = communalSourceMonitor;
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
         lockscreenShadeTransitionController.setNotificationPanelController(this);
         DynamicPrivacyControlListener
@@ -924,9 +879,6 @@
         mNotificationPanelUnfoldAnimationController = unfoldComponent.map(
                 SysUIUnfoldComponent::getNotificationPanelUnfoldAnimationController);
 
-        mCommunalSourceMonitorCallback = (source) -> {
-            mUiExecutor.execute(() -> setCommunalSource(source));
-        };
         mQsFrameTranslateController = qsFrameTranslateController;
         updateUserSwitcherFlags();
         onFinishInflate();
@@ -962,7 +914,6 @@
     private void onFinishInflate() {
         loadDimens();
         mKeyguardStatusBar = mView.findViewById(R.id.keyguard_header);
-        mCommunalView = mView.findViewById(R.id.communal_host);
 
         FrameLayout userAvatarContainer = null;
         KeyguardUserSwitcherView keyguardUserSwitcherView = null;
@@ -984,20 +935,11 @@
                         .getKeyguardStatusBarViewController();
         mKeyguardStatusBarViewController.init();
 
-        if (mCommunalView != null) {
-            CommunalViewComponent communalViewComponent =
-                    mCommunalViewComponentFactory.build(mCommunalView);
-            mCommunalViewController =
-                    communalViewComponent.getCommunalHostViewController();
-            mCommunalViewController.init();
-        }
-
         mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
         updateViewControllers(
                 mView.findViewById(R.id.keyguard_status_view),
                 userAvatarContainer,
-                keyguardUserSwitcherView,
-                mCommunalView);
+                keyguardUserSwitcherView);
 
         NotificationStackScrollLayout stackScrollLayout = mView.findViewById(
                 R.id.notification_stack_scroller);
@@ -1088,8 +1030,7 @@
 
     private void updateViewControllers(KeyguardStatusView keyguardStatusView,
             FrameLayout userAvatarView,
-            KeyguardUserSwitcherView keyguardUserSwitcherView,
-            CommunalHostView communalView) {
+            KeyguardUserSwitcherView keyguardUserSwitcherView) {
         // Re-associate the KeyguardStatusViewController
         KeyguardStatusViewComponent statusViewComponent =
                 mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
@@ -1140,14 +1081,10 @@
 
     public void updateResources() {
         mQuickQsOffsetHeight = SystemBarUtils.getQuickQsOffsetHeight(mView.getContext());
-        mSplitShadeStatusBarHeight = Utils.getSplitShadeStatusBarHeight(mView.getContext());
         mSplitShadeNotificationsScrimMarginBottom =
                 mResources.getDimensionPixelSize(
                         R.dimen.split_shade_notifications_scrim_margin_bottom);
 
-        int panelMarginHorizontal = mResources.getDimensionPixelSize(
-                R.dimen.notification_panel_margin_horizontal);
-
         final boolean newShouldUseSplitNotificationShade =
                 Utils.shouldUseSplitNotificationShade(mResources);
         final boolean splitNotificationShadeChanged =
@@ -1157,49 +1094,12 @@
         if (mQs != null) {
             mQs.setInSplitShade(mShouldUseSplitNotificationShade);
         }
-
-        int notificationsBottomMargin = mResources.getDimensionPixelSize(
-                R.dimen.notification_panel_margin_bottom);
+        mSplitShadeStatusBarHeight = Utils.getSplitShadeStatusBarHeight(mView.getContext());
         int topMargin = mShouldUseSplitNotificationShade ? mSplitShadeStatusBarHeight :
                 mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_top);
         mSplitShadeHeaderController.setSplitShadeMode(mShouldUseSplitNotificationShade);
-
-        // To change the constraints at runtime, all children of the ConstraintLayout must have ids
-        ensureAllViewsHaveIds(mNotificationContainerParent);
-        ConstraintSet constraintSet = new ConstraintSet();
-        constraintSet.clone(mNotificationContainerParent);
-        int statusViewMarginHorizontal = mResources.getDimensionPixelSize(
-                R.dimen.status_view_margin_horizontal);
-        constraintSet.setMargin(R.id.keyguard_status_view, START, statusViewMarginHorizontal);
-        constraintSet.setMargin(R.id.keyguard_status_view, END, statusViewMarginHorizontal);
-        if (mShouldUseSplitNotificationShade) {
-            // width = 0 to take up all available space within constraints
-            constraintSet.connect(R.id.qs_frame, END, R.id.qs_edge_guideline, END);
-            constraintSet.connect(
-                    R.id.notification_stack_scroller, START,
-                    R.id.qs_edge_guideline, START);
-            constraintSet.constrainHeight(R.id.split_shade_status_bar, mSplitShadeStatusBarHeight);
-        } else {
-            constraintSet.connect(R.id.qs_frame, END, PARENT_ID, END);
-            constraintSet.connect(R.id.notification_stack_scroller, START, PARENT_ID, START);
-            if (mUseCombinedQSHeaders) {
-                constraintSet.constrainHeight(R.id.split_shade_status_bar, WRAP_CONTENT);
-            }
-        }
-        constraintSet.setMargin(R.id.notification_stack_scroller, START,
-                mShouldUseSplitNotificationShade ? 0 : panelMarginHorizontal);
-        constraintSet.setMargin(R.id.notification_stack_scroller, END, panelMarginHorizontal);
-        constraintSet.setMargin(R.id.notification_stack_scroller, TOP, topMargin);
-        constraintSet.setMargin(R.id.notification_stack_scroller, BOTTOM,
-                notificationsBottomMargin);
-        constraintSet.setMargin(R.id.qs_frame, START, panelMarginHorizontal);
-        constraintSet.setMargin(R.id.qs_frame, END,
-                mShouldUseSplitNotificationShade ? 0 : panelMarginHorizontal);
-        constraintSet.setMargin(R.id.qs_frame, TOP, topMargin);
-        constraintSet.applyTo(mNotificationContainerParent);
         mAmbientState.setStackTopMargin(topMargin);
-        mNotificationsQSContainerController.updateMargins();
-        mNotificationsQSContainerController.setSplitShadeEnabled(mShouldUseSplitNotificationShade);
+        mNotificationsQSContainerController.updateResources();
 
         updateKeyguardStatusViewAlignment(/* animate= */false);
 
@@ -1210,15 +1110,6 @@
         }
     }
 
-    private static void ensureAllViewsHaveIds(ViewGroup parentView) {
-        for (int i = 0; i < parentView.getChildCount(); i++) {
-            View childView = parentView.getChildAt(i);
-            if (childView.getId() == View.NO_ID) {
-                childView.setId(View.generateViewId());
-            }
-        }
-    }
-
     private View reInflateStub(int viewId, int stubId, int layoutId, boolean enabled) {
         View view = mView.findViewById(viewId);
         if (view != null) {
@@ -1282,7 +1173,7 @@
                         showKeyguardUserSwitcher /* enabled */);
 
         updateViewControllers(mView.findViewById(R.id.keyguard_status_view), userAvatarView,
-                keyguardUserSwitcherView, mCommunalView);
+                keyguardUserSwitcherView);
 
         // Update keyguard bottom area
         int index = mView.indexOfChild(mKeyguardBottomArea);
@@ -1428,10 +1319,6 @@
         int stackScrollerPadding;
         boolean onKeyguard = isOnKeyguard();
 
-        if (onKeyguard) {
-            updateCommunalViewAppearance();
-        }
-
         if (onKeyguard || forceClockUpdate) {
             updateClockAppearance();
         }
@@ -1457,22 +1344,6 @@
         mAnimateNextPositionUpdate = false;
     }
 
-    private void updateCommunalViewAppearance() {
-        if (mCommunalViewController == null) {
-            return;
-        }
-
-        float expandedFraction =
-                mScreenOffAnimationController.shouldExpandNotifications()
-                        ? 1.0f : getExpandedFraction();
-        mCommunalPositionAlgorithm.setup(expandedFraction, mCommunalView.getHeight());
-        mCommunalPositionAlgorithm.run(mCommunalPositionResult);
-        boolean animate =
-                mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending()
-                        || mAnimateNextPositionUpdate;
-        mCommunalViewController.updatePosition(mCommunalPositionResult.communalY, animate);
-    }
-
     private void updateClockAppearance() {
         int userSwitcherPreferredY = mStatusBarHeaderHeightKeyguard;
         boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
@@ -1547,9 +1418,8 @@
     private void updateKeyguardStatusViewAlignment(boolean animate) {
         boolean hasVisibleNotifications = mNotificationStackScrollLayoutController
                 .getVisibleNotificationCount() != 0 || mMediaDataManager.hasActiveMedia();
-        boolean hasCommunalSurface = mCommunalSource != null && mCommunalSource.get() != null;
-        boolean shouldBeCentered = !mShouldUseSplitNotificationShade
-                || (!hasVisibleNotifications && !hasCommunalSurface) || mDozing;
+        boolean shouldBeCentered = !mShouldUseSplitNotificationShade || !hasVisibleNotifications
+                || mDozing;
         if (mStatusViewCentered != shouldBeCentered) {
             mStatusViewCentered = shouldBeCentered;
             ConstraintSet constraintSet = new ConstraintSet();
@@ -1558,6 +1428,11 @@
             constraintSet.connect(R.id.keyguard_status_view, END, statusConstraint, END);
             if (animate) {
                 ChangeBounds transition = new ChangeBounds();
+                if (mShouldUseSplitNotificationShade) {
+                    // Excluding media from the transition on split-shade, as it doesn't transition
+                    // horizontally properly.
+                    transition.excludeTarget(R.id.status_view_media_container, true);
+                }
                 transition.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
                 transition.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
                 TransitionManager.beginDelayedTransition(mNotificationContainerParent, transition);
@@ -1579,11 +1454,6 @@
      * @return the maximum keyguard notifications that can fit on the screen
      */
     private int computeMaxKeyguardNotifications() {
-        // Do not show any notifications on the keyguard if a communal source is set.
-        if (mCommunalSource != null && mCommunalSource.get() != null) {
-            return 0;
-        }
-
         float minPadding = mClockPositionAlgorithm.getMinStackScrollerPadding();
         int notificationPadding = Math.max(
                 1, mResources.getDimensionPixelSize(R.dimen.notification_divider_height));
@@ -1707,15 +1577,11 @@
         return true;
     }
 
-    private void updateCommunal() {
-        if (mCommunalViewController != null) {
-            mCommunalViewController.setAlpha(mKeyguardOnlyContentAlpha);
-        }
-    }
-
     private void updateClock() {
         float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha;
         mKeyguardStatusViewController.setAlpha(alpha);
+        mKeyguardStatusViewController
+                .setTranslationYExcludingMedia(mKeyguardOnlyTransitionTranslationY);
         if (mKeyguardQsUserSwitchController != null) {
             mKeyguardQsUserSwitchController.setAlpha(alpha);
         }
@@ -1786,11 +1652,16 @@
 
         if (mQsExpanded) {
             mQsExpandImmediate = true;
-            mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
+            setShowShelfOnly(true);
         }
         super.collapse(delayed, speedUpFactor);
     }
 
+    private void setShowShelfOnly(boolean shelfOnly) {
+        mNotificationStackScrollLayoutController.setShouldShowShelfOnly(
+                shelfOnly && !mShouldUseSplitNotificationShade);
+    }
+
     public void closeQs() {
         cancelQsAnimation();
         setQsExpansion(mQsMinExpansionHeight);
@@ -1827,7 +1698,7 @@
     public void expandWithQs() {
         if (isQsExpansionEnabled()) {
             mQsExpandImmediate = true;
-            mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
+            setShowShelfOnly(true);
         }
         if (isFullyCollapsed()) {
             expand(true /* animate */);
@@ -1860,14 +1731,14 @@
         mHeadsUpTouchHelper.notifyFling(!expand);
         mKeyguardStateController.notifyPanelFlingStart(!expand /* flingingToDismiss */);
         setClosingWithAlphaFadeout(!expand && !isOnKeyguard() && getFadeoutAlpha() == 1.0f);
-        mNotificationStackScrollLayoutController.setIsFlinging(true);
+        mAmbientState.setIsFlinging(true);
         super.flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing);
     }
 
     @Override
     protected void onFlingEnd(boolean cancelled) {
         super.onFlingEnd(cancelled);
-        mNotificationStackScrollLayoutController.setIsFlinging(false);
+        mAmbientState.setIsFlinging(false);
     }
 
     private boolean onQsIntercept(MotionEvent event) {
@@ -2026,7 +1897,15 @@
             mFalsingManager.isFalseTouch(QS_COLLAPSE);
         }
 
-        flingSettings(vel, expandsQs && !isCancelMotionEvent ? FLING_EXPAND : FLING_COLLAPSE);
+        int flingType;
+        if (expandsQs && !isCancelMotionEvent) {
+            flingType = FLING_EXPAND;
+        } else if (mShouldUseSplitNotificationShade) {
+            flingType = FLING_HIDE;
+        } else {
+            flingType = FLING_COLLAPSE;
+        }
+        flingSettings(vel, flingType);
     }
 
     private void logQsSwipeDown(float y) {
@@ -2091,8 +1970,10 @@
             return false;
         }
         final int action = event.getActionMasked();
-        if (action == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f
-                && mBarState != KEYGUARD && !mQsExpanded && isQsExpansionEnabled()) {
+        boolean collapsedQs = !mQsExpanded && !mShouldUseSplitNotificationShade;
+        boolean expandedShadeCollapsedQs = getExpandedFraction() == 1f && mBarState != KEYGUARD
+                && collapsedQs && isQsExpansionEnabled();
+        if (action == MotionEvent.ACTION_DOWN && expandedShadeCollapsedQs) {
             // Down in the empty area while fully expanded - go to QS.
             mQsTracking = true;
             traceQsJank(true /* startTracing */, false /* wasCancelled */);
@@ -2107,7 +1988,7 @@
         }
         if (!mQsExpandImmediate && mQsTracking) {
             onQsTouch(event);
-            if (!mConflictingQsExpansionGesture) {
+            if (!mConflictingQsExpansionGesture && !mShouldUseSplitNotificationShade) {
                 return true;
             }
         }
@@ -2121,7 +2002,7 @@
                 < mStatusBarMinHeight) {
             mMetricsLogger.count(COUNTER_PANEL_OPEN_QS, 1);
             mQsExpandImmediate = true;
-            mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
+            setShowShelfOnly(true);
             requestPanelHeightUpdate();
 
             // Normally, we start listening when the panel is expanded, but here we need to start
@@ -2192,6 +2073,9 @@
         if (!isFullyCollapsed()) {
             return;
         }
+        if (mShouldUseSplitNotificationShade) {
+            mQsExpandImmediate = true;
+        }
         mExpectingSynthesizedDown = true;
         onTrackingStarted();
         updatePanelExpanded();
@@ -2398,12 +2282,10 @@
     }
 
     private void updateQsState() {
-        mNotificationStackScrollLayoutController.setQsExpanded(mQsExpanded);
+        boolean qsFullScreen = mQsExpanded && !mShouldUseSplitNotificationShade;
+        mNotificationStackScrollLayoutController.setQsFullScreen(qsFullScreen);
         mNotificationStackScrollLayoutController.setScrollingEnabled(
-                mBarState != KEYGUARD
-                        && (!mQsExpanded
-                            || mQsExpansionFromOverscroll
-                            || mShouldUseSplitNotificationShade));
+                mBarState != KEYGUARD && (!qsFullScreen || mQsExpansionFromOverscroll));
 
         if (mKeyguardUserSwitcherController != null && mQsExpanded
                 && !mStackScrollerOverscrolling) {
@@ -2448,7 +2330,7 @@
     private void updateQsExpansion() {
         if (mQs == null) return;
         final float squishiness;
-        if (mQsExpandImmediate || mQsExpanded) {
+        if ((mQsExpandImmediate || mQsExpanded) && !mShouldUseSplitNotificationShade) {
             squishiness = 1;
         } else if (mLockscreenShadeTransitionController.getQSDragProgress() > 0) {
             squishiness = mLockscreenShadeTransitionController.getQSDragProgress();
@@ -2483,10 +2365,6 @@
         mSplitShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction);
         mSplitShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
         mSplitShadeHeaderController.setShadeExpanded(mQsVisible);
-
-        if (mCommunalViewController != null) {
-            mCommunalViewController.updateQsExpansion(qsExpansionFraction);
-        }
     }
 
     private void onStackYChanged(boolean shouldAnimate) {
@@ -2849,10 +2727,6 @@
         }
         mTransitionToFullShadeQSPosition = position;
         updateQsExpansion();
-
-        if (mCommunalViewController != null) {
-            mCommunalViewController.updateShadeExpansion(mTransitioningToFullShadeProgress);
-        }
     }
 
     /**
@@ -2865,18 +2739,18 @@
     }
 
     /**
-     * Set the alpha of the keyguard elements which only show on the lockscreen, but not in
-     * shade locked / shade. This is used when dragging down to the full shade.
+     * Set the alpha and translationY of the keyguard elements which only show on the lockscreen,
+     * but not in shade locked / shade. This is used when dragging down to the full shade.
      */
-    public void setKeyguardOnlyContentAlpha(float keyguardAlpha) {
+    public void setKeyguardTransitionProgress(float keyguardAlpha, int keyguardTranslationY) {
         mKeyguardOnlyContentAlpha = Interpolators.ALPHA_IN.getInterpolation(keyguardAlpha);
+        mKeyguardOnlyTransitionTranslationY = keyguardTranslationY;
         if (mBarState == KEYGUARD) {
             // If the animator is running, it's already fading out the content and this is a reset
             mBottomAreaShadeAlpha = mKeyguardOnlyContentAlpha;
             updateKeyguardBottomAreaAlpha();
         }
         updateClock();
-        updateCommunal();
     }
 
     private void trackMovement(MotionEvent event) {
@@ -3135,9 +3009,7 @@
     }
 
     private int calculatePanelHeightShade() {
-        int emptyBottomMargin = mNotificationStackScrollLayoutController.getEmptyBottomMargin();
-        int maxHeight = mNotificationStackScrollLayoutController.getHeight() - emptyBottomMargin;
-
+        final int maxHeight = mNotificationStackScrollLayoutController.getHeight();
         if (mBarState == KEYGUARD) {
             int minKeyguardPanelBottom = mClockPositionAlgorithm.getLockscreenStatusViewHeight()
                     + mNotificationStackScrollLayoutController.getIntrinsicContentHeight();
@@ -3305,7 +3177,7 @@
             setListening(true);
         }
         mQsExpandImmediate = false;
-        mNotificationStackScrollLayoutController.setShouldShowShelfOnly(false);
+        setShowShelfOnly(false);
         mTwoFingerQsExpandPossible = false;
         updateTrackingHeadsUp(null);
         mExpandingFromHeadsUp = false;
@@ -3361,9 +3233,7 @@
         mScrimController.onTrackingStarted();
         if (mQsFullyExpanded) {
             mQsExpandImmediate = true;
-            if (!mShouldUseSplitNotificationShade) {
-                mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
-            }
+            setShowShelfOnly(true);
         }
         if (mBarState == KEYGUARD || mBarState == StatusBarState.SHADE_LOCKED) {
             mAffordanceHelper.animateHideLeftRightIcon();
@@ -3466,9 +3336,7 @@
         boolean wasRunning = isLaunchTransitionRunning();
         super.setIsLaunchAnimationRunning(running);
         if (wasRunning != isLaunchTransitionRunning()) {
-            for (Callbacks cb : mNotifEventSourceCallbacks) {
-                cb.onLaunchingActivityChanged(running);
-            }
+            mPanelEventsEmitter.notifyLaunchingActivityChanged(running);
         }
     }
 
@@ -3477,9 +3345,7 @@
         boolean wasClosing = isClosing();
         super.setIsClosing(isClosing);
         if (wasClosing != isClosing) {
-            for (Callbacks cb : mNotifEventSourceCallbacks) {
-                cb.onPanelCollapsingChanged(isClosing);
-            }
+            mPanelEventsEmitter.notifyPanelCollapsingChanged(isClosing);
         }
     }
 
@@ -4072,10 +3938,6 @@
         mNotificationStackScrollLayoutController.runAfterAnimationFinished(r);
     }
 
-    public void setScrollingEnabled(boolean b) {
-        mNotificationStackScrollLayoutController.setScrollingEnabled(b);
-    }
-
     private Runnable mHideExpandedRunnable;
     private final Runnable mMaybeHideExpandedRunnable = new Runnable() {
         @Override
@@ -4381,16 +4243,6 @@
                 .commitUpdate(mDisplayId);
     }
 
-    @Override
-    public void registerCallbacks(Callbacks callbacks) {
-        mNotifEventSourceCallbacks.addIfAbsent(callbacks);
-    }
-
-    @Override
-    public void unregisterCallbacks(Callbacks callbacks) {
-        mNotifEventSourceCallbacks.remove(callbacks);
-    }
-
     private class OnHeightChangedListener implements ExpandableView.OnHeightChangedListener {
         @Override
         public void onHeightChanged(ExpandableView view, boolean needsAnimation) {
@@ -4770,14 +4622,6 @@
                     goingToFullShade,
                     mBarState);
 
-            if (mCommunalViewController != null) {
-                mCommunalViewController.setKeyguardStatusViewVisibility(
-                        statusBarState,
-                        keyguardFadingAway,
-                        goingToFullShade,
-                        mBarState);
-            }
-
             setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);
 
             mBarState = statusBarState;
@@ -4905,25 +4749,6 @@
         setExpandedFraction(1f);
     }
 
-    private void setCommunalSource(WeakReference<CommunalSource> source) {
-        CommunalSource existingSource = mCommunalSource != null ? mCommunalSource.get() : null;
-
-        if (existingSource != null) {
-            mCommunalViewController.show(null /*source*/);
-        }
-
-        mCommunalSource = source;
-
-        CommunalSource currentSource = mCommunalSource != null ? mCommunalSource.get() : null;
-        // Set source and register callback
-        if (currentSource != null && mCommunalViewController != null) {
-            mCommunalViewController.show(source);
-        }
-
-        updateKeyguardStatusViewAlignment(true /*animate*/);
-        updateMaxDisplayedNotifications(true /*recompute*/);
-    }
-
     /**
      * Sets the overstretch amount in raw pixels when dragging down.
      */
@@ -4941,7 +4766,6 @@
                             .addTagListener(QS.TAG, mFragmentListener);
             mStatusBarStateController.addCallback(mStatusBarStateListener);
             mConfigurationController.addCallback(mConfigurationListener);
-            mCommunalSourceMonitor.addCallback(mCommunalSourceMonitorCallback);
             // Theme might have changed between inflating this view and attaching it to the
             // window, so
             // force a call to onThemeChanged
@@ -4949,7 +4773,6 @@
             mFalsingManager.addTapListener(mFalsingTapListener);
             mKeyguardIndicationController.init();
             registerSettingsChangeListener();
-            mCommunalStateController.addCallback(mCommunalStateCallback);
         }
 
         @Override
@@ -4959,9 +4782,7 @@
                             .removeTagListener(QS.TAG, mFragmentListener);
             mStatusBarStateController.removeCallback(mStatusBarStateListener);
             mConfigurationController.removeCallback(mConfigurationListener);
-            mCommunalSourceMonitor.removeCallback(mCommunalSourceMonitorCallback);
             mFalsingManager.removeTapListener(mFalsingTapListener);
-            mCommunalStateController.removeCallback(mCommunalStateCallback);
         }
     }
 
@@ -5027,7 +4848,11 @@
 
     private void updateQSMinHeight() {
         float previousMin = mQsMinExpansionHeight;
-        mQsMinExpansionHeight = mKeyguardShowing ? 0 : mQs.getQsMinExpansionHeight();
+        if (mKeyguardShowing || mShouldUseSplitNotificationShade) {
+            mQsMinExpansionHeight = 0;
+        } else {
+            mQsMinExpansionHeight = mQs.getQsMinExpansionHeight();
+        }
         if (mQsExpansionHeight == previousMin) {
             mQsExpansionHeight = mQsMinExpansionHeight;
         }
@@ -5164,4 +4989,35 @@
                     1.0f /* speedUpFactor */);
         }
     }
+
+    @SysUISingleton
+    static class PanelEventsEmitter implements NotifPanelEvents {
+
+        private final ListenerSet<Listener> mListeners = new ListenerSet<>();
+
+        @Inject
+        PanelEventsEmitter() {}
+
+        @Override
+        public void registerListener(@NonNull Listener listener) {
+            mListeners.addIfAbsent(listener);
+        }
+
+        @Override
+        public void unregisterListener(@NonNull Listener listener) {
+            mListeners.remove(listener);
+        }
+
+        private void notifyLaunchingActivityChanged(boolean isLaunchingActivity) {
+            for (Listener cb : mListeners) {
+                cb.onLaunchingActivityChanged(isLaunchingActivity);
+            }
+        }
+
+        private void notifyPanelCollapsingChanged(boolean isCollapsing) {
+            for (NotifPanelEvents.Listener cb : mListeners) {
+                cb.onPanelCollapsingChanged(isCollapsing);
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index 0ff010a..16e5732 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -386,10 +386,12 @@
             }
             visible = true;
         }
-        if (visible) {
-            mNotificationShadeView.setVisibility(View.VISIBLE);
-        } else {
-            mNotificationShadeView.setVisibility(View.INVISIBLE);
+        if (mNotificationShadeView != null) {
+            if (visible) {
+                mNotificationShadeView.setVisibility(View.VISIBLE);
+            } else {
+                mNotificationShadeView.setVisibility(View.INVISIBLE);
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
index 7c9e597..7764d338 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
@@ -1,6 +1,16 @@
 package com.android.systemui.statusbar.phone
 
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import android.view.WindowInsets
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
+import androidx.constraintlayout.widget.ConstraintSet.END
+import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
+import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.constraintlayout.widget.ConstraintSet.TOP
+import com.android.systemui.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.navigationbar.NavigationModeController
@@ -9,6 +19,7 @@
 import com.android.systemui.recents.OverviewProxyService
 import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
 import com.android.systemui.shared.system.QuickStepContract
+import com.android.systemui.util.Utils
 import com.android.systemui.util.ViewController
 import java.util.function.Consumer
 import javax.inject.Inject
@@ -27,22 +38,20 @@
                 mView.invalidate()
             }
         }
-    var splitShadeEnabled = false
-        set(value) {
-            if (field != value) {
-                field = value
-                // in case device configuration changed while showing QS details/customizer
-                updateBottomSpacing()
-            }
-        }
-
+    private var splitShadeEnabled = false
     private var isQSDetailShowing = false
     private var isQSCustomizing = false
     private var isQSCustomizerAnimating = false
 
+    private var splitShadeStatusBarHeight = 0
     private var notificationsBottomMargin = 0
+    private var scrimShadeBottomMargin = 0
     private var bottomStableInsets = 0
     private var bottomCutoutInsets = 0
+    private var panelMarginHorizontal = 0
+    private var topMargin = 0
+
+    private val useCombinedQSHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)
 
     private var isGestureNavigation = true
     private var taskbarVisible = false
@@ -66,20 +75,49 @@
     }
 
     public override fun onViewAttached() {
-        updateMargins()
+        updateResources()
         overviewProxyService.addCallback(taskbarVisibilityListener)
         mView.setInsetsChangedListener(windowInsetsListener)
         mView.setQSFragmentAttachedListener { qs: QS -> qs.setContainerController(this) }
+        mView.setConfigurationChangedListener { updateResources() }
     }
 
     override fun onViewDetached() {
         overviewProxyService.removeCallback(taskbarVisibilityListener)
         mView.removeOnInsetsChangedListener()
         mView.removeQSFragmentAttachedListener()
+        mView.setConfigurationChangedListener(null)
     }
 
-    fun updateMargins() {
-        notificationsBottomMargin = mView.defaultNotificationsMarginBottom
+    fun updateResources() {
+        val newSplitShadeEnabled = Utils.shouldUseSplitNotificationShade(resources)
+        val splitShadeEnabledChanged = newSplitShadeEnabled != splitShadeEnabled
+        splitShadeEnabled = newSplitShadeEnabled
+        notificationsBottomMargin = resources.getDimensionPixelSize(
+                R.dimen.notification_panel_margin_bottom)
+        splitShadeStatusBarHeight = Utils.getSplitShadeStatusBarHeight(context)
+        panelMarginHorizontal = resources.getDimensionPixelSize(
+                R.dimen.notification_panel_margin_horizontal)
+        topMargin = if (splitShadeEnabled) {
+            splitShadeStatusBarHeight
+        } else {
+            resources.getDimensionPixelSize(R.dimen.notification_panel_margin_top)
+        }
+        updateConstraints()
+        if (splitShadeEnabledChanged) {
+            // Let's do it at the end when all margins/paddings were already applied.
+            // We need to updateBottomSpacing() in case device configuration changed while showing
+            // QS details/customizer
+            updateBottomSpacing()
+        }
+        val previousScrimShadeBottomMargin = scrimShadeBottomMargin
+        scrimShadeBottomMargin = resources.getDimensionPixelSize(
+            R.dimen.split_shade_notifications_scrim_margin_bottom
+        )
+
+        if (previousScrimShadeBottomMargin != scrimShadeBottomMargin) {
+            updateBottomSpacing()
+        }
     }
 
     override fun setCustomizerAnimating(animating: Boolean) {
@@ -111,7 +149,11 @@
             qsScrollPaddingBottom = bottomStableInsets
         } else if (newFooter && !(isQSCustomizing || isQSDetailShowing)) {
             // With the new footer, we also want this padding in the bottom in these cases
-            qsScrollPaddingBottom = bottomStableInsets
+            qsScrollPaddingBottom = if (splitShadeEnabled) {
+                notificationsMargin - scrimShadeBottomMargin
+            } else {
+                bottomStableInsets
+            }
         }
         mView.setPadding(0, 0, 0, containerPadding)
         mView.setNotificationsMarginBottom(notificationsMargin)
@@ -153,4 +195,66 @@
         }
         return containerPadding to stackScrollMargin
     }
-}
\ No newline at end of file
+
+    fun updateConstraints() {
+        // To change the constraints at runtime, all children of the ConstraintLayout must have ids
+        ensureAllViewsHaveIds(mView)
+        val constraintSet = ConstraintSet()
+        constraintSet.clone(mView)
+        setKeyguardStatusViewConstraints(constraintSet)
+        setQsConstraints(constraintSet)
+        setNotificationsConstraints(constraintSet)
+        setSplitShadeStatusBarConstraints(constraintSet)
+        mView.applyConstraints(constraintSet)
+    }
+
+    private fun setSplitShadeStatusBarConstraints(constraintSet: ConstraintSet) {
+        if (splitShadeEnabled) {
+            constraintSet.constrainHeight(R.id.split_shade_status_bar, splitShadeStatusBarHeight)
+        } else {
+            if (useCombinedQSHeaders) {
+                constraintSet.constrainHeight(R.id.split_shade_status_bar, WRAP_CONTENT)
+            }
+        }
+    }
+
+    private fun setNotificationsConstraints(constraintSet: ConstraintSet) {
+        val startConstraintId = if (splitShadeEnabled) R.id.qs_edge_guideline else PARENT_ID
+        constraintSet.apply {
+            connect(R.id.notification_stack_scroller, START, startConstraintId, START)
+            setMargin(R.id.notification_stack_scroller, START,
+                    if (splitShadeEnabled) 0 else panelMarginHorizontal)
+            setMargin(R.id.notification_stack_scroller, END, panelMarginHorizontal)
+            setMargin(R.id.notification_stack_scroller, TOP, topMargin)
+            setMargin(R.id.notification_stack_scroller, BOTTOM, notificationsBottomMargin)
+        }
+    }
+
+    private fun setQsConstraints(constraintSet: ConstraintSet) {
+        val endConstraintId = if (splitShadeEnabled) R.id.qs_edge_guideline else PARENT_ID
+        constraintSet.apply {
+            connect(R.id.qs_frame, END, endConstraintId, END)
+            setMargin(R.id.qs_frame, START, if (splitShadeEnabled) 0 else panelMarginHorizontal)
+            setMargin(R.id.qs_frame, END, if (splitShadeEnabled) 0 else panelMarginHorizontal)
+            setMargin(R.id.qs_frame, TOP, topMargin)
+        }
+    }
+
+    private fun setKeyguardStatusViewConstraints(constraintSet: ConstraintSet) {
+        val statusViewMarginHorizontal = resources.getDimensionPixelSize(
+                R.dimen.status_view_margin_horizontal)
+        constraintSet.apply {
+            setMargin(R.id.keyguard_status_view, START, statusViewMarginHorizontal)
+            setMargin(R.id.keyguard_status_view, END, statusViewMarginHorizontal)
+        }
+    }
+
+    private fun ensureAllViewsHaveIds(parentView: ViewGroup) {
+        for (i in 0 until parentView.childCount) {
+            val childView = parentView.getChildAt(i)
+            if (childView.id == View.NO_ID) {
+                childView.id = View.generateViewId()
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index 95e3b70..7caea06 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -18,12 +18,15 @@
 
 import android.app.Fragment;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.WindowInsets;
 
+import androidx.annotation.Nullable;
 import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.constraintlayout.widget.ConstraintSet;
 
 import com.android.systemui.R;
 import com.android.systemui.fragments.FragmentHostManager;
@@ -54,6 +57,9 @@
     private View mQSScrollView;
     private View mQSContainer;
 
+    @Nullable
+    private Consumer<Configuration> mConfigurationChangedListener;
+
     public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -79,6 +85,18 @@
         invalidate();
     }
 
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        if (mConfigurationChangedListener != null) {
+            mConfigurationChangedListener.accept(newConfig);
+        }
+    }
+
+    public void setConfigurationChangedListener(Consumer<Configuration> listener) {
+        mConfigurationChangedListener = listener;
+    }
+
     public void setNotificationsMarginBottom(int margin) {
         LayoutParams params = (LayoutParams) mStackScroller.getLayoutParams();
         params.bottomMargin = margin;
@@ -106,10 +124,6 @@
         }
     }
 
-    public int getDefaultNotificationsMarginBottom() {
-        return ((LayoutParams) mStackScroller.getLayoutParams()).bottomMargin;
-    }
-
     public void setInsetsChangedListener(Consumer<WindowInsets> onInsetsChangedListener) {
         mInsetsChangedListener = onInsetsChangedListener;
     }
@@ -180,4 +194,7 @@
         }
     }
 
+    public void applyConstraints(ConstraintSet constraintSet) {
+        constraintSet.applyTo(this);
+    }
 }
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 7c1775e..24f5ff8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -382,7 +382,7 @@
 
     protected void startExpandMotion(float newX, float newY, boolean startTracking,
             float expandedHeight) {
-        if (!mHandlingPointerUp) {
+        if (!mHandlingPointerUp && !mStatusBarStateController.isDozing()) {
             beginJankMonitoring(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
         }
         mInitialOffsetOnTouch = expandedHeight;
@@ -397,6 +397,7 @@
 
     private void endMotionEvent(MotionEvent event, float x, float y, boolean forceCancel) {
         mTrackingPointer = -1;
+        mAmbientState.setSwipingUp(false);
         if ((mTracking && mTouchSlopExceeded) || Math.abs(x - mInitialTouchX) > mTouchSlop
                 || Math.abs(y - mInitialTouchY) > mTouchSlop
                 || event.getActionMasked() == MotionEvent.ACTION_CANCEL || forceCancel) {
@@ -460,7 +461,6 @@
             boolean expands = onEmptySpaceClick(mInitialTouchX);
             onTrackingStopped(expands);
         }
-        mAmbientState.setSwipingUp(false);
         mVelocityTracker.clear();
     }
 
@@ -654,7 +654,9 @@
 
             @Override
             public void onAnimationStart(Animator animation) {
-                beginJankMonitoring(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
+                if (!mStatusBarStateController.isDozing()) {
+                    beginJankMonitoring(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
+                }
             }
 
             @Override
@@ -794,6 +796,7 @@
             }
             mExpandedFraction = Math.min(1f,
                     maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
+            mAmbientState.setExpansionFraction(mExpandedFraction);
             onHeightUpdated(mExpandedHeight);
             updatePanelExpansionAndVisibility();
         });
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 a3c795f..419661b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -773,7 +773,7 @@
             }
             if (mUnOcclusionAnimationRunning && mState == ScrimState.KEYGUARD) {
                 // We're unoccluding the keyguard and don't want to have a bright flash.
-                mNotificationsAlpha = mScrimBehindAlphaKeyguard;
+                mNotificationsAlpha = ScrimState.KEYGUARD.getNotifAlpha();
                 mNotificationsTint = ScrimState.KEYGUARD.getNotifTint();
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index edbddbb..637e4be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -41,6 +41,7 @@
 import android.util.EventLog;
 import android.view.View;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.jank.InteractionJankMonitor;
@@ -51,6 +52,7 @@
 import com.android.systemui.EventLogTags;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.assist.AssistManager;
+import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
@@ -75,6 +77,7 @@
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.HeadsUpUtil;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.ListenerSet;
 import com.android.systemui.wmshell.BubblesManager;
 
 import java.util.Optional;
@@ -128,6 +131,7 @@
     private final ActivityLaunchAnimator mActivityLaunchAnimator;
     private final NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
     private final OnUserInteractionCallback mOnUserInteractionCallback;
+    private final LaunchEventsEmitter mLaunchEventsEmitter;
 
     private boolean mIsCollapsingToShowActivityOverLockscreen;
 
@@ -166,7 +170,8 @@
             NotificationPresenter presenter,
             NotificationPanelViewController panel,
             ActivityLaunchAnimator activityLaunchAnimator,
-            NotificationLaunchAnimatorControllerProvider notificationAnimationProvider) {
+            NotificationLaunchAnimatorControllerProvider notificationAnimationProvider,
+            LaunchEventsEmitter launchEventsEmitter) {
         mContext = context;
         mCommandQueue = commandQueue;
         mMainThreadHandler = mainThreadHandler;
@@ -192,18 +197,17 @@
         mLockPatternUtils = lockPatternUtils;
         mStatusBarRemoteInputCallback = remoteInputCallback;
         mActivityIntentHelper = activityIntentHelper;
-
         mNotifPipelineFlags = notifPipelineFlags;
         mMetricsLogger = metricsLogger;
         mLogger = logger;
         mOnUserInteractionCallback = onUserInteractionCallback;
-
         // TODO: use KeyguardStateController#isOccluded to remove this dependency
         mCentralSurfaces = centralSurfaces;
         mPresenter = presenter;
         mNotificationPanel = panel;
         mActivityLaunchAnimator = activityLaunchAnimator;
         mNotificationAnimationProvider = notificationAnimationProvider;
+        mLaunchEventsEmitter = launchEventsEmitter;
 
         if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
             mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@@ -254,6 +258,8 @@
             return;
         }
 
+        mLaunchEventsEmitter.notifyStartLaunchNotifActivity(entry);
+
         boolean isActivityIntent = intent != null && intent.isActivity() && !isBubble;
         final boolean willLaunchResolverActivity = isActivityIntent
                 && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
@@ -280,7 +286,9 @@
             postKeyguardAction.onDismiss();
         } else {
             mActivityStarter.dismissKeyguardThenExecute(
-                    postKeyguardAction, null /* cancel */, willLaunchResolverActivity);
+                    postKeyguardAction,
+                    () -> mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry),
+                    willLaunchResolverActivity);
         }
     }
 
@@ -362,6 +370,8 @@
             mLogger.logExpandingBubble(notificationKey);
             removeHunAfterClick(row);
             expandBubbleStackOnMainThread(entry);
+            mMainThreadHandler.post(
+                    () -> mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry));
         } else {
             startNotificationIntent(intent, fillInIntent, entry, row, animate, isActivityIntent);
         }
@@ -380,24 +390,22 @@
         // inform NMS that the notification was clicked
         mClickNotifier.onNotificationClick(notificationKey, nv);
 
-        if (!canBubble) {
-            if (shouldAutoCancel || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(
-                    notificationKey)) {
-                // Immediately remove notification from visually showing.
-                // We have to post the removal to the UI thread for synchronization.
-                mMainThreadHandler.post(() -> {
-                    final Runnable removeNotification = () ->
-                            mOnUserInteractionCallback.onDismiss(
-                                    entry, REASON_CLICK, summaryToRemove);
-                    if (mPresenter.isCollapsing()) {
-                        // To avoid lags we're only performing the remove
-                        // after the shade is collapsed
-                        mShadeController.addPostCollapseAction(removeNotification);
-                    } else {
-                        removeNotification.run();
-                    }
-                });
-            }
+        if (!canBubble && (shouldAutoCancel
+                || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(notificationKey))) {
+            // Immediately remove notification from visually showing.
+            // We have to post the removal to the UI thread for synchronization.
+            mMainThreadHandler.post(() -> {
+                final Runnable removeNotification = () -> {
+                    mOnUserInteractionCallback.onDismiss(entry, REASON_CLICK, summaryToRemove);
+                };
+                if (mPresenter.isCollapsing()) {
+                    // To avoid lags we're only performing the remove
+                    // after the shade is collapsed
+                    mShadeController.addPostCollapseAction(removeNotification);
+                } else {
+                    removeNotification.run();
+                }
+            });
         }
 
         mIsCollapsingToShowActivityOverLockscreen = false;
@@ -473,14 +481,19 @@
             boolean isActivityIntent) {
         mLogger.logStartNotificationIntent(entry.getKey(), intent);
         try {
+            Runnable onFinishAnimationCallback =
+                    () -> mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry);
             ActivityLaunchAnimator.Controller animationController =
                     new StatusBarLaunchAnimatorController(
-                            mNotificationAnimationProvider.getAnimatorController(row),
+                            mNotificationAnimationProvider
+                                    .getAnimatorController(row, onFinishAnimationCallback),
                             mCentralSurfaces,
                             isActivityIntent);
-
-            mActivityLaunchAnimator.startPendingIntentWithAnimation(animationController,
-                    animate, intent.getCreatorPackage(), (adapter) -> {
+            mActivityLaunchAnimator.startPendingIntentWithAnimation(
+                    animationController,
+                    animate,
+                    intent.getCreatorPackage(),
+                    (adapter) -> {
                         long eventTime = row.getAndResetLastActionUpTime();
                         Bundle options = eventTime > 0
                                 ? getActivityOptions(
@@ -659,4 +672,35 @@
 
         return entry.shouldSuppressFullScreenIntent();
     }
+
+    @SysUISingleton
+    static class LaunchEventsEmitter implements NotifActivityLaunchEvents {
+
+        private final ListenerSet<Listener> mListeners = new ListenerSet<>();
+
+        @Inject
+        LaunchEventsEmitter() {}
+
+        @Override
+        public void registerListener(@NonNull Listener listener) {
+            mListeners.addIfAbsent(listener);
+        }
+
+        @Override
+        public void unregisterListener(@NonNull Listener listener) {
+            mListeners.remove(listener);
+        }
+
+        private void notifyStartLaunchNotifActivity(NotificationEntry entry) {
+            for (Listener listener : mListeners) {
+                listener.onStartLaunchNotifActivity(entry);
+            }
+        }
+
+        private void notifyFinishLaunchNotifActivity(NotificationEntry entry) {
+            for (Listener listener : mListeners) {
+                listener.onFinishLaunchNotifActivity(entry);
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
index 59c9d0b..a86ad6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
@@ -27,7 +27,6 @@
 import com.android.systemui.statusbar.core.StatusBarInitializer;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
-import com.android.systemui.statusbar.notification.collection.render.StatusBarNotifPanelEventSourceModule;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutListContainerModule;
@@ -60,8 +59,8 @@
  * outside the component. Should more items be moved *into* this component to avoid so many getters?
  */
 @Subcomponent(modules = {
+        CentralSurfacesStartableModule.class,
         NotificationStackScrollLayoutListContainerModule.class,
-        StatusBarNotifPanelEventSourceModule.class,
         StatusBarViewModule.class,
         StatusBarNotificationActivityStarterModule.class,
         StatusBarNotificationPresenterModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
similarity index 65%
rename from packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
index 2894780..21e5ad5 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -14,13 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.dagger;
+package com.android.systemui.statusbar.phone.dagger;
+
+import java.util.Set;
 
 import dagger.Module;
+import dagger.multibindings.Multibinds;
 
-/**
- * Dagger module for including the WMComponent.
- */
-@Module(subcomponents = {WMComponent.class})
-public abstract class WMModule {
+@Module
+interface CentralSurfacesStartableModule {
+    @Multibinds
+    Set<CentralSurfacesComponent.Startable> multibindStartables();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
index ad47e2b..01fe865 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.annotation.WorkerThread;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -219,6 +220,7 @@
             new CameraManager.TorchCallback() {
 
         @Override
+        @WorkerThread
         public void onTorchModeUnavailable(String cameraId) {
             if (TextUtils.equals(cameraId, mCameraId)) {
                 setCameraAvailable(false);
@@ -229,6 +231,7 @@
         }
 
         @Override
+        @WorkerThread
         public void onTorchModeChanged(String cameraId, boolean enabled) {
             if (TextUtils.equals(cameraId, mCameraId)) {
                 setCameraAvailable(true);
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 7e2488f..e8bf89a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
@@ -35,7 +35,6 @@
 import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
 import com.android.settingslib.drawable.CircleFramedDrawable;
 import com.android.systemui.R;
-import com.android.systemui.communal.CommunalStateController;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.plugins.FalsingManager;
@@ -119,7 +118,6 @@
             @Main Resources resources,
             ScreenLifecycle screenLifecycle,
             UserSwitcherController userSwitcherController,
-            CommunalStateController communalStateController,
             KeyguardStateController keyguardStateController,
             FalsingManager falsingManager,
             ConfigurationController configurationController,
@@ -138,10 +136,9 @@
         mFalsingManager = falsingManager;
         mConfigurationController = configurationController;
         mStatusBarStateController = statusBarStateController;
-        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
+        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
                 keyguardStateController, dozeParameters,
-                screenOffAnimationController,  /* animateYPos= */ false,
-                /* visibleOnCommunal= */ false);
+                screenOffAnimationController,  /* animateYPos= */ false);
         mUserSwitchDialogController = userSwitchDialogController;
         mUiEventLogger = uiEventLogger;
     }
@@ -270,7 +267,7 @@
             drawable = new CircleFramedDrawable(mCurrentUser.picture, avatarSize);
         }
 
-        Drawable bg = mContext.getDrawable(R.drawable.kg_bg_avatar);
+        Drawable bg = mContext.getDrawable(R.drawable.user_avatar_bg);
         drawable = new LayerDrawable(new Drawable[]{bg, drawable});
         return drawable;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
index 04a6a11..03ab888 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
@@ -42,7 +42,6 @@
 import com.android.settingslib.drawable.CircleFramedDrawable;
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
-import com.android.systemui.communal.CommunalStateController;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -158,7 +157,6 @@
             LayoutInflater layoutInflater,
             ScreenLifecycle screenLifecycle,
             UserSwitcherController userSwitcherController,
-            CommunalStateController communalStateController,
             KeyguardStateController keyguardStateController,
             SysuiStatusBarStateController statusBarStateController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -174,10 +172,9 @@
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mAdapter = new KeyguardUserAdapter(mContext, resources, layoutInflater,
                 mUserSwitcherController, this);
-        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController,
+        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
                 keyguardStateController, dozeParameters,
-                screenOffAnimationController, /* animateYPos= */ false,
-                /* visibleOnCommunal= */ false);
+                screenOffAnimationController, /* animateYPos= */ false);
         mBackground = new KeyguardUserSwitcherScrim(context);
     }
 
@@ -543,7 +540,7 @@
             }
             drawable.setTint(mResources.getColor(iconColorRes, mContext.getTheme()));
 
-            Drawable bg = mContext.getDrawable(R.drawable.kg_bg_avatar);
+            Drawable bg = mContext.getDrawable(R.drawable.user_avatar_bg);
             drawable = new LayerDrawable(new Drawable[]{bg, drawable});
             return drawable;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 48949f92..4d6d05f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -22,8 +22,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.app.ActivityManager;
 import android.app.Notification;
-import android.app.PendingIntent;
-import android.app.RemoteInput;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
@@ -75,7 +73,6 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry.EditedSuggestionInfo;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.LightBarController;
@@ -111,21 +108,15 @@
     private ProgressBar mProgressBar;
     private ImageView mDelete;
     private ImageView mDeleteBg;
-    // TODO(b/193539698): remove reveal param fields, turn them into parameters where needed
-    private int mRevealCx;
-    private int mRevealCy;
-    private int mRevealR;
     private boolean mColorized;
     private int mTint;
     private boolean mResetting;
+    @Nullable private RevealParams mRevealParams;
 
     // TODO(b/193539698): move these to a Controller
     private RemoteInputController mController;
     private final UiEventLogger mUiEventLogger;
     private NotificationEntry mEntry;
-    private PendingIntent mPendingIntent;
-    private RemoteInput mRemoteInput;
-    private RemoteInput[] mRemoteInputs;
     private boolean mRemoved;
     private NotificationViewWrapper mWrapper;
 
@@ -397,9 +388,8 @@
         // During removal, we get reattached and lose focus. Not hiding in that
         // case to prevent flicker.
         if (!mRemoved) {
-            if (animate && mRevealR > 0) {
-                Animator reveal = ViewAnimationUtils.createCircularReveal(
-                        this, mRevealCx, mRevealCy, mRevealR, 0);
+            if (animate && mRevealParams != null && mRevealParams.radius > 0) {
+                Animator reveal = mRevealParams.createCircularHideAnimator(this);
                 reveal.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
                 reveal.setDuration(StackStateAnimator.ANIMATION_DURATION_CLOSE_REMOTE_INPUT);
                 reveal.addListener(new AnimatorListenerAdapter() {
@@ -454,30 +444,12 @@
         mController.removeSpinning(mEntry.getKey(), mToken);
     }
 
-    public void setPendingIntent(PendingIntent pendingIntent) {
-        mPendingIntent = pendingIntent;
+    public void setHintText(CharSequence hintText) {
+        mEditText.setHint(hintText);
     }
 
-    /**
-     * Sets the remote input for this view.
-     *
-     * @param remoteInputs The remote inputs that need to be sent to the app.
-     * @param remoteInput The remote input that needs to be activated.
-     * @param editedSuggestionInfo The smart reply that should be inserted in the remote input, or
-     *         {@code null} if the user is not editing a smart reply.
-     */
-    public void setRemoteInput(RemoteInput[] remoteInputs, RemoteInput remoteInput,
-            @Nullable EditedSuggestionInfo editedSuggestionInfo) {
-        mRemoteInputs = remoteInputs;
-        mRemoteInput = remoteInput;
-        mEditText.setHint(mRemoteInput.getLabel());
-        mEditText.setSupportedMimeTypes(remoteInput.getAllowedDataTypes());
-
-        mEntry.editedSuggestionInfo = editedSuggestionInfo;
-        if (editedSuggestionInfo != null) {
-            mEntry.remoteInputText = editedSuggestionInfo.originalText;
-            mEntry.remoteInputAttachment = null;
-        }
+    public void setSupportedMimeTypes(Collection<String> mimeTypes) {
+        mEditText.setSupportedMimeTypes(mimeTypes);
     }
 
     /** Populates the text field of the remote input with the given content. */
@@ -486,9 +458,8 @@
     }
 
     public void focusAnimated() {
-        if (getVisibility() != VISIBLE) {
-            Animator animator = ViewAnimationUtils.createCircularReveal(
-                    this, mRevealCx, mRevealCy, 0, mRevealR);
+        if (getVisibility() != VISIBLE && mRevealParams != null) {
+            Animator animator = mRevealParams.createCircularRevealAnimator(this);
             animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
             animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
             animator.start();
@@ -587,30 +558,12 @@
         return mEditText.isFocused() && mEditText.isEnabled();
     }
 
-    // TODO(b/193539698): move this to the controller
-    public void stealFocusFrom(RemoteInputView other) {
-        other.close();
-        setPendingIntent(other.mPendingIntent);
-        setRemoteInput(other.mRemoteInputs, other.mRemoteInput, mEntry.editedSuggestionInfo);
-        setRevealParameters(other.mRevealCx, other.mRevealCy, other.mRevealR);
-        getController().setPendingIntent(other.mPendingIntent);
-        getController().setRemoteInput(other.mRemoteInput);
-        getController().setRemoteInputs(other.mRemoteInputs);
-        focus();
-    }
-
-    public PendingIntent getPendingIntent() {
-        return mPendingIntent;
-    }
-
     public void setRemoved() {
         mRemoved = true;
     }
 
-    public void setRevealParameters(int cx, int cy, int r) {
-        mRevealCx = cx;
-        mRevealCy = cy;
-        mRevealR = r;
+    public void setRevealParameters(@Nullable RevealParams revealParams) {
+        mRevealParams = revealParams;
     }
 
     @Override
@@ -938,4 +891,24 @@
         }
 
     }
+
+    public static class RevealParams {
+        final int centerX;
+        final int centerY;
+        final int radius;
+
+        public RevealParams(int centerX, int centerY, int radius) {
+            this.centerX = centerX;
+            this.centerY = centerY;
+            this.radius = radius;
+        }
+
+        Animator createCircularRevealAnimator(View view) {
+            return ViewAnimationUtils.createCircularReveal(view, centerX, centerY, radius, 0);
+        }
+
+        Animator createCircularHideAnimator(View view) {
+            return ViewAnimationUtils.createCircularReveal(view, centerX, centerY, 0, radius);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
index ef0a5b4..bd87875 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
@@ -33,7 +33,9 @@
 import com.android.systemui.statusbar.NotificationRemoteInputManager
 import com.android.systemui.statusbar.RemoteInputController
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntry.EditedSuggestionInfo
 import com.android.systemui.statusbar.policy.RemoteInputView.NotificationRemoteInputEvent
+import com.android.systemui.statusbar.policy.RemoteInputView.RevealParams
 import com.android.systemui.statusbar.policy.dagger.RemoteInputViewScope
 import javax.inject.Inject
 
@@ -41,6 +43,8 @@
     fun bind()
     fun unbind()
 
+    val isActive: Boolean
+
     /**
      * A [NotificationRemoteInputManager.BouncerChecker] that will be used to determine if the
      * device needs to be unlocked before sending the RemoteInput.
@@ -55,6 +59,14 @@
     /** Other [RemoteInput]s from the notification associated with this Controller. */
     var remoteInputs: Array<RemoteInput>?
 
+    var revealParams: RevealParams?
+
+    /**
+     * Sets the smart reply that should be inserted in the remote input, or `null` if the user is
+     * not editing a smart reply.
+     */
+    fun setEditedSuggestionInfo(info: EditedSuggestionInfo?)
+
     /**
      * Tries to find an action in {@param actions} that matches the current pending intent
      * of this view and updates its state to that of the found action
@@ -68,6 +80,19 @@
 
     /** Unregisters a listener previously registered via [addOnSendRemoteInputListener] */
     fun removeOnSendRemoteInputListener(listener: OnSendRemoteInputListener)
+
+    fun close()
+
+    fun focus()
+
+    fun stealFocusFrom(other: RemoteInputViewController) {
+        other.close()
+        remoteInput = other.remoteInput
+        remoteInputs = other.remoteInputs
+        revealParams = other.revealParams
+        pendingIntent = other.pendingIntent
+        focus()
+    }
 }
 
 /** Listener for send events  */
@@ -100,15 +125,41 @@
 
     private var isBound = false
 
-    override var pendingIntent: PendingIntent? = null
     override var bouncerChecker: NotificationRemoteInputManager.BouncerChecker? = null
+
     override var remoteInput: RemoteInput? = null
+        set(value) {
+            field = value
+            value?.takeIf { isBound }?.let {
+                view.setHintText(it.label)
+                view.setSupportedMimeTypes(it.allowedDataTypes)
+            }
+        }
+
+    override var pendingIntent: PendingIntent? = null
     override var remoteInputs: Array<RemoteInput>? = null
 
+    override var revealParams: RevealParams? = null
+        set(value) {
+            field = value
+            if (isBound) {
+                view.setRevealParameters(value)
+            }
+        }
+
+    override val isActive: Boolean get() = view.isActive
+
     override fun bind() {
         if (isBound) return
         isBound = true
 
+        // TODO: refreshUI method?
+        remoteInput?.let {
+            view.setHintText(it.label)
+            view.setSupportedMimeTypes(it.allowedDataTypes)
+        }
+        view.setRevealParameters(revealParams)
+
         view.addOnEditTextFocusChangedListener(onFocusChangeListener)
         view.addOnSendRemoteInputListener(onSendRemoteInputListener)
     }
@@ -121,6 +172,14 @@
         view.removeOnSendRemoteInputListener(onSendRemoteInputListener)
     }
 
+    override fun setEditedSuggestionInfo(info: EditedSuggestionInfo?) {
+        entry.editedSuggestionInfo = info
+        if (info != null) {
+            entry.remoteInputText = info.originalText
+            entry.remoteInputAttachment = null
+        }
+    }
+
     override fun updatePendingIntentFromActions(actions: Array<Notification.Action>?): Boolean {
         actions ?: return false
         val current: Intent = pendingIntent?.intent ?: return false
@@ -132,8 +191,7 @@
             pendingIntent = actionIntent
             remoteInput = input
             remoteInputs = inputs
-            view.pendingIntent = actionIntent
-            view.setRemoteInput(inputs, input, null /* editedSuggestionInfo */)
+            setEditedSuggestionInfo(null)
             return true
         }
         return false
@@ -148,6 +206,14 @@
         onSendListeners.remove(listener)
     }
 
+    override fun close() {
+        view.close()
+    }
+
+    override fun focus() {
+        view.focus()
+    }
+
     private val onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
         remoteInputQuickSettingsDisabler.setRemoteInputActive(hasFocus)
     }
@@ -217,11 +283,12 @@
      * @return returns intent with granted URI permissions that should be used immediately
      */
     private fun prepareRemoteInput(remoteInput: RemoteInput): Intent =
-            if (entry.remoteInputAttachment == null) prepareRemoteInputFromText(remoteInput)
-            else prepareRemoteInputFromData(
-                    remoteInput,
-                    entry.remoteInputMimeType,
-                    entry.remoteInputUri)
+        if (entry.remoteInputAttachment == null)
+            prepareRemoteInputFromText(remoteInput)
+        else prepareRemoteInputFromData(
+                remoteInput,
+                entry.remoteInputMimeType,
+                entry.remoteInputUri)
 
     private fun prepareRemoteInputFromText(remoteInput: RemoteInput): Intent {
         val results = Bundle()
@@ -232,11 +299,10 @@
         view.clearAttachment()
         entry.remoteInputUri = null
         entry.remoteInputMimeType = null
-        if (entry.editedSuggestionInfo == null) {
-            RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_FREE_FORM_INPUT)
-        } else {
-            RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_CHOICE)
-        }
+        val resultSource = entry.editedSuggestionInfo
+                ?.let { RemoteInput.SOURCE_FREE_FORM_INPUT }
+                ?: RemoteInput.SOURCE_CHOICE
+        RemoteInput.setResultsSource(fillInIntent, resultSource)
         return fillInIntent
     }
 
@@ -266,11 +332,10 @@
         entry.remoteInputText = fullText
 
         // mirror prepareRemoteInputFromText for text input
-        if (entry.editedSuggestionInfo == null) {
-            RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_FREE_FORM_INPUT)
-        } else if (entry.remoteInputAttachment == null) {
-            RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_CHOICE)
-        }
+        val resultSource = entry.editedSuggestionInfo
+                ?.let { RemoteInput.SOURCE_FREE_FORM_INPUT }
+                ?: RemoteInput.SOURCE_CHOICE
+        RemoteInput.setResultsSource(fillInIntent, resultSource)
         return fillInIntent
     }
 }
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 ddc9076..763f041 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -67,6 +67,7 @@
 import com.android.systemui.SystemUISecondaryUserService;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -122,6 +123,7 @@
     protected final Handler mHandler;
     private final ActivityStarter mActivityStarter;
     private final BroadcastDispatcher mBroadcastDispatcher;
+    private final BroadcastSender mBroadcastSender;
     private final TelephonyListenerManager mTelephonyListenerManager;
     private final InteractionJankMonitor mInteractionJankMonitor;
     private final LatencyTracker mLatencyTracker;
@@ -165,6 +167,7 @@
             @Main Handler handler,
             ActivityStarter activityStarter,
             BroadcastDispatcher broadcastDispatcher,
+            BroadcastSender broadcastSender,
             UiEventLogger uiEventLogger,
             FalsingManager falsingManager,
             TelephonyListenerManager telephonyListenerManager,
@@ -179,6 +182,7 @@
         mActivityManager = activityManager;
         mUserTracker = userTracker;
         mBroadcastDispatcher = broadcastDispatcher;
+        mBroadcastSender = broadcastSender;
         mTelephonyListenerManager = telephonyListenerManager;
         mUiEventLogger = uiEventLogger;
         mFalsingManager = falsingManager;
@@ -982,9 +986,9 @@
         protected static Drawable getIconDrawable(Context context, UserRecord item) {
             int iconRes;
             if (item.isAddUser) {
-                iconRes = R.drawable.ic_account_circle;
-            } else if (item.isGuest) {
                 iconRes = R.drawable.ic_account_circle_filled;
+            } else if (item.isGuest) {
+                iconRes = R.drawable.ic_account_circle;
             } else if (item.isAddSupervisedUser) {
                 iconRes = R.drawable.ic_add_supervised_user;
             } else {
@@ -1194,7 +1198,7 @@
                 }
                 // Use broadcast instead of ShadeController, as this dialog may have started in
                 // another process and normal dagger bindings are not available
-                getContext().sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+                mBroadcastSender.closeSystemDialogs();
                 getContext().startActivityAsUser(
                         CreateUserActivity.createIntentForStart(getContext()),
                         mUserTracker.getUserHandle());
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java b/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java
index 89ab23b..117cba7 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java
@@ -18,7 +18,6 @@
 
 import com.android.systemui.dagger.GlobalModule;
 import com.android.systemui.dagger.GlobalRootComponent;
-import com.android.systemui.dagger.WMModule;
 
 import javax.inject.Singleton;
 
@@ -28,11 +27,7 @@
  * Root component for Dagger injection.
  */
 @Singleton
-@Component(modules = {
-        GlobalModule.class,
-        TvSysUIComponentModule.class,
-        WMModule.class
-})
+@Component(modules = {GlobalModule.class})
 public interface TvGlobalRootComponent extends GlobalRootComponent {
     /**
      * Component Builder interface. This allows to bind Context instance in the component
@@ -42,9 +37,6 @@
         TvGlobalRootComponent build();
     }
 
-    /**
-     * Builder for a WMComponent.
-     */
     @Override
     TvWMComponent.Builder getWMComponentBuilder();
 
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponentModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponentModule.java
deleted file mode 100644
index 9621e5f..0000000
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponentModule.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.tv;
-
-import dagger.Module;
-
-/**
- * Dagger module for including the SysUIComponent.
- */
-@Module(subcomponents = {TvSysUIComponent.class})
-public abstract class TvSysUIComponentModule {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index 71d8e33..7e3bce5 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -199,10 +199,13 @@
     /**
      * Gets the {@link R.dimen#split_shade_header_height}.
      *
-     * Currently, it's the same as {@link com.android.internal.R.dimen#quick_qs_offset_height}.
+     * It should be fine to not ignore cutouts as split shade might not want to react to them:
+     * for split shade header, which is only on bigger screens, either cutout won't be a problem
+     * (it's usually centered and in split shade that's likely empty area) or we probably want to
+     * handle it differently.
      */
     public static int getSplitShadeStatusBarHeight(Context context) {
-        return SystemBarUtils.getQuickQsOffsetHeight(context);
+        return context.getResources().getDimensionPixelSize(R.dimen.split_shade_header_height);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
index e8a9bc7..8f61abc 100644
--- a/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
@@ -25,10 +25,8 @@
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.LongRunning;
 import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.UiBackground;
 
 import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
 
 import dagger.Module;
 import dagger.Provides;
@@ -149,18 +147,6 @@
         return new RepeatableExecutorImpl(exec);
     }
 
-    /**
-     * Provide an Executor specifically for running UI operations on a separate thread.
-     *
-     * Keep submitted runnables short and to the point, just as with any other UI code.
-     */
-    @Provides
-    @SysUISingleton
-    @UiBackground
-    public static Executor provideUiBackgroundExecutor() {
-        return Executors.newSingleThreadExecutor();
-    }
-
     /** */
     @Provides
     @Main
diff --git a/packages/SystemUI/src/com/android/systemui/util/service/PackageObserver.java b/packages/SystemUI/src/com/android/systemui/util/service/PackageObserver.java
index 2ee7b20..0d47d73 100644
--- a/packages/SystemUI/src/com/android/systemui/util/service/PackageObserver.java
+++ b/packages/SystemUI/src/com/android/systemui/util/service/PackageObserver.java
@@ -24,8 +24,6 @@
 import android.os.PatternMatcher;
 import android.util.Log;
 
-import com.android.systemui.communal.CommunalSource;
-
 import com.google.android.collect.Lists;
 
 import java.lang.ref.WeakReference;
@@ -36,8 +34,8 @@
 
 /**
  * {@link PackageObserver} allows for monitoring the system for changes relating to a particular
- * package. This can be used by {@link CommunalSource} clients to detect when a related package
- * has changed and reloading is necessary.
+ * package. This can be used by clients to detect when a related package has changed and reloading
+ * is necessary.
  */
 public class PackageObserver implements Observer {
     private static final String TAG = "PackageObserver";
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index 69ebfe8..8a96194 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -749,6 +749,8 @@
             return;
         }
 
+        entry.setFlagBubble(shouldBubble);
+
         // Update the state in NotificationManagerService
         try {
             int flags = Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index c3c3f90..60567c4 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -51,6 +51,7 @@
 import com.android.systemui.shared.tracing.ProtoTraceable;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.tracing.ProtoTracer;
 import com.android.systemui.tracing.nano.SystemUiTraceProto;
@@ -116,6 +117,7 @@
 
     private final CommandQueue mCommandQueue;
     private final ConfigurationController mConfigurationController;
+    private final KeyguardStateController mKeyguardStateController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final NavigationModeController mNavigationModeController;
     private final ScreenLifecycle mScreenLifecycle;
@@ -129,7 +131,7 @@
     private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback;
     private KeyguardUpdateMonitorCallback mPipKeyguardCallback;
     private KeyguardUpdateMonitorCallback mOneHandedKeyguardCallback;
-    private KeyguardUpdateMonitorCallback mCompatUIKeyguardCallback;
+    private KeyguardStateController.Callback mCompatUIKeyguardCallback;
     private WakefulnessLifecycle.Observer mWakefulnessObserver;
 
     @Inject
@@ -143,6 +145,7 @@
             Optional<DragAndDrop> dragAndDropOptional,
             CommandQueue commandQueue,
             ConfigurationController configurationController,
+            KeyguardStateController keyguardStateController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             NavigationModeController navigationModeController,
             ScreenLifecycle screenLifecycle,
@@ -154,6 +157,7 @@
         super(context);
         mCommandQueue = commandQueue;
         mConfigurationController = configurationController;
+        mKeyguardStateController = keyguardStateController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mNavigationModeController = navigationModeController;
         mScreenLifecycle = screenLifecycle;
@@ -362,13 +366,13 @@
 
     @VisibleForTesting
     void initCompatUi(CompatUI sizeCompatUI) {
-        mCompatUIKeyguardCallback = new KeyguardUpdateMonitorCallback() {
+        mCompatUIKeyguardCallback = new KeyguardStateController.Callback() {
             @Override
-            public void onKeyguardOccludedChanged(boolean occluded) {
-                sizeCompatUI.onKeyguardOccludedChanged(occluded);
+            public void onKeyguardShowingChanged() {
+                sizeCompatUI.onKeyguardShowingChanged(mKeyguardStateController.isShowing());
             }
         };
-        mKeyguardUpdateMonitor.registerCallback(mCompatUIKeyguardCallback);
+        mKeyguardStateController.addCallback(mCompatUIKeyguardCallback);
     }
 
     void initDragAndDrop(DragAndDrop dragAndDrop) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index 217092e..1753157 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -22,7 +22,6 @@
 import android.testing.AndroidTestingRunner;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.communal.CommunalStateController;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
@@ -50,8 +49,6 @@
     @Mock
     private KeyguardStateController mKeyguardStateController;
     @Mock
-    private CommunalStateController mCommunalStateController;
-    @Mock
     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @Mock
     ConfigurationController mConfigurationController;
@@ -76,7 +73,6 @@
                 mKeyguardClockSwitchController,
                 mKeyguardStateController,
                 mKeyguardUpdateMonitor,
-                mCommunalStateController,
                 mConfigurationController,
                 mDozeParameters,
                 mKeyguardUnlockAnimationController,
@@ -116,4 +112,13 @@
         mKeyguardUpdateMonitorCallbackCaptor.getValue().onUserSwitchComplete(0);
         verify(mKeyguardClockSwitchController).refreshFormat();
     }
+
+    @Test
+    public void setTranslationYExcludingMedia_forwardsCallToView() {
+        float translationY = 123f;
+
+        mController.setTranslationYExcludingMedia(translationY);
+
+        verify(mKeyguardStatusView).setChildrenTranslationYExcludingMediaView(translationY);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
new file mode 100644
index 0000000..ce44f4d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
@@ -0,0 +1,55 @@
+package com.android.keyguard
+
+import android.test.suitebuilder.annotation.SmallTest
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.children
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+class KeyguardStatusViewTest : SysuiTestCase() {
+
+    private lateinit var keyguardStatusView: KeyguardStatusView
+    private val mediaView: View
+        get() = keyguardStatusView.findViewById(R.id.status_view_media_container)
+    private val statusViewContainer: ViewGroup
+        get() = keyguardStatusView.findViewById(R.id.status_view_container)
+    private val childrenExcludingMedia
+        get() = statusViewContainer.children.filter { it != mediaView }
+
+    @Before
+    fun setUp() {
+        keyguardStatusView = LayoutInflater.from(context)
+                .inflate(R.layout.keyguard_status_view, /* root= */ null) as KeyguardStatusView
+    }
+
+    @Test
+    fun setChildrenTranslationYExcludingMediaView_mediaViewIsNotTranslated() {
+        val translationY = 1234f
+
+        keyguardStatusView.setChildrenTranslationYExcludingMediaView(translationY)
+
+        assertThat(mediaView.translationY).isEqualTo(0)
+    }
+
+    @Test
+    fun setChildrenTranslationYExcludingMediaView_childrenAreTranslated() {
+        val translationY = 1234f
+
+        keyguardStatusView.setChildrenTranslationYExcludingMediaView(translationY)
+
+        childrenExcludingMedia.forEach {
+            assertThat(it.translationY).isEqualTo(translationY)
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardVisibilityHelperTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardVisibilityHelperTest.java
deleted file mode 100644
index a93a15d..0000000
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardVisibilityHelperTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.keyguard;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.test.suitebuilder.annotation.SmallTest;
-import android.view.View;
-import android.view.ViewPropertyAnimator;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.communal.CommunalStateController;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-public class KeyguardVisibilityHelperTest extends SysuiTestCase {
-    @Mock
-    private CommunalStateController mCommunalStateController;
-    @Mock
-    private KeyguardStateController mKeyguardStateController;
-    @Mock
-    com.android.systemui.statusbar.phone.DozeParameters mDozeParameters;
-    @Mock
-    ScreenOffAnimationController mScreenOffAnimationController;
-    @Mock
-    ViewPropertyAnimator mViewPropertyAnimator;
-    @Mock
-    View mTargetView;
-
-    private KeyguardVisibilityHelper mKeyguardVisibilityHelper;
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        when(mTargetView.animate()).thenReturn(mViewPropertyAnimator);
-        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mTargetView,
-                mCommunalStateController, mKeyguardStateController, mDozeParameters,
-                mScreenOffAnimationController, false, false);
-    }
-
-    @Test
-    public void testHideOnCommunal() {
-        // Verify view is hidden when communal is visible.
-        when(mCommunalStateController.getCommunalViewShowing()).thenReturn(true);
-        mKeyguardVisibilityHelper.setViewVisibility(StatusBarState.KEYGUARD, false,
-                false, StatusBarState.KEYGUARD);
-        verify(mTargetView).setVisibility(View.GONE);
-        verify(mTargetView).setAlpha(1.0f);
-
-        // Verify view is shown when communal is not visible.
-        when(mCommunalStateController.getCommunalViewShowing()).thenReturn(false);
-        mKeyguardVisibilityHelper.setViewVisibility(StatusBarState.KEYGUARD, false,
-                false, StatusBarState.KEYGUARD);
-        verify(mTargetView).setVisibility(View.VISIBLE);
-    }
-
-    @Test
-    public void testVisibleOnCommunal() {
-        when(mCommunalStateController.getCommunalViewShowing()).thenReturn(true);
-        when(mKeyguardStateController.isOccluded()).thenReturn(false);
-
-        // Verify that helpers constructed with visibility on communal are not hidden when communal
-        // is present.
-        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mTargetView,
-                mCommunalStateController, mKeyguardStateController, mDozeParameters,
-                mScreenOffAnimationController, false, true);
-        mKeyguardVisibilityHelper.setViewVisibility(StatusBarState.KEYGUARD, false,
-                false, StatusBarState.KEYGUARD);
-        verify(mTargetView).setVisibility(View.VISIBLE);
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewBoundAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewBoundAnimatorTest.kt
new file mode 100644
index 0000000..214fd4d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewBoundAnimatorTest.kt
@@ -0,0 +1,277 @@
+package com.android.systemui.animation
+
+import android.animation.ObjectAnimator
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.View
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertNotNull
+import junit.framework.Assert.assertNull
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class ViewBoundAnimatorTest : SysuiTestCase() {
+    companion object {
+        private const val TEST_DURATION = 1000L
+        private val TEST_INTERPOLATOR = Interpolators.LINEAR
+    }
+
+    private lateinit var rootView: LinearLayout
+
+    @Before
+    fun setUp() {
+        rootView = LinearLayout(mContext)
+    }
+
+    @After
+    fun tearDown() {
+        ViewBoundAnimator.stopAnimating(rootView)
+    }
+
+    @Test
+    fun respectsAnimationParameters() {
+        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+
+        ViewBoundAnimator.animate(
+            rootView, interpolator = TEST_INTERPOLATOR, duration = TEST_DURATION
+        )
+        rootView.layout(0 /* l */, 0 /* t */, 100 /* r */, 100 /* b */)
+
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        val animator = rootView.getTag(R.id.tag_animator) as ObjectAnimator
+        assertEquals(animator.interpolator, TEST_INTERPOLATOR)
+        assertEquals(animator.duration, TEST_DURATION)
+    }
+
+    @Test
+    fun animatesFromStartToEnd() {
+        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+
+        ViewBoundAnimator.animate(rootView)
+        // Change all bounds.
+        rootView.layout(0 /* l */, 15 /* t */, 70 /* r */, 80 /* b */)
+
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        // The initial values should be those of the previous layout.
+        checkBounds(rootView, l = 10, t = 10, r = 50, b = 50)
+        endAnimation(rootView)
+        assertNull(rootView.getTag(R.id.tag_animator))
+        // The end values should be those of the latest layout.
+        checkBounds(rootView, l = 0, t = 15, r = 70, b = 80)
+    }
+
+    @Test
+    fun animatesSuccessiveLayoutChanges() {
+        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+
+        ViewBoundAnimator.animate(rootView)
+        // Change all bounds.
+        rootView.layout(0 /* l */, 15 /* t */, 70 /* r */, 80 /* b */)
+
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        endAnimation(rootView)
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 0, t = 15, r = 70, b = 80)
+
+        // Change only top and right.
+        rootView.layout(0 /* l */, 20 /* t */, 60 /* r */, 80 /* b */)
+
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        endAnimation(rootView)
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 0, t = 20, r = 60, b = 80)
+
+        // Change all bounds again.
+        rootView.layout(5 /* l */, 25 /* t */, 55 /* r */, 95 /* b */)
+
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        endAnimation(rootView)
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 5, t = 25, r = 55, b = 95)
+    }
+
+    @Test
+    fun animatesFromPreviousAnimationProgress() {
+        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+
+        ViewBoundAnimator.animateNextUpdate(rootView, interpolator = TEST_INTERPOLATOR)
+        // Change all bounds.
+        rootView.layout(0 /* l */, 20 /* t */, 70 /* r */, 80 /* b */)
+
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        advanceAnimation(rootView, fraction = 0.5f)
+        checkBounds(rootView, l = 5, t = 15, r = 60, b = 65)
+
+        // Change all bounds again.
+        rootView.layout(25 /* l */, 25 /* t */, 55 /* r */, 60 /* b */)
+
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 5, t = 15, r = 60, b = 65)
+        endAnimation(rootView)
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 25, t = 25, r = 55, b = 60)
+    }
+
+    @Test
+    fun animatesRootAndChildren() {
+        val firstChild = View(mContext)
+        rootView.addView(firstChild)
+        val secondChild = View(mContext)
+        rootView.addView(secondChild)
+        rootView.layout(0 /* l */, 0 /* t */, 150 /* r */, 100 /* b */)
+        firstChild.layout(0 /* l */, 0 /* t */, 100 /* r */, 100 /* b */)
+        secondChild.layout(100 /* l */, 0 /* t */, 150 /* r */, 100 /* b */)
+
+        ViewBoundAnimator.animate(rootView)
+        // Change all bounds.
+        rootView.layout(10 /* l */, 20 /* t */, 200 /* r */, 120 /* b */)
+        firstChild.layout(10 /* l */, 20 /* t */, 150 /* r */, 120 /* b */)
+        secondChild.layout(150 /* l */, 20 /* t */, 200 /* r */, 120 /* b */)
+
+        assertNotNull(rootView.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 = 100, b = 100)
+        checkBounds(secondChild, l = 100, t = 0, r = 150, b = 100)
+        endAnimation(rootView)
+        assertNull(rootView.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 = 10, t = 20, r = 150, b = 120)
+        checkBounds(secondChild, l = 150, t = 20, r = 200, b = 120)
+    }
+
+    @Test
+    fun doesNotAnimateInvisibleViews() {
+        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+
+        ViewBoundAnimator.animate(rootView)
+        // GONE.
+        rootView.visibility = View.GONE
+        rootView.layout(0 /* l */, 15 /* t */, 55 /* r */, 80 /* b */)
+
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 0, t = 15, r = 55, b = 80)
+
+        // INVISIBLE.
+        rootView.visibility = View.INVISIBLE
+        rootView.layout(0 /* l */, 20 /* t */, 0 /* r */, 20 /* b */)
+    }
+
+    @Test
+    fun doesNotAnimateUnchangingBounds() {
+        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+
+        ViewBoundAnimator.animate(rootView)
+        // No bounds are changed.
+        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 10, t = 10, r = 50, b = 50)
+
+        // Change only right and bottom.
+        rootView.layout(10 /* l */, 10 /* t */, 70 /* r */, 80 /* b */)
+
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        endAnimation(rootView)
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 10, t = 10, r = 70, b = 80)
+    }
+
+    @Test
+    fun doesNotAnimateExcludedBounds() {
+        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+
+        ViewBoundAnimator.animate(
+            rootView,
+            bounds = setOf(ViewBoundAnimator.Bound.LEFT, ViewBoundAnimator.Bound.TOP),
+            interpolator = TEST_INTERPOLATOR
+        )
+        // Change all bounds.
+        rootView.layout(0 /* l */, 20 /* t */, 70 /* r */, 80 /* b */)
+
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        advanceAnimation(rootView, 0.5f)
+        checkBounds(rootView, l = 5, t = 15, r = 70, b = 80)
+        endAnimation(rootView)
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 0, t = 20, r = 70, b = 80)
+    }
+
+    @Test
+    fun stopsAnimatingAfterSingleLayout() {
+        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+
+        ViewBoundAnimator.animateNextUpdate(rootView)
+        // Change all bounds.
+        rootView.layout(0 /* l */, 15 /* t */, 70 /* r */, 80 /* b */)
+
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        endAnimation(rootView)
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 0, t = 15, r = 70, b = 80)
+
+        // Change all bounds again.
+        rootView.layout(10 /* l */, 10 /* t */, 50/* r */, 50 /* b */)
+
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 10, t = 10, r = 50, b = 50)
+    }
+
+    @Test
+    fun stopsAnimatingWhenInstructed() {
+        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+
+        ViewBoundAnimator.animate(rootView)
+        // Change all bounds.
+        rootView.layout(0 /* l */, 15 /* t */, 70 /* r */, 80 /* b */)
+
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        endAnimation(rootView)
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 0, t = 15, r = 70, b = 80)
+
+        ViewBoundAnimator.stopAnimating(rootView)
+        // Change all bounds again.
+        rootView.layout(10 /* l */, 10 /* t */, 50/* r */, 50 /* b */)
+
+        assertNull(rootView.getTag(R.id.tag_animator))
+        checkBounds(rootView, l = 10, t = 10, r = 50, b = 50)
+    }
+
+    private fun checkBounds(v: View, l: Int, t: Int, r: Int, b: Int) {
+        assertEquals(l, v.left)
+        assertEquals(t, v.top)
+        assertEquals(r, v.right)
+        assertEquals(b, v.bottom)
+    }
+
+    private fun advanceAnimation(rootView: View, fraction: Float) {
+        (rootView.getTag(R.id.tag_animator) as? ObjectAnimator)?.setCurrentFraction(fraction)
+
+        if (rootView is ViewGroup) {
+            for (i in 0 until rootView.childCount) {
+                advanceAnimation(rootView.getChildAt(i), fraction)
+            }
+        }
+    }
+
+    private fun endAnimation(rootView: View) {
+        (rootView.getTag(R.id.tag_animator) as? ObjectAnimator)?.end()
+
+        if (rootView is ViewGroup) {
+            for (i in 0 until rootView.childCount) {
+                endAnimation(rootView.getChildAt(i))
+            }
+        }
+    }
+}
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 1856fda..613931f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -48,6 +48,7 @@
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
 
@@ -64,8 +65,8 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.SystemUIDialogManager;
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
@@ -188,6 +189,7 @@
     @Captor private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor;
     private IUdfpsOverlayController mOverlayController;
     @Captor private ArgumentCaptor<UdfpsView.OnTouchListener> mTouchListenerCaptor;
+    @Captor private ArgumentCaptor<View.OnHoverListener> mHoverListenerCaptor;
     @Captor private ArgumentCaptor<Runnable> mOnIlluminatedRunnableCaptor;
     @Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
     private ScreenLifecycle.Observer mScreenObserver;
@@ -568,23 +570,24 @@
     }
 
     @Test
-    public void playHapticOnTouchUdfpsArea() throws RemoteException {
+    public void playHapticOnTouchUdfpsArea_a11yTouchExplorationEnabled() throws RemoteException {
         // Configure UdfpsView to accept the ACTION_DOWN event
         when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
         when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
 
-        // GIVEN that the overlay is showing
+        // GIVEN that the overlay is showing and a11y touch exploration enabled
+        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
         mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
                 BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
         mFgExecutor.runAllReady();
 
-        // WHEN ACTION_DOWN is received
-        verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
-        MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
-        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
-        downEvent.recycle();
-        MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
-        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+        // WHEN ACTION_HOVER is received
+        verify(mUdfpsView).setOnHoverListener(mHoverListenerCaptor.capture());
+        MotionEvent enterEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_ENTER, 0, 0, 0);
+        mHoverListenerCaptor.getValue().onHover(mUdfpsView, enterEvent);
+        enterEvent.recycle();
+        MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_MOVE, 0, 0, 0);
+        mHoverListenerCaptor.getValue().onHover(mUdfpsView, moveEvent);
         moveEvent.recycle();
 
         // THEN tick haptic is played
@@ -600,4 +603,34 @@
         assertEquals(VibrationAttributes.USAGE_COMMUNICATION_REQUEST,
                 UdfpsController.VIBRATION_ATTRIBUTES.getUsage());
     }
+
+    @Test
+    public void noHapticOnTouchUdfpsArea_a11yTouchExplorationDisabled() throws RemoteException {
+        // Configure UdfpsView to accept the ACTION_DOWN event
+        when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
+        when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
+
+        // GIVEN that the overlay is showing and a11y touch exploration NOT enabled
+        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
+        mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
+                BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
+        mFgExecutor.runAllReady();
+
+        // WHEN ACTION_DOWN is received
+        verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
+        MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
+        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
+        downEvent.recycle();
+        MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
+        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+        moveEvent.recycle();
+
+        // THEN NO haptic played
+        verify(mVibrator, never()).vibrate(
+                anyInt(),
+                anyString(),
+                any(),
+                anyString(),
+                any());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt
new file mode 100644
index 0000000..fbd2c91
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt
@@ -0,0 +1,145 @@
+/*
+ * 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.broadcast
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.os.UserHandle
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.util.wakelock.WakeLockFake
+import com.google.common.truth.Truth.assertThat
+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.verify
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class BroadcastSenderTest : SysuiTestCase() {
+
+    @Mock
+    private lateinit var mockContext: Context
+
+    private lateinit var broadcastSender: BroadcastSender
+    private lateinit var executor: FakeExecutor
+    private lateinit var wakeLock: WakeLockFake
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        executor = FakeExecutor(FakeSystemClock())
+        wakeLock = WakeLockFake()
+        val wakeLockBuilder = WakeLockFake.Builder(mContext)
+        wakeLockBuilder.setWakeLock(wakeLock)
+        broadcastSender = BroadcastSender(mockContext, wakeLockBuilder, executor)
+    }
+
+    @Test
+    fun sendBroadcast_dispatchesWithWakelock() {
+        val intent = Intent(Intent.ACTION_VIEW)
+        broadcastSender.sendBroadcast(intent)
+
+        runExecutorAssertingWakelock {
+            verify(mockContext).sendBroadcast(intent)
+        }
+    }
+
+    @Test
+    fun sendBroadcastWithPermission_dispatchesWithWakelock() {
+        val intent = Intent(Intent.ACTION_VIEW)
+        val permission = "Permission"
+        broadcastSender.sendBroadcast(intent, permission)
+
+        runExecutorAssertingWakelock {
+            verify(mockContext).sendBroadcast(intent, permission)
+        }
+    }
+
+    @Test
+    fun sendBroadcastAsUser_dispatchesWithWakelock() {
+        val intent = Intent(Intent.ACTION_VIEW)
+        broadcastSender.sendBroadcastAsUser(intent, UserHandle.ALL)
+
+        runExecutorAssertingWakelock {
+            verify(mockContext).sendBroadcastAsUser(intent, UserHandle.ALL)
+        }
+    }
+
+    @Test
+    fun sendBroadcastAsUserWithPermission_dispatchesWithWakelock() {
+        val intent = Intent(Intent.ACTION_VIEW)
+        val permission = "Permission"
+        broadcastSender.sendBroadcastAsUser(intent, UserHandle.ALL, permission)
+
+        runExecutorAssertingWakelock {
+            verify(mockContext).sendBroadcastAsUser(intent, UserHandle.ALL, permission)
+        }
+    }
+
+    @Test
+    fun sendBroadcastAsUserWithPermissionAndOptions_dispatchesWithWakelock() {
+        val intent = Intent(Intent.ACTION_VIEW)
+        val permission = "Permission"
+        val options = Bundle()
+        options.putString("key", "value")
+
+        broadcastSender.sendBroadcastAsUser(intent, UserHandle.ALL, permission, options)
+
+        runExecutorAssertingWakelock {
+            verify(mockContext).sendBroadcastAsUser(intent, UserHandle.ALL, permission, options)
+        }
+    }
+
+    @Test
+    fun sendBroadcastAsUserWithPermissionAndAppOp_dispatchesWithWakelock() {
+        val intent = Intent(Intent.ACTION_VIEW)
+        val permission = "Permission"
+
+        broadcastSender.sendBroadcastAsUser(intent, UserHandle.ALL, permission, 12)
+
+        runExecutorAssertingWakelock {
+            verify(mockContext).sendBroadcastAsUser(intent, UserHandle.ALL, permission, 12)
+        }
+    }
+
+    @Test
+    fun sendCloseSystemDialogs_dispatchesWithWakelock() {
+        val intentCaptor = ArgumentCaptor.forClass(Intent::class.java)
+
+        broadcastSender.closeSystemDialogs()
+
+        runExecutorAssertingWakelock {
+            verify(mockContext).sendBroadcast(intentCaptor.capture())
+            assertThat(intentCaptor.value.action).isEqualTo(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
+        }
+    }
+
+    private fun runExecutorAssertingWakelock(verification: () -> Unit) {
+        assertThat(wakeLock.isHeld).isTrue()
+        executor.runAllReady()
+        verification.invoke()
+        assertThat(wakeLock.isHeld).isFalse()
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewControllerTest.java
deleted file mode 100644
index 8bd5e79..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewControllerTest.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.testing.AndroidTestingRunner;
-import android.view.View;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-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.lang.ref.WeakReference;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class CommunalHostViewControllerTest extends SysuiTestCase {
-    @Mock
-    private CommunalStateController mCommunalStateController;
-
-    @Mock
-    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-
-    @Mock
-    private KeyguardStateController mKeyguardStateController;
-
-    @Mock
-    private StatusBarStateController mStatusBarStateController;
-
-    @Mock
-    private CommunalHostView mCommunalView;
-
-    @Mock
-    private DozeParameters mDozeParameters;
-
-    @Mock
-    private ScreenOffAnimationController mScreenOffAnimationController;
-
-    private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
-
-    private CommunalHostViewController mController;
-
-    @Mock
-    private CommunalSource mCommunalSource;
-
-    @Mock
-    private View mChildView;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mKeyguardStateController.isShowing()).thenReturn(true);
-        when(mCommunalView.isAttachedToWindow()).thenReturn(true);
-        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
-
-        mController = new CommunalHostViewController(mFakeExecutor, mCommunalStateController,
-                mKeyguardUpdateMonitor, mKeyguardStateController, mDozeParameters,
-                mScreenOffAnimationController, mStatusBarStateController, mCommunalView);
-        mController.init();
-        mFakeExecutor.runAllReady();
-
-        Mockito.clearInvocations(mCommunalView);
-    }
-
-    @Test
-    public void testShow() {
-        ArgumentCaptor<KeyguardStateController.Callback> callbackCapture =
-                ArgumentCaptor.forClass(KeyguardStateController.Callback.class);
-
-        // Capture callback value for later use.
-        verify(mKeyguardStateController).addCallback(callbackCapture.capture());
-
-        // Verify the communal view is shown when the controller is initialized with keyguard
-        // showing (see setup).
-        mController.show(new WeakReference<>(mCommunalSource));
-        mFakeExecutor.runAllReady();
-        verify(mCommunalView).setVisibility(View.VISIBLE);
-
-        // Trigger keyguard off to ensure visibility of communal view is changed accordingly.
-        when(mKeyguardStateController.isShowing()).thenReturn(false);
-        callbackCapture.getValue().onKeyguardShowingChanged();
-        mFakeExecutor.runAllReady();
-        verify(mCommunalView).setVisibility(View.INVISIBLE);
-    }
-
-    @Test
-    public void testHideOnOcclude() {
-        ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCapture =
-                ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
-
-        // Capture callback value for later use.
-        verify(mKeyguardUpdateMonitor).registerCallback(callbackCapture.capture());
-
-        // Establish a visible communal view.
-        mController.show(new WeakReference<>(mCommunalSource));
-        mFakeExecutor.runAllReady();
-        verify(mCommunalView).setVisibility(View.VISIBLE);
-        Mockito.clearInvocations(mCommunalView);
-
-        // Occlude.
-        Mockito.clearInvocations(mCommunalView);
-        callbackCapture.getValue().onKeyguardOccludedChanged(true);
-        mFakeExecutor.runAllReady();
-        verify(mCommunalView).setVisibility(View.INVISIBLE);
-
-        // Unocclude.
-        Mockito.clearInvocations(mCommunalView);
-        callbackCapture.getValue().onKeyguardOccludedChanged(false);
-        mFakeExecutor.runAllReady();
-        verify(mCommunalView).setVisibility(View.VISIBLE);
-    }
-
-    @Test
-    public void testReportOcclusion() {
-        // Ensure CommunalHostViewController reports view occluded when either the QS or Shade is
-        // expanded.
-        clearInvocations(mCommunalStateController);
-        mController.updateShadeExpansion(0);
-        verify(mCommunalStateController).setCommunalViewOccluded(false);
-        clearInvocations(mCommunalStateController);
-        mController.updateQsExpansion(.5f);
-        verify(mCommunalStateController).setCommunalViewOccluded(true);
-        clearInvocations(mCommunalStateController);
-        mController.updateShadeExpansion(.7f);
-        verify(mCommunalStateController).setCommunalViewOccluded(true);
-        clearInvocations(mCommunalStateController);
-        mController.updateShadeExpansion(0);
-        verify(mCommunalStateController).setCommunalViewOccluded(true);
-        clearInvocations(mCommunalStateController);
-        mController.updateQsExpansion(0f);
-        verify(mCommunalStateController).setCommunalViewOccluded(false);
-        clearInvocations(mCommunalStateController);
-    }
-
-    @Test
-    public void testCommunalStateControllerHideNotified() {
-        ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCapture =
-                ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
-
-        // Capture callback value for later use.
-        verify(mKeyguardUpdateMonitor).registerCallback(callbackCapture.capture());
-
-        // Establish a visible communal view.
-        mController.show(new WeakReference<>(mCommunalSource));
-        mFakeExecutor.runAllReady();
-
-        // Occlude
-        clearInvocations(mCommunalStateController);
-        callbackCapture.getValue().onKeyguardOccludedChanged(true);
-        mFakeExecutor.runAllReady();
-
-        // Verify state controller is notified communal view is hidden.
-        verify(mCommunalStateController).setCommunalViewShowing(false);
-    }
-
-    @Test
-    public void testAlphaPropagation() {
-        final float alpha = 0.8f;
-
-        // Ensure alpha setting is propagated to children.
-        when(mCommunalView.getChildCount()).thenReturn(1);
-        when(mCommunalView.getChildAt(0)).thenReturn(mChildView);
-        mController.setAlpha(alpha);
-        verify(mChildView).setAlpha(alpha);
-        verify(mCommunalView).setAlpha(alpha);
-    }
-
-    @Test
-    public void testMultipleShowRequestSuppression() {
-        // Ensure first request invokes source.
-        mController.show(new WeakReference<>(mCommunalSource));
-        mFakeExecutor.runAllReady();
-        verify(mCommunalSource).requestCommunalView(any());
-        clearInvocations(mCommunalSource);
-
-        // Ensure subsequent identical request is suppressed
-        mController.show(new WeakReference<>(mCommunalSource));
-        mFakeExecutor.runAllReady();
-        verify(mCommunalSource, never()).requestCommunalView(any());
-    }
-
-    @Test
-    public void testNoShowInvocationOnBouncer() {
-        ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCapture =
-                ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
-
-        // Capture callback value for later use.
-        verify(mKeyguardUpdateMonitor).registerCallback(callbackCapture.capture());
-
-        // Set source so it will be cleared if in invalid state.
-        mController.show(new WeakReference<>(mCommunalSource));
-        mFakeExecutor.runAllReady();
-        clearInvocations(mCommunalStateController, mCommunalView);
-
-        // Change bouncer to showing.
-        callbackCapture.getValue().onKeyguardBouncerChanged(true);
-        mFakeExecutor.runAllReady();
-
-        // Verify that there were no requests to remove all child views or set the communal
-        // state to not showing.
-        verify(mCommunalStateController, never()).setCommunalViewShowing(eq(false));
-        verify(mCommunalView, never()).removeAllViews();
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithmTest.java
deleted file mode 100644
index 0a0266b..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewPositionAlgorithmTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.communal.CommunalHostViewPositionAlgorithm.Result;
-
-import org.junit.Test;
-
-
-@SmallTest
-public class CommunalHostViewPositionAlgorithmTest extends SysuiTestCase {
-    @Test
-    public void testOutput() {
-        final float expansion = 0.25f;
-        final int height = 120;
-
-        final CommunalHostViewPositionAlgorithm algorithm = new CommunalHostViewPositionAlgorithm();
-        algorithm.setup(expansion, height);
-        final Result result = new Result();
-        algorithm.run(result);
-
-        // Verify the communal view is shifted offscreen vertically by the correct amount.
-        assertThat((1 - expansion) * -height).isEqualTo(result.communalY);
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSettingConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSettingConditionTest.java
deleted file mode 100644
index c5b1a1d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSettingConditionTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.os.Looper;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.communal.conditions.CommunalSettingCondition;
-import com.android.systemui.util.condition.Condition;
-import com.android.systemui.util.settings.FakeSettings;
-import com.android.systemui.utils.os.FakeHandler;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class CommunalSettingConditionTest extends SysuiTestCase {
-    private FakeSettings mSecureSettings;
-    private CommunalSettingCondition mCondition;
-
-    @Before
-    public void setup() {
-        final FakeHandler handler = new FakeHandler(Looper.getMainLooper());
-        mSecureSettings = new FakeSettings();
-        mCondition = new CommunalSettingCondition(handler, mSecureSettings);
-    }
-
-    @Test
-    public void addCallback_communalSettingEnabled_immediatelyReportsTrue() {
-        updateCommunalSetting(true);
-
-        final Condition.Callback callback = mock(Condition.Callback.class);
-        mCondition.addCallback(callback);
-        verify(callback).onConditionChanged(mCondition);
-        assertThat(mCondition.isConditionMet()).isTrue();
-    }
-
-    @Test
-    public void addCallback_communalSettingDisabled_noReport() {
-        updateCommunalSetting(false);
-
-        final Condition.Callback callback = mock(Condition.Callback.class);
-        mCondition.addCallback(callback);
-        verify(callback, never()).onConditionChanged(eq(mCondition));
-    }
-
-    @Test
-    public void updateCallback_communalSettingEnabled_reportsTrue() {
-        updateCommunalSetting(false);
-
-        final Condition.Callback callback = mock(Condition.Callback.class);
-        mCondition.addCallback(callback);
-        clearInvocations(callback);
-
-        updateCommunalSetting(true);
-        verify(callback).onConditionChanged(mCondition);
-        assertThat(mCondition.isConditionMet()).isTrue();
-    }
-
-    @Test
-    public void updateCallback_communalSettingDisabled_reportsFalse() {
-        updateCommunalSetting(true);
-
-        final Condition.Callback callback = mock(Condition.Callback.class);
-        mCondition.addCallback(callback);
-        clearInvocations(callback);
-
-        updateCommunalSetting(false);
-        verify(callback).onConditionChanged(mCondition);
-        assertThat(mCondition.isConditionMet()).isFalse();
-    }
-
-    @Test
-    public void updateCallback_communalSettingDidNotChange_neverReportDup() {
-        updateCommunalSetting(true);
-
-        final Condition.Callback callback = mock(Condition.Callback.class);
-        mCondition.addCallback(callback);
-        clearInvocations(callback);
-
-        updateCommunalSetting(true);
-        verify(callback, never()).onConditionChanged(mCondition);
-        assertThat(mCondition.isConditionMet()).isTrue();
-    }
-
-    private void updateCommunalSetting(boolean value) {
-        mSecureSettings.putIntForUser(Settings.Secure.COMMUNAL_MODE_ENABLED, value ? 1 : 0,
-                UserHandle.USER_SYSTEM);
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourceMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourceMonitorTest.java
deleted file mode 100644
index df1cc76..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourceMonitorTest.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.condition.Monitor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.lang.ref.WeakReference;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class CommunalSourceMonitorTest extends SysuiTestCase {
-    @Mock private Monitor mCommunalConditionsMonitor;
-
-    @Captor private ArgumentCaptor<Monitor.Callback> mConditionsCallbackCaptor;
-
-    private CommunalSourceMonitor mCommunalSourceMonitor;
-    private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mCommunalSourceMonitor = new CommunalSourceMonitor(mExecutor, mCommunalConditionsMonitor);
-    }
-
-    @Test
-    public void testSourceAddedBeforeCallbackAdded() {
-        final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
-        final CommunalSource source = mock(CommunalSource.class);
-
-        setSource(source);
-        mCommunalSourceMonitor.addCallback(callback);
-        setConditionsMet(true);
-
-        verifyOnSourceAvailableCalledWith(callback, source);
-    }
-
-    @Test
-    public void testRemoveCallback() {
-        final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
-        final CommunalSource source = mock(CommunalSource.class);
-
-        mCommunalSourceMonitor.addCallback(callback);
-        mCommunalSourceMonitor.removeCallback(callback);
-        setSource(source);
-
-        verify(callback, never()).onSourceAvailable(any());
-    }
-
-    @Test
-    public void testAddCallbackWithConditionsMet() {
-        final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
-        final CommunalSource source = mock(CommunalSource.class);
-
-        mCommunalSourceMonitor.addCallback(callback);
-        setConditionsMet(true);
-        clearInvocations(callback);
-        setSource(source);
-
-        verifyOnSourceAvailableCalledWith(callback, source);
-    }
-
-    @Test
-    public void testAddCallbackWithConditionsNotMet() {
-        final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
-        final CommunalSource source = mock(CommunalSource.class);
-
-        mCommunalSourceMonitor.addCallback(callback);
-        setConditionsMet(false);
-        setSource(source);
-
-        verify(callback, never()).onSourceAvailable(any());
-    }
-
-    @Test
-    public void testConditionsAreMetAfterCallbackAdded() {
-        final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
-        final CommunalSource source = mock(CommunalSource.class);
-
-        mCommunalSourceMonitor.addCallback(callback);
-        setSource(source);
-
-        // The callback should not have executed since communal is disabled.
-        verify(callback, never()).onSourceAvailable(any());
-
-        // The callback should execute when all conditions are met.
-        setConditionsMet(true);
-        verifyOnSourceAvailableCalledWith(callback, source);
-    }
-
-    @Test
-    public void testConditionsNoLongerMetAfterCallbackAdded() {
-        final CommunalSourceMonitor.Callback callback = mock(CommunalSourceMonitor.Callback.class);
-        final CommunalSource source = mock(CommunalSource.class);
-
-        mCommunalSourceMonitor.addCallback(callback);
-        setSource(source);
-        setConditionsMet(true);
-        verifyOnSourceAvailableCalledWith(callback, source);
-
-        // The callback should execute again when conditions are no longer met, with a value of
-        // null.
-        setConditionsMet(false);
-        verify(callback).onSourceAvailable(null);
-    }
-
-    private void verifyOnSourceAvailableCalledWith(CommunalSourceMonitor.Callback callback,
-            CommunalSource source) {
-        final ArgumentCaptor<WeakReference<CommunalSource>> sourceCapture =
-                ArgumentCaptor.forClass(WeakReference.class);
-        verify(callback).onSourceAvailable(sourceCapture.capture());
-        assertThat(sourceCapture.getValue().get()).isEqualTo(source);
-    }
-
-    // Pushes an update on whether the communal conditions are met, assuming that a callback has
-    // been registered with the communal conditions monitor.
-    private void setConditionsMet(boolean value) {
-        mExecutor.runAllReady();
-        verify(mCommunalConditionsMonitor).addCallback(mConditionsCallbackCaptor.capture());
-        final Monitor.Callback conditionsCallback =
-                mConditionsCallbackCaptor.getValue();
-        conditionsCallback.onConditionsChanged(value);
-        mExecutor.runAllReady();
-    }
-
-    private void setSource(CommunalSource source) {
-        mCommunalSourceMonitor.setSource(source);
-        mExecutor.runAllReady();
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourcePrimerTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourcePrimerTest.java
deleted file mode 100644
index 1d9a059..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalSourcePrimerTest.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.util.concurrency.FakeExecutor;;
-import com.android.systemui.util.ref.GcWeakReference;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import com.google.common.util.concurrent.ListenableFuture;
-
-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;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class CommunalSourcePrimerTest extends SysuiTestCase {
-    private static final String TEST_COMPONENT_NAME = "com.google.tests/.CommunalService";
-    private static final int MAX_RETRIES = 5;
-    private static final int RETRY_DELAY_MS = 1000;
-    private static final int CONNECTION_MIN_DURATION_MS = 5000;
-
-    // A simple implementation of {@link CommunalSource.Observer} to capture a callback value.
-    // Used to ensure the references to a {@link CommunalSource.Observer.Callback} can be fully
-    // removed.
-    private static class FakeObserver implements CommunalSource.Observer {
-        public GcWeakReference<Callback> mLastCallback;
-
-        @Override
-        public void addCallback(Callback callback) {
-            mLastCallback = new GcWeakReference<>(callback);
-        }
-
-        @Override
-        public void removeCallback(Callback callback) {
-            if (mLastCallback.get() == callback) {
-                mLastCallback = null;
-            }
-        }
-    }
-
-    // A simple implementation of {@link CommunalSource} to capture callback values. This
-    // implementation better emulates the {@link WeakReference} wrapping behavior of
-    // {@link CommunalSource} implementations than a mock.
-    private static class FakeSource implements CommunalSource {
-        @Override
-        public ListenableFuture<CommunalViewResult> requestCommunalView(Context context) {
-            return null;
-        }
-    }
-
-    @Mock
-    private Context mContext;
-
-    @Mock
-    private Resources mResources;
-
-    private FakeSystemClock mFakeClock = new FakeSystemClock();
-    private FakeExecutor mFakeExecutor = new FakeExecutor(mFakeClock);
-
-    private FakeSource mSource = new FakeSource();
-
-    @Mock
-    private CommunalSourceMonitor mCommunalSourceMonitor;
-
-    @Mock
-    private CommunalSource.Connector mConnector;
-
-    @Mock
-    private CommunalSource.Connection mConnection;
-
-    private FakeObserver mObserver = new FakeObserver();
-
-    private CommunalSourcePrimer mPrimer;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        when(mResources.getInteger(R.integer.config_communalSourceMaxReconnectAttempts))
-                .thenReturn(MAX_RETRIES);
-        when(mResources.getInteger(R.integer.config_communalSourceReconnectBaseDelay))
-                .thenReturn(RETRY_DELAY_MS);
-        when(mResources.getInteger(R.integer.config_communalSourceReconnectBaseDelay))
-                .thenReturn(RETRY_DELAY_MS);
-        when(mResources.getString(R.string.config_communalSourceComponent))
-                .thenReturn(TEST_COMPONENT_NAME);
-        when(mResources.getInteger(R.integer.config_connectionMinDuration))
-                .thenReturn(CONNECTION_MIN_DURATION_MS);
-
-        mPrimer = new CommunalSourcePrimer(mContext, mResources, mFakeClock, mFakeExecutor,
-                mCommunalSourceMonitor, Optional.of(mConnector), Optional.of(mObserver));
-    }
-
-    private CommunalSource.Connection.Callback captureCallbackAndSend(
-            CommunalSource.Connector connector, Optional<CommunalSource> source) {
-        ArgumentCaptor<CommunalSource.Connection.Callback> connectionCallback =
-                ArgumentCaptor.forClass(CommunalSource.Connection.Callback.class);
-
-        verify(connector).connect(connectionCallback.capture());
-        Mockito.clearInvocations(connector);
-
-        final CommunalSource.Connection.Callback callback = connectionCallback.getValue();
-        callback.onSourceEstablished(source);
-
-        return callback;
-    }
-
-    @Test
-    public void testConnect() {
-        mPrimer.onBootCompleted();
-        captureCallbackAndSend(mConnector, Optional.of(mSource));
-        verify(mCommunalSourceMonitor).setSource(mSource);
-    }
-
-    @Test
-    public void testRetryOnBindFailure() throws Exception {
-        mPrimer.onBootCompleted();
-
-        // Verify attempts happen. Note that we account for the retries plus initial attempt, which
-        // is not scheduled.
-        for (int attemptCount = 0; attemptCount < MAX_RETRIES + 1; attemptCount++) {
-            captureCallbackAndSend(mConnector, Optional.empty());
-            mFakeExecutor.advanceClockToNext();
-            mFakeExecutor.runAllReady();
-        }
-
-        verify(mCommunalSourceMonitor, never()).setSource(Mockito.notNull());
-    }
-
-    @Test
-    public void testRetryOnDisconnectFailure() throws Exception {
-        mPrimer.onBootCompleted();
-        // Verify attempts happen. Note that we account for the retries plus initial attempt, which
-        // is not scheduled.
-        for (int attemptCount = 0; attemptCount < MAX_RETRIES + 1; attemptCount++) {
-            final CommunalSource.Connection.Callback callback =
-                    captureCallbackAndSend(mConnector, Optional.of(mSource));
-            verify(mCommunalSourceMonitor).setSource(Mockito.notNull());
-            clearInvocations(mCommunalSourceMonitor);
-            callback.onDisconnected();
-            mFakeExecutor.advanceClockToNext();
-            mFakeExecutor.runAllReady();
-        }
-
-        verify(mConnector, never()).connect(any());
-    }
-
-    @Test
-    public void testAttemptOnPackageChange() {
-        mPrimer.onBootCompleted();
-        captureCallbackAndSend(mConnector, Optional.empty());
-
-        mObserver.mLastCallback.get().onSourceChanged();
-
-        verify(mConnector, times(1)).connect(any());
-    }
-
-    @Test
-    public void testDisconnect() {
-        mPrimer.onBootCompleted();
-        final CommunalSource.Connection.Callback callback =
-                captureCallbackAndSend(mConnector, Optional.of(mSource));
-        verify(mCommunalSourceMonitor).setSource(mSource);
-
-        mFakeClock.advanceTime(CONNECTION_MIN_DURATION_MS + 1);
-        callback.onDisconnected();
-
-        verify(mConnector).connect(any());
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalStateControllerTest.java
deleted file mode 100644
index 7f85c35..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalStateControllerTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class CommunalStateControllerTest extends SysuiTestCase {
-    @Mock
-    private CommunalStateController.Callback mCallback;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    @Test
-    public void testDefaultCommunalViewShowingState() {
-        // The state controller should report the communal view as not showing by default.
-        final CommunalStateController stateController = new CommunalStateController();
-        assertThat(stateController.getCommunalViewShowing()).isFalse();
-    }
-
-    @Test
-    public void testNotifyCommunalSurfaceShow() {
-        final CommunalStateController stateController = new CommunalStateController();
-        stateController.addCallback(mCallback);
-
-        // Verify setting communal view to showing propagates to callback.
-        stateController.setCommunalViewShowing(true);
-        verify(mCallback).onCommunalViewShowingChanged();
-        assertThat(stateController.getCommunalViewShowing()).isTrue();
-
-        clearInvocations(mCallback);
-
-        // Verify setting communal view to not showing propagates to callback.
-        stateController.setCommunalViewShowing(false);
-        verify(mCallback).onCommunalViewShowingChanged();
-        assertThat(stateController.getCommunalViewShowing()).isFalse();
-    }
-
-    @Test
-    public void testCallbackRegistration() {
-        final CommunalStateController stateController = new CommunalStateController();
-        stateController.addCallback(mCallback);
-
-        // Verify setting communal view to showing propagates to callback.
-        stateController.setCommunalViewShowing(true);
-        verify(mCallback).onCommunalViewShowingChanged();
-
-        clearInvocations(mCallback);
-
-        stateController.removeCallback(mCallback);
-        clearInvocations(mCallback);
-
-        // Verify callback not invoked after removing from state controller.
-        stateController.setCommunalViewShowing(false);
-        verify(mCallback, never()).onCommunalViewShowingChanged();
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/PackageObserverTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/PackageObserverTest.java
deleted file mode 100644
index 1cd6069..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/PackageObserverTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.verify;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class PackageObserverTest extends SysuiTestCase {
-    private static final String PACKAGE_NAME = "com.foo.bar";
-
-    @Mock
-    Context mContext;
-
-    @Mock
-    CommunalSource.Observer.Callback mCallback;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    @Test
-    public void testChange() {
-        final PackageObserver observer = new PackageObserver(mContext, PACKAGE_NAME);
-        final ArgumentCaptor<BroadcastReceiver> receiverCapture =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-
-        observer.addCallback(mCallback);
-
-        // Verify broadcast receiver registered.
-        verify(mContext).registerReceiver(receiverCapture.capture(), any(), anyInt());
-
-        // Simulate package change.
-        receiverCapture.getValue().onReceive(mContext, new Intent());
-
-        // Check that callback was informed.
-        verify(mCallback).onSourceChanged();
-
-        observer.removeCallback(mCallback);
-
-        // Make sure receiver is unregistered on last callback removal
-        verify(mContext).unregisterReceiver(receiverCapture.getValue());
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
index da25c62..49eaf823 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
@@ -23,6 +23,7 @@
 import android.test.suitebuilder.annotation.SmallTest
 import android.testing.AndroidTestingRunner
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.controls.ControlsMetricsLogger
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.statusbar.VibratorHelper
@@ -62,6 +63,8 @@
     @Mock
     private lateinit var activityStarter: ActivityStarter
     @Mock
+    private lateinit var broadcastSender: BroadcastSender
+    @Mock
     private lateinit var taskViewFactory: Optional<TaskViewFactory>
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private lateinit var cvh: ControlViewHolder
@@ -94,6 +97,7 @@
                 bgExecutor,
                 uiExecutor,
                 activityStarter,
+                broadcastSender,
                 keyguardStateController,
                 taskViewFactory,
                 metricsLogger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
index 87b9172..0166fa2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
@@ -21,6 +21,7 @@
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastSender
 import com.android.wm.shell.TaskView
 import org.junit.Before
 import org.junit.Test
@@ -39,6 +40,8 @@
     @Mock
     private lateinit var taskView: TaskView
     @Mock
+    private lateinit var broadcastSender: BroadcastSender
+    @Mock
     private lateinit var controlViewHolder: ControlViewHolder
     @Mock
     private lateinit var pendingIntent: PendingIntent
@@ -63,6 +66,7 @@
     private fun createDialog(pendingIntent: PendingIntent): DetailDialog {
         return DetailDialog(
             mContext,
+            broadcastSender,
             taskView,
             pendingIntent,
             controlViewHolder
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index badafa4..f4b378e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -27,6 +27,7 @@
 import static com.android.systemui.doze.DozeMachine.State.FINISH;
 import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
 import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotSame;
@@ -468,37 +469,39 @@
     public void transitionToDoze_shouldClampBrightness_afterTimeout_clampsToDim() {
         when(mWakefulnessLifecycle.getLastSleepReason()).thenReturn(
                 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
-        when(mDozeParameters.shouldControlUnlockedScreenOff()).thenReturn(true);
         when(mDozeParameters.shouldClampToDimBrightness()).thenReturn(true);
 
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
-        mScreen.transitionTo(INITIALIZED, DOZE);
 
         // If we're dozing after a timeout, and playing the unlocked screen animation, we should
         // stay at or below dim brightness, because the screen dims just before timeout.
         assertTrue(mServiceFake.screenBrightness <= DIM_BRIGHTNESS);
+
+        // Once we transition to Doze, use the doze brightness
+        mScreen.transitionTo(INITIALIZED, DOZE);
+        assertEquals(mServiceFake.screenBrightness, DEFAULT_BRIGHTNESS);
     }
 
     @Test
     public void transitionToDoze_shouldClampBrightness_notAfterTimeout_doesNotClampToDim() {
         when(mWakefulnessLifecycle.getLastSleepReason()).thenReturn(
                 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON);
-        when(mDozeParameters.shouldControlUnlockedScreenOff()).thenReturn(true);
         when(mDozeParameters.shouldClampToDimBrightness()).thenReturn(true);
 
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
-        mScreen.transitionTo(INITIALIZED, DOZE);
 
         // If we're playing the unlocked screen off animation after a power button press, we should
         // leave the brightness alone.
         assertEquals(mServiceFake.screenBrightness, DEFAULT_BRIGHTNESS);
+
+        mScreen.transitionTo(INITIALIZED, DOZE);
+        assertEquals(mServiceFake.screenBrightness, DEFAULT_BRIGHTNESS);
     }
 
     @Test
     public void transitionToDoze_noClampBrightness_afterTimeout_noScreenOff_doesNotClampToDim() {
         when(mWakefulnessLifecycle.getLastSleepReason()).thenReturn(
                 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
-        when(mDozeParameters.shouldControlUnlockedScreenOff()).thenReturn(false);
         when(mDozeParameters.shouldClampToDimBrightness()).thenReturn(false);
 
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
@@ -514,11 +517,9 @@
                 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
         when(mWakefulnessLifecycle.getWakefulness()).thenReturn(
                 WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP);
-        when(mDozeParameters.shouldControlUnlockedScreenOff()).thenReturn(false);
         when(mDozeParameters.shouldClampToDimBrightness()).thenReturn(false);
 
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
-        mScreen.transitionTo(INITIALIZED, DOZE);
 
         assertTrue(mServiceFake.screenBrightness <= DIM_BRIGHTNESS);
     }
@@ -529,7 +530,6 @@
                 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON);
         when(mWakefulnessLifecycle.getWakefulness()).thenReturn(
                 WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP);
-        when(mDozeParameters.shouldControlUnlockedScreenOff()).thenReturn(false);
         when(mDozeParameters.shouldClampToDimBrightness()).thenReturn(false);
 
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
index ff9e13a..dcbdea0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.dreams;
 
-import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
@@ -30,7 +29,6 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dreams.complication.ComplicationHostViewController;
 
@@ -44,7 +42,6 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
-    private static final int DREAM_OVERLAY_NOTIFICATIONS_DRAG_AREA_HEIGHT = 100;
     private static final int MAX_BURN_IN_OFFSET = 20;
     private static final long BURN_IN_PROTECTION_UPDATE_INTERVAL = 10;
     private static final long MILLIS_UNTIL_FULL_JITTER = 240 * 1000;
@@ -76,9 +73,6 @@
     public void setup() {
         MockitoAnnotations.initMocks(this);
 
-        when(mResources.getDimensionPixelSize(
-                R.dimen.dream_overlay_notifications_drag_area_height)).thenReturn(
-                        DREAM_OVERLAY_NOTIFICATIONS_DRAG_AREA_HEIGHT);
         when(mDreamOverlayContainerView.getResources()).thenReturn(mResources);
         when(mDreamOverlayContainerView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
 
@@ -100,13 +94,6 @@
     }
 
     @Test
-    public void testSetsDreamOverlayNotificationsDragAreaHeight() {
-        assertEquals(
-                mController.getDreamOverlayNotificationsDragAreaHeight(),
-                DREAM_OVERLAY_NOTIFICATIONS_DRAG_AREA_HEIGHT);
-    }
-
-    @Test
     public void testBurnInProtectionStartsWhenContentViewAttached() {
         mController.onViewAttached();
         verify(mHandler).postDelayed(any(Runnable.class), eq(BURN_IN_PROTECTION_UPDATE_INTERVAL));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
index b3d5459..3657192 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -222,4 +223,25 @@
         verify(mLifecycleRegistry).setCurrentState(Lifecycle.State.DESTROYED);
         verify(mStateController).setOverlayActive(false);
     }
+
+    @Test
+    public void testDecorViewNotAddedToWindowAfterDestroy() throws Exception {
+        when(mDreamOverlayContainerView.getParent())
+                .thenReturn(mDreamOverlayContainerViewParent)
+                .thenReturn(null);
+
+        final IBinder proxy = mService.onBind(new Intent());
+        final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
+
+        // Inform the overlay service of dream starting.
+        overlay.startDream(mWindowParams, mDreamOverlayCallback);
+
+        // Destroy the service.
+        mService.onDestroy();
+
+        // Run executor tasks.
+        mMainExecutor.runAllReady();
+
+        verify(mWindowManager, never()).addView(any(), any());
+    }
 }
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 3b17a80..ed1cf69 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
@@ -15,26 +15,31 @@
  */
 package com.android.systemui.dreams;
 
-import static org.mockito.ArgumentMatchers.any;
 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.app.smartspace.SmartspaceTarget;
 import android.content.Context;
 import android.testing.AndroidTestingRunner;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
+import com.android.systemui.dreams.smartspace.DreamsSmartspaceController;
+import com.android.systemui.plugins.BcSmartspaceDataPlugin;
 
 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.Arrays;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 public class SmartSpaceComplicationTest extends SysuiTestCase {
@@ -42,7 +47,7 @@
     private Context mContext;
 
     @Mock
-    private LockscreenSmartspaceController mSmartspaceController;
+    private DreamsSmartspaceController mSmartspaceController;
 
     @Mock
     private DreamOverlayStateController mDreamOverlayStateController;
@@ -60,7 +65,6 @@
      */
     @Test
     public void testAvailability() {
-        when(mSmartspaceController.isEnabled()).thenReturn(false);
 
         final SmartSpaceComplication.Registrant registrant = new SmartSpaceComplication.Registrant(
                 mContext,
@@ -68,10 +72,22 @@
                 mComplication,
                 mSmartspaceController);
         registrant.start();
-        verify(mDreamOverlayStateController, never()).addComplication(any());
+        verify(mDreamOverlayStateController, never()).addComplication(eq(mComplication));
 
-        when(mSmartspaceController.isEnabled()).thenReturn(true);
-        registrant.start();
+
+        final ArgumentCaptor<DreamOverlayStateController.Callback> dreamCallbackCaptor =
+                ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
+        verify(mDreamOverlayStateController).addCallback(dreamCallbackCaptor.capture());
+
+        when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
+        dreamCallbackCaptor.getValue().onStateChanged();
+
+        final ArgumentCaptor<BcSmartspaceDataPlugin.SmartspaceTargetListener> listenerCaptor =
+                ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
+        verify(mSmartspaceController).addListener(listenerCaptor.capture());
+
+        final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
+        listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
         verify(mDreamOverlayStateController).addComplication(eq(mComplication));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
index 6fead9e..f00fbe6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
@@ -341,6 +341,7 @@
     public void testCreateActionItems_lockdownEnabled_doesShowLockdown() {
         mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
         doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
+        doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayEmergency();
         doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
         doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
         String[] actions = {
@@ -365,8 +366,10 @@
     public void testCreateActionItems_lockdownDisabled_doesNotShowLockdown() {
         mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
         doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
+        doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayEmergency();
         // make sure lockdown action will NOT be shown
         doReturn(false).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
+        doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
         String[] actions = {
                 GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
                 // lockdown action not allowed
@@ -386,6 +389,32 @@
     }
 
     @Test
+    public void testCreateActionItems_emergencyDisabled_doesNotShowEmergency() {
+        mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
+        doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
+        // make sure emergency action will NOT be shown
+        doReturn(false).when(mGlobalActionsDialogLite).shouldDisplayEmergency();
+        doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
+        doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
+        String[] actions = {
+                // emergency action not allowed
+                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
+                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCKDOWN,
+                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_POWER,
+                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_RESTART,
+        };
+        doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
+        mGlobalActionsDialogLite.createActionItems();
+
+        assertItemsOfType(mGlobalActionsDialogLite.mItems,
+                GlobalActionsDialogLite.LockDownAction.class,
+                GlobalActionsDialogLite.ShutDownAction.class,
+                GlobalActionsDialogLite.RestartAction.class);
+        assertThat(mGlobalActionsDialogLite.mOverflowItems).isEmpty();
+        assertThat(mGlobalActionsDialogLite.mPowerItems).isEmpty();
+    }
+
+    @Test
     public void testShouldLogLockdownPress() {
         GlobalActionsDialogLite.LockDownAction lockDownAction =
                 mGlobalActionsDialogLite.new LockDownAction();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
index dcbe0ab..daf81bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
@@ -37,7 +37,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 import javax.inject.Provider
-import org.mockito.Mockito.`when` as whenever
 
 private val DATA = MediaData(
     userId = -1,
@@ -83,7 +82,6 @@
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
-        whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
         mediaCarouselController = MediaCarouselController(
             context,
             mediaControlPanelFactory,
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 708fc91..90eff1a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -40,6 +40,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.media.dialog.MediaOutputDialogFactory
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
@@ -59,6 +60,7 @@
 import org.mockito.Mock
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
@@ -85,6 +87,7 @@
 
     private lateinit var bgExecutor: FakeExecutor
     @Mock private lateinit var activityStarter: ActivityStarter
+    @Mock private lateinit var broadcastSender: BroadcastSender
 
     @Mock private lateinit var holder: PlayerViewHolder
     @Mock private lateinit var sessionHolder: PlayerSessionViewHolder
@@ -98,7 +101,6 @@
     @Mock private lateinit var mediaOutputDialogFactory: MediaOutputDialogFactory
     @Mock private lateinit var mediaCarouselController: MediaCarouselController
     @Mock private lateinit var falsingManager: FalsingManager
-    @Mock private lateinit var mediaFlags: MediaFlags
     private lateinit var appIcon: ImageView
     private lateinit var albumView: ImageView
     private lateinit var titleText: TextView
@@ -119,8 +121,6 @@
     private lateinit var actionPlayPause: ImageButton
     private lateinit var actionNext: ImageButton
     private lateinit var actionPrev: ImageButton
-    private lateinit var actionStart: ImageButton
-    private lateinit var actionEnd: ImageButton
     @Mock private lateinit var longPressText: TextView
     @Mock private lateinit var handler: Handler
     private lateinit var settings: View
@@ -144,9 +144,9 @@
         whenever(mediaViewController.expandedLayout).thenReturn(expandedSet)
         whenever(mediaViewController.collapsedLayout).thenReturn(collapsedSet)
 
-        player = MediaControlPanel(context, bgExecutor, activityStarter, mediaViewController,
-            seekBarViewModel, Lazy { mediaDataManager },
-            mediaOutputDialogFactory, mediaCarouselController, falsingManager, mediaFlags, clock)
+        player = MediaControlPanel(context, bgExecutor, activityStarter, broadcastSender,
+            mediaViewController, seekBarViewModel, Lazy { mediaDataManager },
+            mediaOutputDialogFactory, mediaCarouselController, falsingManager, clock)
         whenever(seekBarViewModel.progress).thenReturn(seekBarData)
 
         // Set up mock views for the players
@@ -168,6 +168,17 @@
         cancelText = TextView(context)
         dismiss = FrameLayout(context)
         dismissText = TextView(context)
+
+        action0 = ImageButton(context).also { it.setId(R.id.action0) }
+        action1 = ImageButton(context).also { it.setId(R.id.action1) }
+        action2 = ImageButton(context).also { it.setId(R.id.action2) }
+        action3 = ImageButton(context).also { it.setId(R.id.action3) }
+        action4 = ImageButton(context).also { it.setId(R.id.action4) }
+
+        actionPlayPause = ImageButton(context).also { it.setId(R.id.actionPlayPause) }
+        actionPrev = ImageButton(context).also { it.setId(R.id.actionPrev) }
+        actionNext = ImageButton(context).also { it.setId(R.id.actionNext) }
+
         initPlayerHolderMocks()
         initSessionHolderMocks()
 
@@ -203,95 +214,66 @@
                 device = device,
                 active = true,
                 resumeAction = null)
+    }
 
-        whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(false)
-        whenever(mediaFlags.useMediaSessionLayout()).thenReturn(false)
+    /**
+     * Initialize elements common to both view holders
+     */
+    private fun initMediaViewHolderMocks(viewHolder: MediaViewHolder) {
+        whenever(viewHolder.player).thenReturn(view)
+        whenever(viewHolder.appIcon).thenReturn(appIcon)
+        whenever(viewHolder.albumView).thenReturn(albumView)
+        whenever(viewHolder.titleText).thenReturn(titleText)
+        whenever(viewHolder.artistText).thenReturn(artistText)
+        whenever(seamlessBackground.getDrawable(0)).thenReturn(mock(GradientDrawable::class.java))
+        whenever(viewHolder.seamless).thenReturn(seamless)
+        whenever(viewHolder.seamlessButton).thenReturn(seamlessButton)
+        whenever(viewHolder.seamlessIcon).thenReturn(seamlessIcon)
+        whenever(viewHolder.seamlessText).thenReturn(seamlessText)
+        whenever(viewHolder.seekBar).thenReturn(seekBar)
+
+        // Action buttons
+        whenever(viewHolder.action0).thenReturn(action0)
+        whenever(viewHolder.getAction(R.id.action0)).thenReturn(action0)
+        whenever(viewHolder.action1).thenReturn(action1)
+        whenever(viewHolder.getAction(R.id.action1)).thenReturn(action1)
+        whenever(viewHolder.action2).thenReturn(action2)
+        whenever(viewHolder.getAction(R.id.action2)).thenReturn(action2)
+        whenever(viewHolder.action3).thenReturn(action3)
+        whenever(viewHolder.getAction(R.id.action3)).thenReturn(action3)
+        whenever(viewHolder.action4).thenReturn(action4)
+        whenever(viewHolder.getAction(R.id.action4)).thenReturn(action4)
+
+        // Long press menu
+        whenever(viewHolder.longPressText).thenReturn(longPressText)
+        whenever(longPressText.handler).thenReturn(handler)
+        whenever(viewHolder.settings).thenReturn(settings)
+        whenever(viewHolder.settingsText).thenReturn(settingsText)
+        whenever(viewHolder.cancel).thenReturn(cancel)
+        whenever(viewHolder.cancelText).thenReturn(cancelText)
+        whenever(viewHolder.dismiss).thenReturn(dismiss)
+        whenever(viewHolder.dismissText).thenReturn(dismissText)
     }
 
     /** Mock view holder for the notification player */
     private fun initPlayerHolderMocks() {
-        whenever(holder.player).thenReturn(view)
-        whenever(holder.appIcon).thenReturn(appIcon)
-        whenever(holder.albumView).thenReturn(albumView)
-        whenever(holder.titleText).thenReturn(titleText)
-        whenever(holder.artistText).thenReturn(artistText)
-        whenever(seamlessBackground.getDrawable(0)).thenReturn(mock(GradientDrawable::class.java))
-        whenever(holder.seamless).thenReturn(seamless)
-        whenever(holder.seamlessButton).thenReturn(seamlessButton)
-        whenever(holder.seamlessIcon).thenReturn(seamlessIcon)
-        whenever(holder.seamlessText).thenReturn(seamlessText)
-        whenever(holder.seekBar).thenReturn(seekBar)
+        initMediaViewHolderMocks(holder)
+
         whenever(holder.elapsedTimeView).thenReturn(elapsedTimeView)
         whenever(holder.totalTimeView).thenReturn(totalTimeView)
-
-        // Action buttons
-        action0 = ImageButton(context)
-        whenever(holder.action0).thenReturn(action0)
-        whenever(holder.getAction(R.id.action0)).thenReturn(action0)
-        action1 = ImageButton(context)
-        whenever(holder.action1).thenReturn(action1)
-        whenever(holder.getAction(R.id.action1)).thenReturn(action1)
-        action2 = ImageButton(context)
-        whenever(holder.action2).thenReturn(action2)
-        whenever(holder.getAction(R.id.action2)).thenReturn(action2)
-        action3 = ImageButton(context)
-        whenever(holder.action3).thenReturn(action3)
-        whenever(holder.getAction(R.id.action3)).thenReturn(action3)
-        action4 = ImageButton(context)
-        whenever(holder.action4).thenReturn(action4)
-        whenever(holder.getAction(R.id.action4)).thenReturn(action4)
-
-        // Long press menu
-        whenever(holder.longPressText).thenReturn(longPressText)
-        whenever(longPressText.handler).thenReturn(handler)
-        whenever(holder.settings).thenReturn(settings)
-        whenever(holder.settingsText).thenReturn(settingsText)
-        whenever(holder.cancel).thenReturn(cancel)
-        whenever(holder.cancelText).thenReturn(cancelText)
-        whenever(holder.dismiss).thenReturn(dismiss)
-        whenever(holder.dismissText).thenReturn(dismissText)
     }
 
     /** Mock view holder for session player */
     private fun initSessionHolderMocks() {
-        whenever(sessionHolder.player).thenReturn(view)
-        whenever(sessionHolder.albumView).thenReturn(albumView)
-        whenever(sessionHolder.appIcon).thenReturn(appIcon)
-        whenever(sessionHolder.titleText).thenReturn(titleText)
-        whenever(sessionHolder.artistText).thenReturn(artistText)
-        val seamlessBackground = mock(RippleDrawable::class.java)
-        whenever(seamlessBackground.getDrawable(0)).thenReturn(mock(GradientDrawable::class.java))
-        whenever(sessionHolder.seamless).thenReturn(seamless)
-        whenever(sessionHolder.seamlessButton).thenReturn(seamlessButton)
-        whenever(sessionHolder.seamlessIcon).thenReturn(seamlessIcon)
-        whenever(sessionHolder.seamlessText).thenReturn(seamlessText)
-        whenever(sessionHolder.seekBar).thenReturn(seekBar)
+        initMediaViewHolderMocks(sessionHolder)
 
-        // Action buttons
-        actionPlayPause = ImageButton(context)
+        // Semantic action buttons
         whenever(sessionHolder.actionPlayPause).thenReturn(actionPlayPause)
         whenever(sessionHolder.getAction(R.id.actionPlayPause)).thenReturn(actionPlayPause)
-        actionNext = ImageButton(context)
         whenever(sessionHolder.actionNext).thenReturn(actionNext)
         whenever(sessionHolder.getAction(R.id.actionNext)).thenReturn(actionNext)
-        actionPrev = ImageButton(context)
         whenever(sessionHolder.actionPrev).thenReturn(actionPrev)
         whenever(sessionHolder.getAction(R.id.actionPrev)).thenReturn(actionPrev)
-        actionStart = ImageButton(context)
-        whenever(sessionHolder.actionStart).thenReturn(actionStart)
-        whenever(sessionHolder.getAction(R.id.actionStart)).thenReturn(actionStart)
-        actionEnd = ImageButton(context)
-        whenever(sessionHolder.actionEnd).thenReturn(actionEnd)
-        whenever(sessionHolder.getAction(R.id.actionEnd)).thenReturn(actionEnd)
-
-        // Long press menu
-        whenever(sessionHolder.longPressText).thenReturn(longPressText)
-        whenever(sessionHolder.settings).thenReturn(settings)
-        whenever(sessionHolder.settingsText).thenReturn(settingsText)
-        whenever(sessionHolder.cancel).thenReturn(cancel)
-        whenever(sessionHolder.cancelText).thenReturn(cancelText)
-        whenever(sessionHolder.dismiss).thenReturn(dismiss)
-        whenever(sessionHolder.dismissText).thenReturn(dismissText)
     }
 
     @After
@@ -309,15 +291,12 @@
 
     @Test
     fun bindSemanticActionsOldLayout() {
-        whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
-        whenever(mediaFlags.useMediaSessionLayout()).thenReturn(false)
-
         val icon = Icon.createWithResource(context, android.R.drawable.ic_media_play)
         val semanticActions = MediaButton(
             playOrPause = MediaAction(icon, Runnable {}, "play"),
             nextOrCustom = MediaAction(icon, Runnable {}, "next"),
-            startCustom = MediaAction(icon, null, "custom 1"),
-            endCustom = MediaAction(icon, null, "custom 2")
+            custom0 = MediaAction(icon, null, "custom 0"),
+            custom1 = MediaAction(icon, null, "custom 1")
         )
         val state = mediaData.copy(semanticActions = semanticActions)
 
@@ -325,7 +304,7 @@
         player.bindPlayer(state, PACKAGE)
 
         verify(expandedSet).setVisibility(R.id.action0, ConstraintSet.VISIBLE)
-        assertThat(action0.contentDescription).isEqualTo("custom 1")
+        assertThat(action0.contentDescription).isEqualTo("custom 0")
         assertThat(action0.isEnabled()).isFalse()
 
         verify(expandedSet).setVisibility(R.id.action1, ConstraintSet.INVISIBLE)
@@ -340,41 +319,103 @@
         assertThat(action3.contentDescription).isEqualTo("next")
 
         verify(expandedSet).setVisibility(R.id.action4, ConstraintSet.VISIBLE)
-        assertThat(action4.contentDescription).isEqualTo("custom 2")
+        assertThat(action4.contentDescription).isEqualTo("custom 1")
         assertThat(action4.isEnabled()).isFalse()
     }
 
     @Test
     fun bindSemanticActionsNewLayout() {
-        whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
-        whenever(mediaFlags.useMediaSessionLayout()).thenReturn(true)
-
         val icon = Icon.createWithResource(context, android.R.drawable.ic_media_play)
         val semanticActions = MediaButton(
                 playOrPause = MediaAction(icon, Runnable {}, "play"),
                 nextOrCustom = MediaAction(icon, Runnable {}, "next"),
-                startCustom = MediaAction(icon, null, "custom 1"),
-                endCustom = MediaAction(icon, null, "custom 2")
+                custom0 = MediaAction(icon, null, "custom 0"),
+                custom1 = MediaAction(icon, null, "custom 1")
         )
         val state = mediaData.copy(semanticActions = semanticActions)
 
         player.attachPlayer(sessionHolder, MediaViewController.TYPE.PLAYER_SESSION)
         player.bindPlayer(state, PACKAGE)
 
-        assertThat(actionStart.contentDescription).isEqualTo("custom 1")
-        assertThat(actionStart.isEnabled()).isFalse()
-
         assertThat(actionPrev.isEnabled()).isFalse()
         assertThat(actionPrev.drawable).isNull()
+        verify(collapsedSet).setVisibility(R.id.actionPrev, ConstraintSet.GONE)
 
         assertThat(actionPlayPause.isEnabled()).isTrue()
         assertThat(actionPlayPause.contentDescription).isEqualTo("play")
+        verify(collapsedSet).setVisibility(R.id.actionPlayPause, ConstraintSet.VISIBLE)
 
         assertThat(actionNext.isEnabled()).isTrue()
         assertThat(actionNext.contentDescription).isEqualTo("next")
+        verify(collapsedSet).setVisibility(R.id.actionNext, ConstraintSet.VISIBLE)
 
-        assertThat(actionEnd.contentDescription).isEqualTo("custom 2")
-        assertThat(actionEnd.isEnabled()).isFalse()
+        // Called twice since these IDs are used as generic buttons
+        assertThat(action0.contentDescription).isEqualTo("custom 0")
+        assertThat(action0.isEnabled()).isFalse()
+        verify(collapsedSet, times(2)).setVisibility(R.id.action0, ConstraintSet.GONE)
+
+        assertThat(action1.contentDescription).isEqualTo("custom 1")
+        assertThat(action1.isEnabled()).isFalse()
+        verify(collapsedSet, times(2)).setVisibility(R.id.action1, ConstraintSet.GONE)
+
+        // Verify generic buttons are hidden
+        verify(collapsedSet).setVisibility(R.id.action2, ConstraintSet.GONE)
+        verify(expandedSet).setVisibility(R.id.action2, ConstraintSet.GONE)
+
+        verify(collapsedSet).setVisibility(R.id.action3, ConstraintSet.GONE)
+        verify(expandedSet).setVisibility(R.id.action3, ConstraintSet.GONE)
+
+        verify(collapsedSet).setVisibility(R.id.action4, ConstraintSet.GONE)
+        verify(expandedSet).setVisibility(R.id.action4, ConstraintSet.GONE)
+    }
+
+    @Test
+    fun bindNotificationActionsNewLayout() {
+        val icon = Icon.createWithResource(context, android.R.drawable.ic_media_play)
+        val actions = listOf(
+            MediaAction(icon, Runnable {}, "previous"),
+            MediaAction(icon, Runnable {}, "play"),
+            MediaAction(icon, null, "next"),
+            MediaAction(icon, null, "custom 0"),
+            MediaAction(icon, Runnable {}, "custom 1")
+        )
+        val state = mediaData.copy(actions = actions,
+            actionsToShowInCompact = listOf(1, 2),
+            semanticActions = null)
+
+        player.attachPlayer(sessionHolder, MediaViewController.TYPE.PLAYER_SESSION)
+        player.bindPlayer(state, PACKAGE)
+
+        // Verify semantic actions are hidden
+        verify(collapsedSet).setVisibility(R.id.actionPrev, ConstraintSet.GONE)
+        verify(expandedSet).setVisibility(R.id.actionPrev, ConstraintSet.GONE)
+
+        verify(collapsedSet).setVisibility(R.id.actionPlayPause, ConstraintSet.GONE)
+        verify(expandedSet).setVisibility(R.id.actionPlayPause, ConstraintSet.GONE)
+
+        verify(collapsedSet).setVisibility(R.id.actionNext, ConstraintSet.GONE)
+        verify(expandedSet).setVisibility(R.id.actionNext, ConstraintSet.GONE)
+
+        // Generic actions all enabled
+        assertThat(action0.contentDescription).isEqualTo("previous")
+        assertThat(action0.isEnabled()).isTrue()
+        verify(collapsedSet).setVisibility(R.id.action0, ConstraintSet.GONE)
+
+        assertThat(action1.contentDescription).isEqualTo("play")
+        assertThat(action1.isEnabled()).isTrue()
+        verify(collapsedSet).setVisibility(R.id.action1, ConstraintSet.VISIBLE)
+
+        assertThat(action2.contentDescription).isEqualTo("next")
+        assertThat(action2.isEnabled()).isFalse()
+        verify(collapsedSet).setVisibility(R.id.action2, ConstraintSet.VISIBLE)
+
+        assertThat(action3.contentDescription).isEqualTo("custom 0")
+        assertThat(action3.isEnabled()).isFalse()
+        verify(collapsedSet).setVisibility(R.id.action3, ConstraintSet.GONE)
+
+        assertThat(action4.contentDescription).isEqualTo("custom 1")
+        assertThat(action4.isEnabled()).isTrue()
+        verify(collapsedSet).setVisibility(R.id.action4, ConstraintSet.GONE)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
index 6b203bc..82a48ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
@@ -23,6 +23,7 @@
 import android.testing.TestableLooper
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
@@ -65,6 +66,8 @@
     @Mock
     private lateinit var broadcastDispatcher: BroadcastDispatcher
     @Mock
+    private lateinit var broadcastSender: BroadcastSender
+    @Mock
     private lateinit var mediaResumeListener: MediaResumeListener
     @Mock
     private lateinit var mediaDataManager: MediaDataManager
@@ -87,7 +90,7 @@
     fun setup() {
         MockitoAnnotations.initMocks(this)
         MediaPlayerData.clear()
-        mediaDataFilter = MediaDataFilter(context, broadcastDispatcher,
+        mediaDataFilter = MediaDataFilter(context, broadcastDispatcher, broadcastSender,
                 lockscreenUserManager, executor, clock)
         mediaDataFilter.mediaDataManager = mediaDataManager
         mediaDataFilter.addListener(listener)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
index 021f70e..be2450d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.statusbar.SbnBuilder
 import com.android.systemui.tuner.TunerService
 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
@@ -37,6 +38,7 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito
@@ -167,7 +169,7 @@
         whenever(mediaSmartspaceTarget.featureType).thenReturn(SmartspaceTarget.FEATURE_MEDIA)
         whenever(mediaSmartspaceTarget.iconGrid).thenReturn(listOf(mediaRecommendationItem))
         whenever(mediaSmartspaceTarget.creationTimeMillis).thenReturn(1234L)
-        whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(false)
+        whenever(mediaFlags.areMediaSessionActionsEnabled(any(), anyInt())).thenReturn(false)
     }
 
     @After
@@ -594,7 +596,7 @@
     @Test
     fun testPlaybackActions_noState_usesNotification() {
         val desc = "Notification Action"
-        whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
+        whenever(mediaFlags.areMediaSessionActionsEnabled(any(), anyInt())).thenReturn(true)
         whenever(controller.playbackState).thenReturn(null)
 
         val notifWithAction = SbnBuilder().run {
@@ -621,7 +623,7 @@
     @Test
     fun testPlaybackActions_hasPrevNext() {
         val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4")
-        whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
+        whenever(mediaFlags.areMediaSessionActionsEnabled(any(), anyInt())).thenReturn(true)
         val stateActions = PlaybackState.ACTION_PLAY or
                 PlaybackState.ACTION_SKIP_TO_PREVIOUS or
                 PlaybackState.ACTION_SKIP_TO_NEXT
@@ -659,17 +661,17 @@
         actions.nextOrCustom!!.action!!.run()
         verify(transportControls).skipToNext()
 
-        assertThat(actions.startCustom).isNotNull()
-        assertThat(actions.startCustom!!.contentDescription).isEqualTo(customDesc[0])
+        assertThat(actions.custom0).isNotNull()
+        assertThat(actions.custom0!!.contentDescription).isEqualTo(customDesc[0])
 
-        assertThat(actions.endCustom).isNotNull()
-        assertThat(actions.endCustom!!.contentDescription).isEqualTo(customDesc[1])
+        assertThat(actions.custom1).isNotNull()
+        assertThat(actions.custom1!!.contentDescription).isEqualTo(customDesc[1])
     }
 
     @Test
     fun testPlaybackActions_noPrevNext_usesCustom() {
         val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4", "custom 5")
-        whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
+        whenever(mediaFlags.areMediaSessionActionsEnabled(any(), anyInt())).thenReturn(true)
         val stateActions = PlaybackState.ACTION_PLAY
         val stateBuilder = PlaybackState.Builder()
                 .setActions(stateActions)
@@ -697,17 +699,17 @@
         assertThat(actions.nextOrCustom).isNotNull()
         assertThat(actions.nextOrCustom!!.contentDescription).isEqualTo(customDesc[1])
 
-        assertThat(actions.startCustom).isNotNull()
-        assertThat(actions.startCustom!!.contentDescription).isEqualTo(customDesc[2])
+        assertThat(actions.custom0).isNotNull()
+        assertThat(actions.custom0!!.contentDescription).isEqualTo(customDesc[2])
 
-        assertThat(actions.endCustom).isNotNull()
-        assertThat(actions.endCustom!!.contentDescription).isEqualTo(customDesc[3])
+        assertThat(actions.custom1).isNotNull()
+        assertThat(actions.custom1!!.contentDescription).isEqualTo(customDesc[3])
     }
 
     @Test
     fun testPlaybackActions_reservedSpace() {
         val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4")
-        whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
+        whenever(mediaFlags.areMediaSessionActionsEnabled(any(), anyInt())).thenReturn(true)
         val stateActions = PlaybackState.ACTION_PLAY
         val stateBuilder = PlaybackState.Builder()
                 .setActions(stateActions)
@@ -737,10 +739,10 @@
         assertThat(actions.prevOrCustom).isNull()
         assertThat(actions.nextOrCustom).isNull()
 
-        assertThat(actions.startCustom).isNotNull()
-        assertThat(actions.startCustom!!.contentDescription).isEqualTo(customDesc[0])
+        assertThat(actions.custom0).isNotNull()
+        assertThat(actions.custom0!!.contentDescription).isEqualTo(customDesc[0])
 
-        assertThat(actions.endCustom).isNotNull()
-        assertThat(actions.endCustom!!.contentDescription).isEqualTo(customDesc[1])
+        assertThat(actions.custom1).isNotNull()
+        assertThat(actions.custom1!!.contentDescription).isEqualTo(customDesc[1])
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
index b359ae5..8e201b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
@@ -117,9 +117,9 @@
                 dreamOverlayStateController)
         verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture())
         verify(statusBarStateController).addCallback(statusBarCallback.capture())
-        setupHost(lockHost, MediaHierarchyManager.LOCATION_LOCKSCREEN)
-        setupHost(qsHost, MediaHierarchyManager.LOCATION_QS)
-        setupHost(qqsHost, MediaHierarchyManager.LOCATION_QQS)
+        setupHost(lockHost, MediaHierarchyManager.LOCATION_LOCKSCREEN, LOCKSCREEN_TOP)
+        setupHost(qsHost, MediaHierarchyManager.LOCATION_QS, QS_TOP)
+        setupHost(qqsHost, MediaHierarchyManager.LOCATION_QQS, QQS_TOP)
         `when`(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
         `when`(mediaCarouselController.mediaCarouselScrollHandler)
                 .thenReturn(mediaCarouselScrollHandler)
@@ -130,9 +130,9 @@
         clearInvocations(mediaCarouselController)
     }
 
-    private fun setupHost(host: MediaHost, location: Int) {
+    private fun setupHost(host: MediaHost, location: Int, top: Int) {
         `when`(host.location).thenReturn(location)
-        `when`(host.currentBounds).thenReturn(Rect())
+        `when`(host.currentBounds).thenReturn(Rect(0, top, 0, top))
         `when`(host.hostView).thenReturn(uniqueObjectHostView)
         `when`(host.visible).thenReturn(true)
         mediaHiearchyManager.register(host)
@@ -257,6 +257,20 @@
         verify(mediaCarouselController).closeGuts()
     }
 
+    @Test
+    fun getGuidedTransformationTranslationY_notInGuidedTransformation_returnsNegativeNumber() {
+        assertThat(mediaHiearchyManager.getGuidedTransformationTranslationY()).isLessThan(0)
+    }
+
+    @Test
+    fun getGuidedTransformationTranslationY_inGuidedTransformation_returnsCurrentTranslation() {
+        enterGuidedTransformation()
+
+        val expectedTranslation = LOCKSCREEN_TOP - QS_TOP
+        assertThat(mediaHiearchyManager.getGuidedTransformationTranslationY())
+                .isEqualTo(expectedTranslation)
+    }
+
     private fun enableSplitShade() {
         context.getOrCreateTestableResources().addOverride(
             R.bool.config_use_split_notification_shade, true
@@ -284,4 +298,16 @@
     private fun expandQS() {
         mediaHiearchyManager.qsExpansion = 1.0f
     }
+
+    private fun enterGuidedTransformation() {
+        mediaHiearchyManager.qsExpansion = 1.0f
+        goToLockscreen()
+        mediaHiearchyManager.setTransitionToFullShadeAmount(123f)
+    }
+
+    companion object {
+        private const val QQS_TOP = 123
+        private const val QS_TOP = 456
+        private const val LOCKSCREEN_TOP = 789
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaViewControllerTest.kt
new file mode 100644
index 0000000..b7d5ba1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaViewControllerTest.kt
@@ -0,0 +1,55 @@
+package com.android.systemui.media
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.animation.MeasurementInput
+import com.android.systemui.util.animation.TransitionLayout
+import com.android.systemui.util.animation.TransitionViewState
+import junit.framework.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests for {@link MediaViewController}.
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class MediaViewControllerTest : SysuiTestCase() {
+    private val configurationController =
+            com.android.systemui.statusbar.phone.ConfigurationControllerImpl(context)
+    private val mediaHostStatesManager = MediaHostStatesManager()
+    private val mediaViewController =
+            MediaViewController(context, configurationController, mediaHostStatesManager)
+    private val mediaHostStateHolder = MediaHost.MediaHostStateHolder()
+    private var transitionLayout = TransitionLayout(context, /* attrs */ null, /* defStyleAttr */ 0)
+
+    @Before
+    fun setUp() {
+        mediaViewController.attach(transitionLayout, MediaViewController.TYPE.PLAYER)
+    }
+
+    @Test
+    fun testObtainViewState_applySquishFraction_toTransitionViewState_height() {
+        transitionLayout.measureState = TransitionViewState().apply {
+            this.height = 100
+        }
+        mediaHostStateHolder.expansion = 1f
+        val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
+        val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
+        mediaHostStateHolder.measurementInput =
+                MeasurementInput(widthMeasureSpec, heightMeasureSpec)
+
+        // Test no squish
+        mediaHostStateHolder.squishFraction = 1f
+        assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.height == 100)
+
+        // Test half squish
+        mediaHostStateHolder.squishFraction = 0.5f
+        assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.height == 50)
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
index 3c2392a..7ac15125 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
@@ -26,29 +26,33 @@
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
-import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @TestableLooper.RunWithLooper
-public class SeekBarObserverTest : SysuiTestCase() {
+class SeekBarObserverTest : SysuiTestCase() {
 
     private val disabledHeight = 1
     private val enabledHeight = 2
 
     private lateinit var observer: SeekBarObserver
     @Mock private lateinit var mockHolder: PlayerViewHolder
+    @Mock private lateinit var mockSquigglyProgress: SquigglyProgress
     private lateinit var seekBarView: SeekBar
     private lateinit var elapsedTimeView: TextView
     private lateinit var totalTimeView: TextView
 
+    @JvmField @Rule val mockitoRule = MockitoJUnit.rule()
+
     @Before
     fun setUp() {
-        mockHolder = mock(PlayerViewHolder::class.java)
 
         context.orCreateTestableResources
             .addOverride(R.dimen.qs_media_enabled_seekbar_height, enabledHeight)
@@ -56,6 +60,7 @@
             .addOverride(R.dimen.qs_media_disabled_seekbar_height, disabledHeight)
 
         seekBarView = SeekBar(context)
+        seekBarView.progressDrawable = mockSquigglyProgress
         elapsedTimeView = TextView(context)
         totalTimeView = TextView(context)
         whenever(mockHolder.seekBar).thenReturn(seekBarView)
@@ -69,7 +74,7 @@
     fun seekBarGone() {
         // WHEN seek bar is disabled
         val isEnabled = false
-        val data = SeekBarViewModel.Progress(isEnabled, false, null, 0)
+        val data = SeekBarViewModel.Progress(isEnabled, false, false, null, 0)
         observer.onChanged(data)
         // THEN seek bar shows just a thin line with no text
         assertThat(seekBarView.isEnabled()).isFalse()
@@ -84,7 +89,7 @@
     fun seekBarVisible() {
         // WHEN seek bar is enabled
         val isEnabled = true
-        val data = SeekBarViewModel.Progress(isEnabled, true, 3000, 12000)
+        val data = SeekBarViewModel.Progress(isEnabled, true, false, 3000, 12000)
         observer.onChanged(data)
         // THEN seek bar is visible and thick
         assertThat(seekBarView.getVisibility()).isEqualTo(View.VISIBLE)
@@ -96,7 +101,7 @@
     @Test
     fun seekBarProgress() {
         // WHEN part of the track has been played
-        val data = SeekBarViewModel.Progress(true, true, 3000, 120000)
+        val data = SeekBarViewModel.Progress(true, true, true, 3000, 120000)
         observer.onChanged(data)
         // THEN seek bar shows the progress
         assertThat(seekBarView.progress).isEqualTo(3000)
@@ -112,7 +117,7 @@
     fun seekBarDisabledWhenSeekNotAvailable() {
         // WHEN seek is not available
         val isSeekAvailable = false
-        val data = SeekBarViewModel.Progress(true, isSeekAvailable, 3000, 120000)
+        val data = SeekBarViewModel.Progress(true, isSeekAvailable, false, 3000, 120000)
         observer.onChanged(data)
         // THEN seek bar is not enabled
         assertThat(seekBarView.isEnabled()).isFalse()
@@ -122,9 +127,29 @@
     fun seekBarEnabledWhenSeekNotAvailable() {
         // WHEN seek is available
         val isSeekAvailable = true
-        val data = SeekBarViewModel.Progress(true, isSeekAvailable, 3000, 120000)
+        val data = SeekBarViewModel.Progress(true, isSeekAvailable, false, 3000, 120000)
         observer.onChanged(data)
         // THEN seek bar is not enabled
         assertThat(seekBarView.isEnabled()).isTrue()
     }
+
+    @Test
+    fun seekBarPlaying() {
+        // WHEN playing
+        val isPlaying = true
+        val data = SeekBarViewModel.Progress(true, true, isPlaying, 3000, 120000)
+        observer.onChanged(data)
+        // THEN progress drawable is animating
+        verify(mockSquigglyProgress).animate = true
+    }
+
+    @Test
+    fun seekBarNotPlaying() {
+        // WHEN not playing
+        val isPlaying = false
+        val data = SeekBarViewModel.Progress(true, true, isPlaying, 3000, 120000)
+        observer.onChanged(data)
+        // THEN progress drawable is not animating
+        verify(mockSquigglyProgress).animate = false
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SquigglyProgressTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SquigglyProgressTest.kt
new file mode 100644
index 0000000..0787fd6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/SquigglyProgressTest.kt
@@ -0,0 +1,118 @@
+package com.android.systemui.media
+
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.LightingColorFilter
+import android.graphics.Paint
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.anyFloat
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class SquigglyProgressTest : SysuiTestCase() {
+
+    private val colorFilter = LightingColorFilter(Color.RED, Color.BLUE)
+    private val strokeWidth = 5f
+    private val alpha = 128
+    private val tint = Color.GREEN
+
+    lateinit var squigglyProgress: SquigglyProgress
+    @Mock lateinit var canvas: Canvas
+    @Captor lateinit var wavePaintCaptor: ArgumentCaptor<Paint>
+    @Captor lateinit var linePaintCaptor: ArgumentCaptor<Paint>
+    @JvmField @Rule val mockitoRule = MockitoJUnit.rule()
+
+    @Before
+    fun setup() {
+        squigglyProgress = SquigglyProgress()
+        squigglyProgress.waveLength = 30f
+        squigglyProgress.lineAmplitude = 10f
+        squigglyProgress.phaseSpeed = 8f
+        squigglyProgress.strokeWidth = strokeWidth
+        squigglyProgress.bounds = Rect(0, 0, 300, 30)
+    }
+
+    @Test
+    fun testDrawPathAndLine() {
+        squigglyProgress.draw(canvas)
+
+        verify(canvas).drawPath(any(), wavePaintCaptor.capture())
+        verify(canvas).drawLine(anyFloat(), anyFloat(), anyFloat(), anyFloat(),
+                linePaintCaptor.capture())
+    }
+
+    @Test
+    fun testOnLevelChanged() {
+        assertThat(squigglyProgress.setLevel(5)).isFalse()
+        squigglyProgress.animate = true
+        assertThat(squigglyProgress.setLevel(4)).isTrue()
+    }
+
+    @Test
+    fun testStrokeWidth() {
+        squigglyProgress.draw(canvas)
+
+        verify(canvas).drawPath(any(), wavePaintCaptor.capture())
+        verify(canvas).drawLine(anyFloat(), anyFloat(), anyFloat(), anyFloat(),
+                linePaintCaptor.capture())
+
+        assertThat(wavePaintCaptor.value.strokeWidth).isEqualTo(strokeWidth)
+        assertThat(linePaintCaptor.value.strokeWidth).isEqualTo(strokeWidth)
+    }
+
+    @Test
+    fun testAlpha() {
+        squigglyProgress.alpha = alpha
+        squigglyProgress.draw(canvas)
+
+        verify(canvas).drawPath(any(), wavePaintCaptor.capture())
+        verify(canvas).drawLine(anyFloat(), anyFloat(), anyFloat(), anyFloat(),
+                linePaintCaptor.capture())
+
+        assertThat(squigglyProgress.alpha).isEqualTo(alpha)
+        assertThat(wavePaintCaptor.value.alpha).isEqualTo(alpha)
+        assertThat(linePaintCaptor.value.alpha).isEqualTo((alpha / 255f * DISABLED_ALPHA).toInt())
+    }
+
+    @Test
+    fun testColorFilter() {
+        squigglyProgress.colorFilter = colorFilter
+        squigglyProgress.draw(canvas)
+
+        verify(canvas).drawPath(any(), wavePaintCaptor.capture())
+        verify(canvas).drawLine(anyFloat(), anyFloat(), anyFloat(), anyFloat(),
+                linePaintCaptor.capture())
+
+        assertThat(wavePaintCaptor.value.colorFilter).isEqualTo(colorFilter)
+        assertThat(linePaintCaptor.value.colorFilter).isEqualTo(colorFilter)
+    }
+
+    @Test
+    fun testTint() {
+        squigglyProgress.setTint(tint)
+        squigglyProgress.draw(canvas)
+
+        verify(canvas).drawPath(any(), wavePaintCaptor.capture())
+        verify(canvas).drawLine(anyFloat(), anyFloat(), anyFloat(), anyFloat(),
+                linePaintCaptor.capture())
+
+        assertThat(wavePaintCaptor.value.color).isEqualTo(tint)
+        assertThat(linePaintCaptor.value.color).isEqualTo(tint)
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 2be30b3..380fa6d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -37,19 +37,21 @@
 import androidx.core.graphics.drawable.IconCompat;
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.logging.UiEventLogger;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.broadcast.BroadcastSender;
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.phone.ShadeController;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Optional;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -61,27 +63,28 @@
     private MediaOutputBaseAdapter mMediaOutputBaseAdapter = mock(MediaOutputBaseAdapter.class);
     private MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
     private LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
-    private ShadeController mShadeController = mock(ShadeController.class);
     private ActivityStarter mStarter = mock(ActivityStarter.class);
+    private BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
     private NotificationEntryManager mNotificationEntryManager =
             mock(NotificationEntryManager.class);
-    private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
+    private NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
+            NearbyMediaDevicesManager.class);
     private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
 
     private MediaOutputBaseDialogImpl mMediaOutputBaseDialogImpl;
     private MediaOutputController mMediaOutputController;
     private int mHeaderIconRes;
     private IconCompat mIconCompat;
-    private Drawable mAppSourceDrawable;
     private CharSequence mHeaderTitle;
     private CharSequence mHeaderSubtitle;
 
     @Before
     public void setUp() {
-        mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
-                mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator);
-        mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext,
+        mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
+                mMediaSessionManager, mLocalBluetoothManager, mStarter,
+                mNotificationEntryManager, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
+        mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext, mBroadcastSender,
                 mMediaOutputController);
         mMediaOutputBaseDialogImpl.onCreate(new Bundle());
     }
@@ -172,15 +175,16 @@
 
     class MediaOutputBaseDialogImpl extends MediaOutputBaseDialog {
 
-        MediaOutputBaseDialogImpl(Context context, MediaOutputController mediaOutputController) {
-            super(context, mediaOutputController);
+        MediaOutputBaseDialogImpl(Context context, BroadcastSender broadcastSender,
+                MediaOutputController mediaOutputController) {
+            super(context, broadcastSender, mediaOutputController);
 
             mAdapter = mMediaOutputBaseAdapter;
         }
 
         @Override
         Drawable getAppSourceIcon() {
-            return mAppSourceDrawable;
+            return null;
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index 789822e..d2dae74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -33,9 +33,11 @@
 import android.graphics.drawable.Icon;
 import android.media.MediaDescription;
 import android.media.MediaMetadata;
+import android.media.NearbyDevice;
 import android.media.RoutingSessionInfo;
 import android.media.session.MediaController;
 import android.media.session.MediaSessionManager;
+import android.os.RemoteException;
 import android.service.notification.StatusBarNotification;
 import android.testing.AndroidTestingRunner;
 import android.text.TextUtils;
@@ -43,7 +45,6 @@
 import androidx.core.graphics.drawable.IconCompat;
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.logging.UiEventLogger;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.media.LocalMediaManager;
@@ -51,10 +52,12 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
-import com.android.systemui.statusbar.phone.ShadeController;
+
+import com.google.common.collect.ImmutableList;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -62,6 +65,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -86,19 +90,22 @@
     private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class);
     private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
     private MediaDevice mMediaDevice2 = mock(MediaDevice.class);
+    private NearbyDevice mNearbyDevice1 = mock(NearbyDevice.class);
+    private NearbyDevice mNearbyDevice2 = mock(NearbyDevice.class);
     private MediaMetadata mMediaMetadata = mock(MediaMetadata.class);
     private RoutingSessionInfo mRemoteSessionInfo = mock(RoutingSessionInfo.class);
-    private ShadeController mShadeController = mock(ShadeController.class);
     private ActivityStarter mStarter = mock(ActivityStarter.class);
     private CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class);
-    private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
     private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
+    private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
+            NearbyMediaDevicesManager.class);
 
     private Context mSpyContext;
     private MediaOutputController mMediaOutputController;
     private LocalMediaManager mLocalMediaManager;
     private List<MediaController> mMediaControllers = new ArrayList<>();
     private List<MediaDevice> mMediaDevices = new ArrayList<>();
+    private List<NearbyDevice> mNearbyDevices = new ArrayList<>();
     private MediaDescription mMediaDescription;
     private List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
 
@@ -113,9 +120,10 @@
         when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(
                 mCachedBluetoothDeviceManager);
 
-        mMediaOutputController = new MediaOutputController(mSpyContext, TEST_PACKAGE_NAME, false,
-                mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+        mMediaOutputController = new MediaOutputController(mSpyContext, TEST_PACKAGE_NAME,
+                mMediaSessionManager, mLocalBluetoothManager, mStarter,
+                mNotifCollection, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
         mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager);
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
         MediaDescription.Builder builder = new MediaDescription.Builder();
@@ -127,6 +135,13 @@
         when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID);
         mMediaDevices.add(mMediaDevice1);
         mMediaDevices.add(mMediaDevice2);
+
+        when(mNearbyDevice1.getMediaRoute2Id()).thenReturn(TEST_DEVICE_1_ID);
+        when(mNearbyDevice1.getRangeZone()).thenReturn(NearbyDevice.RANGE_CLOSE);
+        when(mNearbyDevice2.getMediaRoute2Id()).thenReturn(TEST_DEVICE_2_ID);
+        when(mNearbyDevice2.getRangeZone()).thenReturn(NearbyDevice.RANGE_FAR);
+        mNearbyDevices.add(mNearbyDevice1);
+        mNearbyDevices.add(mNearbyDevice2);
     }
 
     @Test
@@ -157,9 +172,10 @@
 
     @Test
     public void start_withoutPackageName_verifyMediaControllerInit() {
-        mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
-                mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+        mMediaOutputController = new MediaOutputController(mSpyContext, null,
+                mMediaSessionManager, mLocalBluetoothManager, mStarter,
+                mNotifCollection, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
 
         mMediaOutputController.start(mCb);
 
@@ -167,6 +183,13 @@
     }
 
     @Test
+    public void start_nearbyMediaDevicesManagerNotNull_registersNearbyDevicesCallback() {
+        mMediaOutputController.start(mCb);
+
+        verify(mNearbyMediaDevicesManager).registerNearbyDevicesCallback(any());
+    }
+
+    @Test
     public void stop_withPackageName_verifyMediaControllerDeinit() {
         mMediaOutputController.start(mCb);
         reset(mMediaController);
@@ -178,9 +201,10 @@
 
     @Test
     public void stop_withoutPackageName_verifyMediaControllerDeinit() {
-        mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
-                mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+        mMediaOutputController = new MediaOutputController(mSpyContext, null,
+                mMediaSessionManager, mLocalBluetoothManager, mStarter,
+                mNotifCollection, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
 
         mMediaOutputController.start(mCb);
 
@@ -189,6 +213,39 @@
         verify(mMediaController, never()).unregisterCallback(any());
     }
 
+
+    @Test
+    public void stop_nearbyMediaDevicesManagerNotNull_unregistersNearbyDevicesCallback() {
+        mMediaOutputController.start(mCb);
+        reset(mMediaController);
+
+        mMediaOutputController.stop();
+
+        verify(mNearbyMediaDevicesManager).unregisterNearbyDevicesCallback(any());
+    }
+
+    @Test
+    public void onDevicesUpdated_unregistersNearbyDevicesCallback() throws RemoteException {
+        mMediaOutputController.start(mCb);
+
+        mMediaOutputController.onDevicesUpdated(ImmutableList.of());
+
+        verify(mNearbyMediaDevicesManager).unregisterNearbyDevicesCallback(any());
+    }
+
+    @Test
+    public void onDeviceListUpdate_withNearbyDevices_updatesRangeInformation()
+            throws RemoteException {
+        mMediaOutputController.start(mCb);
+        reset(mCb);
+
+        mMediaOutputController.onDevicesUpdated(mNearbyDevices);
+        mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+
+        verify(mMediaDevice1).setRangeZone(NearbyDevice.RANGE_CLOSE);
+        verify(mMediaDevice2).setRangeZone(NearbyDevice.RANGE_FAR);
+    }
+
     @Test
     public void onDeviceListUpdate_verifyDeviceListCallback() {
         mMediaOutputController.start(mCb);
@@ -449,9 +506,10 @@
 
     @Test
     public void getNotificationLargeIcon_withoutPackageName_returnsNull() {
-        mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
-                mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+        mMediaOutputController = new MediaOutputController(mSpyContext, null,
+                mMediaSessionManager, mLocalBluetoothManager, mStarter,
+                mNotifCollection, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
 
         assertThat(mMediaOutputController.getNotificationIcon()).isNull();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index 8a3ea56..db56f87 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -37,9 +37,10 @@
 import com.android.settingslib.media.MediaDevice;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.broadcast.BroadcastSender;
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.phone.ShadeController;
 
 import org.junit.After;
 import org.junit.Before;
@@ -48,6 +49,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -59,14 +61,16 @@
     // Mock
     private final MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
     private final LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
-    private final ShadeController mShadeController = mock(ShadeController.class);
     private final ActivityStarter mStarter = mock(ActivityStarter.class);
+    private final BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
     private final LocalMediaManager mLocalMediaManager = mock(LocalMediaManager.class);
     private final MediaDevice mMediaDevice = mock(MediaDevice.class);
     private final NotificationEntryManager mNotificationEntryManager =
             mock(NotificationEntryManager.class);
     private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
     private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
+    private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
+            NearbyMediaDevicesManager.class);
 
     private MediaOutputDialog mMediaOutputDialog;
     private MediaOutputController mMediaOutputController;
@@ -74,11 +78,12 @@
 
     @Before
     public void setUp() {
-        mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
-                mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator);
+        mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
+                mMediaSessionManager, mLocalBluetoothManager, mStarter,
+                mNotificationEntryManager, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
-        mMediaOutputDialog = new MediaOutputDialog(mContext, false,
+        mMediaOutputDialog = new MediaOutputDialog(mContext, false, mBroadcastSender,
                 mMediaOutputController, mUiEventLogger);
         mMediaOutputDialog.show();
 
@@ -124,7 +129,7 @@
     // Check the visibility metric logging by creating a new MediaOutput dialog,
     // and verify if the calling times increases.
     public void onCreate_ShouldLogVisibility() {
-        MediaOutputDialog testDialog = new MediaOutputDialog(mContext, false,
+        MediaOutputDialog testDialog = new MediaOutputDialog(mContext, false, mBroadcastSender,
                 mMediaOutputController, mUiEventLogger);
         testDialog.show();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java
index e8cd6c8..0cdde07 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java
@@ -28,16 +28,16 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.logging.UiEventLogger;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.media.LocalMediaManager;
 import com.android.settingslib.media.MediaDevice;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.broadcast.BroadcastSender;
+import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.phone.ShadeController;
 
 import org.junit.After;
 import org.junit.Before;
@@ -46,6 +46,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -57,15 +58,16 @@
     // Mock
     private MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
     private LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
-    private ShadeController mShadeController = mock(ShadeController.class);
     private ActivityStarter mStarter = mock(ActivityStarter.class);
+    private BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
     private LocalMediaManager mLocalMediaManager = mock(LocalMediaManager.class);
     private MediaDevice mMediaDevice = mock(MediaDevice.class);
     private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
     private NotificationEntryManager mNotificationEntryManager =
             mock(NotificationEntryManager.class);
-    private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
     private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
+    private NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
+            NearbyMediaDevicesManager.class);
 
     private MediaOutputGroupDialog mMediaOutputGroupDialog;
     private MediaOutputController mMediaOutputController;
@@ -73,11 +75,12 @@
 
     @Before
     public void setUp() {
-        mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
-                mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator);
+        mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
+                mMediaSessionManager, mLocalBluetoothManager, mStarter,
+                mNotificationEntryManager, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
-        mMediaOutputGroupDialog = new MediaOutputGroupDialog(mContext, false,
+        mMediaOutputGroupDialog = new MediaOutputGroupDialog(mContext, false, mBroadcastSender,
                 mMediaOutputController);
         mMediaOutputGroupDialog.show();
         when(mLocalMediaManager.getSelectedMediaDevice()).thenReturn(mMediaDevices);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
index 794bc09..2a13053 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
@@ -21,13 +21,8 @@
 import android.media.MediaRoute2Info
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.media.taptotransfer.sender.AlmostCloseToEndCast
-import com.android.systemui.media.taptotransfer.sender.AlmostCloseToStartCast
-import com.android.systemui.media.taptotransfer.sender.TransferFailed
-import com.android.systemui.media.taptotransfer.sender.TransferToReceiverTriggered
-import com.android.systemui.media.taptotransfer.sender.TransferToThisDeviceSucceeded
-import com.android.systemui.media.taptotransfer.sender.TransferToThisDeviceTriggered
-import com.android.systemui.media.taptotransfer.sender.TransferToReceiverSucceeded
+import com.android.systemui.media.taptotransfer.receiver.ChipStateReceiver
+import com.android.systemui.media.taptotransfer.sender.ChipStateSender
 import com.android.systemui.statusbar.commandline.Command
 import com.android.systemui.statusbar.commandline.CommandRegistry
 import com.android.systemui.util.concurrency.FakeExecutor
@@ -88,7 +83,7 @@
     @Test
     fun sender_almostCloseToStartCast_serviceCallbackCalled() {
         commandRegistry.onShellCommand(
-            pw, getSenderCommand(AlmostCloseToStartCast::class.simpleName!!)
+            pw, getSenderCommand(ChipStateSender.ALMOST_CLOSE_TO_START_CAST.name)
         )
 
         val routeInfoCaptor = argumentCaptor<MediaRoute2Info>()
@@ -103,7 +98,7 @@
     @Test
     fun sender_almostCloseToEndCast_serviceCallbackCalled() {
         commandRegistry.onShellCommand(
-            pw, getSenderCommand(AlmostCloseToEndCast::class.simpleName!!)
+            pw, getSenderCommand(ChipStateSender.ALMOST_CLOSE_TO_END_CAST.name)
         )
 
         val routeInfoCaptor = argumentCaptor<MediaRoute2Info>()
@@ -118,7 +113,7 @@
     @Test
     fun sender_transferToReceiverTriggered_chipDisplayWithCorrectState() {
         commandRegistry.onShellCommand(
-            pw, getSenderCommand(TransferToReceiverTriggered::class.simpleName!!)
+            pw, getSenderCommand(ChipStateSender.TRANSFER_TO_RECEIVER_TRIGGERED.name)
         )
 
         val routeInfoCaptor = argumentCaptor<MediaRoute2Info>()
@@ -133,7 +128,7 @@
     @Test
     fun sender_transferToThisDeviceTriggered_chipDisplayWithCorrectState() {
         commandRegistry.onShellCommand(
-            pw, getSenderCommand(TransferToThisDeviceTriggered::class.simpleName!!)
+            pw, getSenderCommand(ChipStateSender.TRANSFER_TO_THIS_DEVICE_TRIGGERED.name)
         )
 
         verify(statusBarManager).updateMediaTapToTransferSenderDisplay(
@@ -146,7 +141,7 @@
     @Test
     fun sender_transferToReceiverSucceeded_chipDisplayWithCorrectState() {
         commandRegistry.onShellCommand(
-            pw, getSenderCommand(TransferToReceiverSucceeded::class.simpleName!!)
+            pw, getSenderCommand(ChipStateSender.TRANSFER_TO_RECEIVER_SUCCEEDED.name)
         )
 
         val routeInfoCaptor = argumentCaptor<MediaRoute2Info>()
@@ -161,7 +156,7 @@
     @Test
     fun sender_transferToThisDeviceSucceeded_chipDisplayWithCorrectState() {
         commandRegistry.onShellCommand(
-            pw, getSenderCommand(TransferToThisDeviceSucceeded::class.simpleName!!)
+            pw, getSenderCommand(ChipStateSender.TRANSFER_TO_THIS_DEVICE_SUCCEEDED.name)
         )
 
         val routeInfoCaptor = argumentCaptor<MediaRoute2Info>()
@@ -174,8 +169,10 @@
     }
 
     @Test
-    fun sender_transferFailed_serviceCallbackCalled() {
-        commandRegistry.onShellCommand(pw, getSenderCommand(TransferFailed::class.simpleName!!))
+    fun sender_transferToReceiverFailed_serviceCallbackCalled() {
+        commandRegistry.onShellCommand(
+            pw, getSenderCommand(ChipStateSender.TRANSFER_TO_RECEIVER_FAILED.name)
+        )
 
         verify(statusBarManager).updateMediaTapToTransferSenderDisplay(
             eq(StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED),
@@ -185,8 +182,23 @@
     }
 
     @Test
+    fun sender_transferToThisDeviceFailed_serviceCallbackCalled() {
+        commandRegistry.onShellCommand(
+            pw, getSenderCommand(ChipStateSender.TRANSFER_TO_THIS_DEVICE_FAILED.name)
+        )
+
+        verify(statusBarManager).updateMediaTapToTransferSenderDisplay(
+            eq(StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED),
+            any(),
+            nullable(),
+            nullable())
+    }
+
+    @Test
     fun sender_farFromReceiver_serviceCallbackCalled() {
-        commandRegistry.onShellCommand(pw, getSenderCommand(FAR_FROM_RECEIVER_STATE))
+        commandRegistry.onShellCommand(
+            pw, getSenderCommand(ChipStateSender.FAR_FROM_RECEIVER.name)
+        )
 
         verify(statusBarManager).updateMediaTapToTransferSenderDisplay(
             eq(StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER),
@@ -197,7 +209,9 @@
 
     @Test
     fun receiver_closeToSender_serviceCallbackCalled() {
-        commandRegistry.onShellCommand(pw, getReceiverCommand(CLOSE_TO_SENDER_STATE))
+        commandRegistry.onShellCommand(
+            pw, getReceiverCommand(ChipStateReceiver.CLOSE_TO_SENDER.name)
+        )
 
         verify(statusBarManager).updateMediaTapToTransferReceiverDisplay(
             eq(StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER),
@@ -209,7 +223,9 @@
 
     @Test
     fun receiver_farFromSender_serviceCallbackCalled() {
-        commandRegistry.onShellCommand(pw, getReceiverCommand(FAR_FROM_SENDER_STATE))
+        commandRegistry.onShellCommand(
+            pw, getReceiverCommand(ChipStateReceiver.FAR_FROM_SENDER.name)
+        )
 
         verify(statusBarManager).updateMediaTapToTransferReceiverDisplay(
             eq(StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
index adb59ec..ccce577 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
@@ -17,7 +17,10 @@
 package com.android.systemui.media.taptotransfer.common
 
 import android.content.Context
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
 import android.graphics.drawable.Drawable
+import android.os.PowerManager
 import android.view.MotionEvent
 import android.view.View
 import android.view.ViewGroup
@@ -40,6 +43,7 @@
 import org.junit.Test
 import org.mockito.ArgumentCaptor
 import org.mockito.Mock
+import org.mockito.Mockito.eq
 import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
@@ -48,12 +52,16 @@
 
 @SmallTest
 class MediaTttChipControllerCommonTest : SysuiTestCase() {
-    private lateinit var controllerCommon: MediaTttChipControllerCommon<MediaTttChipState>
+    private lateinit var controllerCommon: MediaTttChipControllerCommon<ChipInfo>
 
     private lateinit var fakeClock: FakeSystemClock
     private lateinit var fakeExecutor: FakeExecutor
 
-    private lateinit var appIconDrawable: Drawable
+    private lateinit var appIconFromPackageName: Drawable
+    @Mock
+    private lateinit var packageManager: PackageManager
+    @Mock
+    private lateinit var applicationInfo: ApplicationInfo
     @Mock
     private lateinit var logger: MediaTttLogger
     @Mock
@@ -62,25 +70,36 @@
     private lateinit var viewUtil: ViewUtil
     @Mock
     private lateinit var tapGestureDetector: TapGestureDetector
+    @Mock
+    private lateinit var powerManager: PowerManager
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        appIconDrawable = context.getDrawable(R.drawable.ic_cake)!!
+
+        appIconFromPackageName = context.getDrawable(R.drawable.ic_cake)!!
+        whenever(packageManager.getApplicationIcon(PACKAGE_NAME)).thenReturn(appIconFromPackageName)
+        whenever(applicationInfo.loadLabel(packageManager)).thenReturn(APP_NAME)
+        whenever(packageManager.getApplicationInfo(
+            eq(PACKAGE_NAME), any<PackageManager.ApplicationInfoFlags>()
+        )).thenReturn(applicationInfo)
+        context.setMockPackageManager(packageManager)
+
         fakeClock = FakeSystemClock()
         fakeExecutor = FakeExecutor(fakeClock)
 
         controllerCommon = TestControllerCommon(
-            context, logger, windowManager, viewUtil, fakeExecutor, tapGestureDetector
+            context, logger, windowManager, viewUtil, fakeExecutor, tapGestureDetector, powerManager
         )
     }
 
     @Test
-    fun displayChip_chipAddedAndGestureDetectionStarted() {
+    fun displayChip_chipAddedAndGestureDetectionStartedAndScreenOn() {
         controllerCommon.displayChip(getState())
 
         verify(windowManager).addView(any(), any())
         verify(tapGestureDetector).addOnGestureDetectedCallback(any(), any())
+        verify(powerManager).wakeUp(any(), any(), any())
     }
 
     @Test
@@ -100,7 +119,7 @@
         controllerCommon.displayChip(state)
         reset(windowManager)
 
-        fakeClock.advanceTime(state.getTimeoutMs() - 1)
+        fakeClock.advanceTime(TIMEOUT_MS - 1)
 
         verify(windowManager, never()).removeView(any())
     }
@@ -111,7 +130,7 @@
         controllerCommon.displayChip(state)
         reset(windowManager)
 
-        fakeClock.advanceTime(state.getTimeoutMs() + 1)
+        fakeClock.advanceTime(TIMEOUT_MS + 1)
 
         verify(windowManager).removeView(any())
     }
@@ -128,7 +147,7 @@
         controllerCommon.displayChip(getState())
 
         // Wait until the timeout for the first display would've happened
-        fakeClock.advanceTime(state.getTimeoutMs() - waitTime + 1)
+        fakeClock.advanceTime(TIMEOUT_MS - waitTime + 1)
 
         // Verify we didn't hide the chip
         verify(windowManager, never()).removeView(any())
@@ -145,7 +164,7 @@
         controllerCommon.displayChip(getState())
 
         // Ensure we still hide the chip eventually
-        fakeClock.advanceTime(state.getTimeoutMs() + 1)
+        fakeClock.advanceTime(TIMEOUT_MS + 1)
 
         verify(windowManager).removeView(any())
     }
@@ -172,16 +191,45 @@
     }
 
     @Test
-    fun setIcon_viewHasIconAndContentDescription() {
+    fun setIcon_nullAppIconDrawable_iconIsFromPackageName() {
         controllerCommon.displayChip(getState())
         val chipView = getChipView()
 
-        val state = TestChipState(PACKAGE_NAME)
-        controllerCommon.setIcon(state, chipView)
+        controllerCommon.setIcon(chipView, PACKAGE_NAME, appIconDrawableOverride = null, null)
 
-        assertThat(chipView.getAppIconView().drawable).isEqualTo(appIconDrawable)
-        assertThat(chipView.getAppIconView().contentDescription)
-                .isEqualTo(state.getAppName(context))
+        assertThat(chipView.getAppIconView().drawable).isEqualTo(appIconFromPackageName)
+    }
+
+    @Test
+    fun displayChip_hasAppIconDrawable_iconIsDrawable() {
+        controllerCommon.displayChip(getState())
+        val chipView = getChipView()
+
+        val drawable = context.getDrawable(R.drawable.ic_alarm)!!
+        controllerCommon.setIcon(chipView, PACKAGE_NAME, drawable, null)
+
+        assertThat(chipView.getAppIconView().drawable).isEqualTo(drawable)
+    }
+
+    @Test
+    fun displayChip_nullAppName_iconContentDescriptionIsFromPackageName() {
+        controllerCommon.displayChip(getState())
+        val chipView = getChipView()
+
+        controllerCommon.setIcon(chipView, PACKAGE_NAME, null, appNameOverride = null)
+
+        assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
+    }
+
+    @Test
+    fun displayChip_hasAppName_iconContentDescriptionIsAppNameOverride() {
+        controllerCommon.displayChip(getState())
+        val chipView = getChipView()
+
+        val appName = "Override App Name"
+        controllerCommon.setIcon(chipView, PACKAGE_NAME, null, appName)
+
+        assertThat(chipView.getAppIconView().contentDescription).isEqualTo(appName)
     }
 
     @Test
@@ -218,7 +266,7 @@
         verify(windowManager, never()).removeView(any())
     }
 
-    private fun getState() = MediaTttChipState(PACKAGE_NAME)
+    private fun getState() = ChipInfo()
 
     private fun getChipView(): ViewGroup {
         val viewCaptor = ArgumentCaptor.forClass(View::class.java)
@@ -235,22 +283,27 @@
         viewUtil: ViewUtil,
         @Main mainExecutor: DelayableExecutor,
         tapGestureDetector: TapGestureDetector,
-    ) : MediaTttChipControllerCommon<MediaTttChipState>(
+        powerManager: PowerManager
+    ) : MediaTttChipControllerCommon<ChipInfo>(
         context,
         logger,
         windowManager,
         viewUtil,
         mainExecutor,
         tapGestureDetector,
+        powerManager,
         R.layout.media_ttt_chip
     ) {
-        override fun updateChipView(chipState: MediaTttChipState, currentChipView: ViewGroup) {
+        override fun updateChipView(chipInfo: ChipInfo, currentChipView: ViewGroup) {
+
         }
     }
 
-    inner class TestChipState(appPackageName: String?) : MediaTttChipState(appPackageName) {
-        override fun getAppIcon(context: Context) = appIconDrawable
+    inner class ChipInfo : ChipInfoCommon {
+        override fun getTimeoutMs() = TIMEOUT_MS
     }
 }
 
 private const val PACKAGE_NAME = "com.android.systemui"
+private const val APP_NAME = "Fake App Name"
+private const val TIMEOUT_MS = 10000L
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
index 56f4589..355d3fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
@@ -22,6 +22,7 @@
 import android.graphics.drawable.Drawable
 import android.media.MediaRoute2Info
 import android.os.Handler
+import android.os.PowerManager
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View
@@ -29,6 +30,7 @@
 import android.view.WindowManager
 import android.widget.ImageView
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
@@ -63,6 +65,8 @@
     @Mock
     private lateinit var logger: MediaTttLogger
     @Mock
+    private lateinit var powerManager: PowerManager
+    @Mock
     private lateinit var windowManager: WindowManager
     @Mock
     private lateinit var viewUtil: ViewUtil
@@ -70,6 +74,8 @@
     private lateinit var commandQueue: CommandQueue
     private lateinit var commandQueueCallback: CommandQueue.Callbacks
     private lateinit var fakeAppIconDrawable: Drawable
+    private lateinit var uiEventLoggerFake: UiEventLoggerFake
+    private lateinit var receiverUiEventLogger: MediaTttReceiverUiEventLogger
 
     @Before
     fun setUp() {
@@ -83,6 +89,9 @@
         )).thenReturn(applicationInfo)
         context.setMockPackageManager(packageManager)
 
+        uiEventLoggerFake = UiEventLoggerFake()
+        receiverUiEventLogger = MediaTttReceiverUiEventLogger(uiEventLoggerFake)
+
         controllerReceiver = MediaTttChipControllerReceiver(
             commandQueue,
             context,
@@ -91,7 +100,9 @@
             viewUtil,
             FakeExecutor(FakeSystemClock()),
             TapGestureDetector(context),
+            powerManager,
             Handler.getMain(),
+            receiverUiEventLogger,
         )
 
         val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
@@ -110,6 +121,9 @@
         )
 
         assertThat(getChipView().getAppIconView().contentDescription).isEqualTo(appName)
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER.id
+        )
     }
 
     @Test
@@ -122,6 +136,9 @@
         )
 
         verify(windowManager, never()).addView(any(), any())
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_FAR_FROM_SENDER.id
+        )
     }
 
     @Test
@@ -157,44 +174,6 @@
         verify(logger).logStateChange(any(), any())
     }
 
-    @Test
-    fun displayChip_nullAppIconDrawable_iconIsFromPackageName() {
-        val state = ChipStateReceiver(PACKAGE_NAME, appIconDrawable = null, "appName")
-
-        controllerReceiver.displayChip(state)
-
-        assertThat(getChipView().getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
-    }
-
-    @Test
-    fun displayChip_hasAppIconDrawable_iconIsDrawable() {
-        val drawable = context.getDrawable(R.drawable.ic_alarm)!!
-        val state = ChipStateReceiver(PACKAGE_NAME, drawable, "appName")
-
-        controllerReceiver.displayChip(state)
-
-        assertThat(getChipView().getAppIconView().drawable).isEqualTo(drawable)
-    }
-
-    @Test
-    fun displayChip_nullAppName_iconContentDescriptionIsFromPackageName() {
-        val state = ChipStateReceiver(PACKAGE_NAME, appIconDrawable = null, appName = null)
-
-        controllerReceiver.displayChip(state)
-
-        assertThat(getChipView().getAppIconView().contentDescription).isEqualTo(APP_NAME)
-    }
-
-    @Test
-    fun displayChip_hasAppName_iconContentDescriptionIsAppNameOverride() {
-        val appName = "Override App Name"
-        val state = ChipStateReceiver(PACKAGE_NAME, appIconDrawable = null, appName)
-
-        controllerReceiver.displayChip(state)
-
-        assertThat(getChipView().getAppIconView().contentDescription).isEqualTo(appName)
-    }
-
     private fun getChipView(): ViewGroup {
         val viewCaptor = ArgumentCaptor.forClass(View::class.java)
         verify(windowManager).addView(viewCaptor.capture(), any())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
new file mode 100644
index 0000000..ee10ddc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
@@ -0,0 +1,30 @@
+package com.android.systemui.media.taptotransfer.receiver
+
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+@SmallTest
+class MediaTttReceiverUiEventLoggerTest : SysuiTestCase() {
+    private lateinit var uiEventLoggerFake: UiEventLoggerFake
+    private lateinit var logger: MediaTttReceiverUiEventLogger
+
+    @Before
+    fun setUp() {
+        uiEventLoggerFake = UiEventLoggerFake()
+        logger = MediaTttReceiverUiEventLogger(uiEventLoggerFake)
+    }
+
+    @Test
+    fun logReceiverStateChange_eventAssociatedWithStateIsLogged() {
+        val state = ChipStateReceiver.CLOSE_TO_SENDER
+
+        logger.logReceiverStateChange(state)
+
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(state.uiEvent.id)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
index fd1d76a..ef53154 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
@@ -21,6 +21,7 @@
 import android.content.pm.PackageManager
 import android.graphics.drawable.Drawable
 import android.media.MediaRoute2Info
+import android.os.PowerManager
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View
@@ -29,6 +30,7 @@
 import android.widget.LinearLayout
 import android.widget.TextView
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.internal.statusbar.IUndoMediaTransferCallback
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
@@ -65,6 +67,8 @@
     @Mock
     private lateinit var logger: MediaTttLogger
     @Mock
+    private lateinit var powerManager: PowerManager
+    @Mock
     private lateinit var windowManager: WindowManager
     @Mock
     private lateinit var viewUtil: ViewUtil
@@ -74,6 +78,8 @@
     private lateinit var fakeAppIconDrawable: Drawable
     private lateinit var fakeClock: FakeSystemClock
     private lateinit var fakeExecutor: FakeExecutor
+    private lateinit var uiEventLoggerFake: UiEventLoggerFake
+    private lateinit var senderUiEventLogger: MediaTttSenderUiEventLogger
 
     @Before
     fun setUp() {
@@ -89,6 +95,8 @@
 
         fakeClock = FakeSystemClock()
         fakeExecutor = FakeExecutor(fakeClock)
+        uiEventLoggerFake = UiEventLoggerFake()
+        senderUiEventLogger = MediaTttSenderUiEventLogger(uiEventLoggerFake)
 
         controllerSender = MediaTttChipControllerSender(
             commandQueue,
@@ -97,7 +105,9 @@
             windowManager,
             viewUtil,
             fakeExecutor,
-            TapGestureDetector(context)
+            TapGestureDetector(context),
+            powerManager,
+            senderUiEventLogger
         )
 
         val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
@@ -113,8 +123,12 @@
             null
         )
 
-        assertThat(getChipView().getChipText())
-            .isEqualTo(almostCloseToStartCast().getChipTextString(context))
+        assertThat(getChipView().getChipText()).isEqualTo(
+            almostCloseToStartCast().state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST.id
+        )
     }
 
     @Test
@@ -125,8 +139,12 @@
             null
         )
 
-        assertThat(getChipView().getChipText())
-            .isEqualTo(almostCloseToEndCast().getChipTextString(context))
+        assertThat(getChipView().getChipText()).isEqualTo(
+            almostCloseToEndCast().state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST.id
+        )
     }
 
     @Test
@@ -137,8 +155,12 @@
             null
         )
 
-        assertThat(getChipView().getChipText())
-            .isEqualTo(transferToReceiverTriggered().getChipTextString(context))
+        assertThat(getChipView().getChipText()).isEqualTo(
+            transferToReceiverTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED.id
+        )
     }
 
     @Test
@@ -149,8 +171,12 @@
             null
         )
 
-        assertThat(getChipView().getChipText())
-            .isEqualTo(transferToThisDeviceTriggered().getChipTextString(context))
+        assertThat(getChipView().getChipText()).isEqualTo(
+            transferToThisDeviceTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED.id
+        )
     }
 
     @Test
@@ -161,8 +187,12 @@
             null
         )
 
-        assertThat(getChipView().getChipText())
-            .isEqualTo(transferToReceiverSucceeded().getChipTextString(context))
+        assertThat(getChipView().getChipText()).isEqualTo(
+            transferToReceiverSucceeded().state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id
+        )
     }
 
     @Test
@@ -173,8 +203,12 @@
             null
         )
 
-        assertThat(getChipView().getChipText())
-            .isEqualTo(transferToThisDeviceSucceeded().getChipTextString(context))
+        assertThat(getChipView().getChipText()).isEqualTo(
+            transferToThisDeviceSucceeded().state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED.id
+        )
     }
 
     @Test
@@ -185,8 +219,12 @@
             null
         )
 
-        assertThat(getChipView().getChipText())
-            .isEqualTo(transferFailed().getChipTextString(context))
+        assertThat(getChipView().getChipText()).isEqualTo(
+            transferToReceiverFailed().state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED.id
+        )
     }
 
     @Test
@@ -197,8 +235,12 @@
             null
         )
 
-        assertThat(getChipView().getChipText())
-            .isEqualTo(transferFailed().getChipTextString(context))
+        assertThat(getChipView().getChipText()).isEqualTo(
+            transferToThisDeviceFailed().state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED.id
+        )
     }
 
     @Test
@@ -210,6 +252,9 @@
         )
 
         verify(windowManager, never()).addView(any(), any())
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_FAR_FROM_RECEIVER.id
+        )
     }
 
     @Test
@@ -250,7 +295,9 @@
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
         assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
-        assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+        assertThat(chipView.getChipText()).isEqualTo(
+            state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
         assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
         assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
         assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
@@ -264,7 +311,9 @@
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
         assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
-        assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+        assertThat(chipView.getChipText()).isEqualTo(
+            state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
         assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
         assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
         assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
@@ -278,7 +327,9 @@
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
         assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
-        assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+        assertThat(chipView.getChipText()).isEqualTo(
+            state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
         assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.VISIBLE)
         assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
         assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
@@ -292,7 +343,9 @@
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
         assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
-        assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+        assertThat(chipView.getChipText()).isEqualTo(
+            state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
         assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.VISIBLE)
         assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
         assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
@@ -306,7 +359,9 @@
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
         assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
-        assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+        assertThat(chipView.getChipText()).isEqualTo(
+            state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
         assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
         assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
     }
@@ -355,8 +410,12 @@
 
         getChipView().getUndoButton().performClick()
 
-        assertThat(getChipView().getChipText())
-            .isEqualTo(transferToThisDeviceTriggered().getChipTextString(context))
+        assertThat(getChipView().getChipText()).isEqualTo(
+            transferToThisDeviceTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED.id
+        )
     }
 
     @Test
@@ -367,7 +426,9 @@
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
         assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
-        assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+        assertThat(chipView.getChipText()).isEqualTo(
+            state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
         assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
         assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.GONE)
     }
@@ -416,19 +477,41 @@
 
         getChipView().getUndoButton().performClick()
 
-        assertThat(getChipView().getChipText())
-            .isEqualTo(transferToReceiverTriggered().getChipTextString(context))
+        assertThat(getChipView().getChipText()).isEqualTo(
+            transferToReceiverTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED.id
+        )
     }
 
     @Test
-    fun transferFailed_appIcon_noDeviceName_noLoadingIcon_noUndo_failureIcon() {
-        val state = transferFailed()
+    fun transferToReceiverFailed_appIcon_noDeviceName_noLoadingIcon_noUndo_failureIcon() {
+        val state = transferToReceiverFailed()
         controllerSender.displayChip(state)
 
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
         assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
-        assertThat(chipView.getChipText()).isEqualTo(state.getChipTextString(context))
+        assertThat(getChipView().getChipText()).isEqualTo(
+            state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
+        assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
+        assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
+        assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.VISIBLE)
+    }
+
+    @Test
+    fun transferToThisDeviceFailed_appIcon_noDeviceName_noLoadingIcon_noUndo_failureIcon() {
+        val state = transferToThisDeviceFailed()
+        controllerSender.displayChip(state)
+
+        val chipView = getChipView()
+        assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
+        assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
+        assertThat(getChipView().getChipText()).isEqualTo(
+            state.state.getChipTextString(context, OTHER_DEVICE_NAME)
+        )
         assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
         assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
         assertThat(chipView.getFailureIcon().visibility).isEqualTo(View.VISIBLE)
@@ -475,7 +558,7 @@
     @Test
     fun changeFromTransferTriggeredToTransferFailed_failureIconAppears() {
         controllerSender.displayChip(transferToReceiverTriggered())
-        controllerSender.displayChip(transferFailed())
+        controllerSender.displayChip(transferToReceiverFailed())
 
         assertThat(getChipView().getFailureIcon().visibility).isEqualTo(View.VISIBLE)
     }
@@ -498,7 +581,7 @@
         fakeClock.advanceTime(1000L)
         controllerSender.removeChip("fakeRemovalReason")
 
-        fakeClock.advanceTime(state.getTimeoutMs() + 1)
+        fakeClock.advanceTime(state.state.timeout + 1)
 
         verify(windowManager).removeView(any())
     }
@@ -521,7 +604,7 @@
         fakeClock.advanceTime(1000L)
         controllerSender.removeChip("fakeRemovalReason")
 
-        fakeClock.advanceTime(state.getTimeoutMs() + 1)
+        fakeClock.advanceTime(state.state.timeout + 1)
 
         verify(windowManager).removeView(any())
     }
@@ -546,34 +629,35 @@
 
     /** Helper method providing default parameters to not clutter up the tests. */
     private fun almostCloseToStartCast() =
-        AlmostCloseToStartCast(PACKAGE_NAME, OTHER_DEVICE_NAME)
+        ChipSenderInfo(ChipStateSender.ALMOST_CLOSE_TO_START_CAST, routeInfo)
 
     /** Helper method providing default parameters to not clutter up the tests. */
     private fun almostCloseToEndCast() =
-        AlmostCloseToEndCast(PACKAGE_NAME, OTHER_DEVICE_NAME)
+        ChipSenderInfo(ChipStateSender.ALMOST_CLOSE_TO_END_CAST, routeInfo)
 
     /** Helper method providing default parameters to not clutter up the tests. */
     private fun transferToReceiverTriggered() =
-        TransferToReceiverTriggered(PACKAGE_NAME, OTHER_DEVICE_NAME)
+        ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo)
 
     /** Helper method providing default parameters to not clutter up the tests. */
     private fun transferToThisDeviceTriggered() =
-        TransferToThisDeviceTriggered(PACKAGE_NAME)
+        ChipSenderInfo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo)
 
     /** Helper method providing default parameters to not clutter up the tests. */
     private fun transferToReceiverSucceeded(undoCallback: IUndoMediaTransferCallback? = null) =
-        TransferToReceiverSucceeded(
-            PACKAGE_NAME, OTHER_DEVICE_NAME, undoCallback
-        )
+        ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, undoCallback)
 
     /** Helper method providing default parameters to not clutter up the tests. */
     private fun transferToThisDeviceSucceeded(undoCallback: IUndoMediaTransferCallback? = null) =
-        TransferToThisDeviceSucceeded(
-            PACKAGE_NAME, OTHER_DEVICE_NAME, undoCallback
-        )
+        ChipSenderInfo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, undoCallback)
 
     /** Helper method providing default parameters to not clutter up the tests. */
-    private fun transferFailed() = TransferFailed(PACKAGE_NAME)
+    private fun transferToReceiverFailed() =
+        ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_FAILED, routeInfo)
+
+    /** Helper method providing default parameters to not clutter up the tests. */
+    private fun transferToThisDeviceFailed() =
+        ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_FAILED, routeInfo)
 }
 
 private const val APP_NAME = "Fake app name"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
new file mode 100644
index 0000000..263637a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
@@ -0,0 +1,46 @@
+package com.android.systemui.media.taptotransfer.sender
+
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+@SmallTest
+class MediaTttSenderUiEventLoggerTest : SysuiTestCase() {
+    private lateinit var uiEventLoggerFake: UiEventLoggerFake
+    private lateinit var logger: MediaTttSenderUiEventLogger
+
+    @Before
+    fun setUp () {
+        uiEventLoggerFake = UiEventLoggerFake()
+        logger = MediaTttSenderUiEventLogger(uiEventLoggerFake)
+    }
+
+    @Test
+    fun logSenderStateChange_eventAssociatedWithStateIsLogged() {
+        val state = ChipStateSender.ALMOST_CLOSE_TO_END_CAST
+        logger.logSenderStateChange(state)
+
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(state.uiEvent.id)
+    }
+
+    @Test
+    fun logUndoClicked_undoEventLogged() {
+        val undoEvent = MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
+
+        logger.logUndoClicked(undoEvent)
+
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(undoEvent.id)
+    }
+
+    @Test
+    fun logUndoClicked_notUndoEvent_eventNotLogged() {
+        logger.logUndoClicked(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED)
+
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(0)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
index afb63ab..a156820 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
@@ -37,6 +37,7 @@
 
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.util.NotificationChannels;
 
@@ -59,7 +60,9 @@
         // Test Instance.
         mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager);
         ActivityStarter starter = mDependency.injectMockDependency(ActivityStarter.class);
-        mPowerNotificationWarnings = new PowerNotificationWarnings(mContext, starter);
+        BroadcastSender broadcastSender = mDependency.injectMockDependency(BroadcastSender.class);
+        mPowerNotificationWarnings = new PowerNotificationWarnings(mContext, starter,
+                broadcastSender);
         BatteryStateSnapshot snapshot = new BatteryStateSnapshot(100, false, false, 1,
                 BatteryManager.BATTERY_HEALTH_GOOD, 5, 15);
         mPowerNotificationWarnings.updateSnapshot(snapshot);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index 19a9863..6b7e5b93 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -20,21 +20,18 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.os.Handler;
-import android.os.Looper;
+import android.os.RemoteException;
 import android.os.UserHandle;
-import android.service.quicksettings.TileService;
+import android.service.quicksettings.IQSTileService;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -49,6 +46,7 @@
 import com.android.systemui.qs.tileimpl.QSFactoryImpl;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.AutoTileManager;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -68,17 +66,25 @@
 import java.util.ArrayList;
 import java.util.Optional;
 
+import javax.inject.Provider;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 public class TileServicesTest extends SysuiTestCase {
     private static int NUM_FAKES = TileServices.DEFAULT_MAX_BOUND * 2;
 
+    private static final ComponentName TEST_COMPONENT =
+            ComponentName.unflattenFromString("pkg/.cls");
+
     private TileServices mTileService;
+    private TestableLooper mTestableLooper;
     private ArrayList<TileServiceManager> mManagers;
     @Mock
     private BroadcastDispatcher mBroadcastDispatcher;
     @Mock
+    private CommandQueue mCommandQueue;
+    @Mock
     private StatusBarIconController mStatusBarIconController;
     @Mock
     private QSFactoryImpl mQSFactory;
@@ -116,17 +122,20 @@
         MockitoAnnotations.initMocks(this);
         mDependency.injectMockDependency(BluetoothController.class);
         mManagers = new ArrayList<>();
+        mTestableLooper = TestableLooper.get(this);
 
         when(mTileServiceRequestControllerBuilder.create(any()))
                 .thenReturn(mTileServiceRequestController);
         when(mTileLifecycleManagerFactory.create(any(Intent.class), any(UserHandle.class)))
                 .thenReturn(mTileLifecycleManager);
 
+        Provider<Handler> provider = () -> new Handler(mTestableLooper.getLooper());
+
         QSTileHost host = new QSTileHost(mContext,
                 mStatusBarIconController,
                 mQSFactory,
-                new Handler(),
-                Looper.myLooper(),
+                provider.get(),
+                mTestableLooper.getLooper(),
                 mPluginManager,
                 mTunerService,
                 () -> mAutoTileManager,
@@ -140,8 +149,8 @@
                 mock(CustomTileStatePersister.class),
                 mTileServiceRequestControllerBuilder,
                 mTileLifecycleManagerFactory);
-        mTileService = new TestTileServices(host, Looper.getMainLooper(), mBroadcastDispatcher,
-                mUserTracker, mKeyguardStateController);
+        mTileService = new TestTileServices(host, provider, mBroadcastDispatcher,
+                mUserTracker, mKeyguardStateController, mCommandQueue);
     }
 
     @After
@@ -152,24 +161,6 @@
     }
 
     @Test
-    public void testActiveTileListenerRegisteredOnAllUsers() {
-        ArgumentCaptor<IntentFilter> captor = ArgumentCaptor.forClass(IntentFilter.class);
-        verify(mBroadcastDispatcher).registerReceiver(any(), captor.capture(), any(), eq(
-                UserHandle.ALL));
-        assertTrue(captor.getValue().hasAction(TileService.ACTION_REQUEST_LISTENING));
-    }
-
-    @Test
-    public void testBadComponentName_doesntCrash() {
-        ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mBroadcastDispatcher).registerReceiver(captor.capture(), any(), any(), eq(
-                UserHandle.ALL));
-        Intent intent = new Intent(TileService.ACTION_REQUEST_LISTENING)
-                .putExtra(Intent.EXTRA_COMPONENT_NAME, "abc");
-        captor.getValue().onReceive(mContext, intent);
-    }
-
-    @Test
     public void testRecalculateBindAllowance() {
         // Add some fake tiles.
         for (int i = 0; i < NUM_FAKES; i++) {
@@ -225,11 +216,36 @@
         }
     }
 
+    @Test
+    public void testRegisterCommand() {
+        verify(mCommandQueue).addCallback(any());
+    }
+
+    @Test
+    public void testRequestListeningStatusCommand() throws RemoteException {
+        ArgumentCaptor<CommandQueue.Callbacks> captor =
+                ArgumentCaptor.forClass(CommandQueue.Callbacks.class);
+        verify(mCommandQueue).addCallback(captor.capture());
+
+        CustomTile mockTile = mock(CustomTile.class);
+        when(mockTile.getComponent()).thenReturn(TEST_COMPONENT);
+
+        TileServiceManager manager = mTileService.getTileWrapper(mockTile);
+        when(manager.isActiveTile()).thenReturn(true);
+        when(manager.getTileService()).thenReturn(mock(IQSTileService.class));
+
+        captor.getValue().requestTileServiceListeningState(TEST_COMPONENT);
+        mTestableLooper.processAllMessages();
+        verify(manager).setBindRequested(true);
+        verify(manager.getTileService()).onStartListening();
+    }
+
     private class TestTileServices extends TileServices {
-        TestTileServices(QSTileHost host, Looper looper,
+        TestTileServices(QSTileHost host, Provider<Handler> handlerProvider,
                 BroadcastDispatcher broadcastDispatcher, UserTracker userTracker,
-                KeyguardStateController keyguardStateController) {
-            super(host, looper, broadcastDispatcher, userTracker, keyguardStateController);
+                KeyguardStateController keyguardStateController, CommandQueue commandQueue) {
+            super(host, handlerProvider, broadcastDispatcher, userTracker, keyguardStateController,
+                    commandQueue);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
index 8297850..b652aee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
@@ -104,8 +104,6 @@
         assertEquals(state.label, mContext.getString(R.string.qr_code_scanner_title));
         assertEquals(state.contentDescription, mContext.getString(R.string.qr_code_scanner_title));
         assertEquals(state.icon, QSTileImpl.ResourceIcon.get(R.drawable.ic_qr_code_scanner));
-        assertEquals(state.secondaryLabel,
-                mContext.getString(R.string.qr_code_scanner_description));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
new file mode 100644
index 0000000..57803e8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
@@ -0,0 +1,181 @@
+/*
+ * 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.smartspace
+
+import android.app.smartspace.SmartspaceManager
+import android.app.smartspace.SmartspaceSession
+import android.app.smartspace.SmartspaceTarget
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.View
+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.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.smartspace.dagger.SmartspaceViewComponent
+import com.android.systemui.util.concurrency.Execution
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.withArgCaptor
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+import java.util.Optional
+import java.util.concurrent.Executor
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class DreamSmartspaceControllerTest : SysuiTestCase() {
+    @Mock
+    private lateinit var smartspaceManager: SmartspaceManager
+
+    @Mock
+    private lateinit var execution: Execution
+
+    @Mock
+    private lateinit var uiExecutor: Executor
+
+    @Mock
+    private lateinit var viewComponentFactory: SmartspaceViewComponent.Factory
+
+    @Mock
+    private lateinit var viewComponent: SmartspaceViewComponent
+
+    @Mock
+    private lateinit var targetFilter: SmartspaceTargetFilter
+
+    @Mock
+    private lateinit var plugin: BcSmartspaceDataPlugin
+
+    @Mock
+    private lateinit var precondition: SmartspacePrecondition
+
+    @Mock
+    private lateinit var smartspaceView: BcSmartspaceDataPlugin.SmartspaceView
+
+    @Mock
+    private lateinit var listener: BcSmartspaceDataPlugin.SmartspaceTargetListener
+
+    @Mock
+    private lateinit var session: SmartspaceSession
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        `when`(viewComponentFactory.create(any(), eq(plugin), any()))
+                .thenReturn(viewComponent)
+        `when`(viewComponent.getView()).thenReturn(smartspaceView)
+        `when`(smartspaceManager.createSmartspaceSession(any())).thenReturn(session)
+    }
+
+    /**
+     * Ensures smartspace session begins on a listener only flow.
+     */
+    @Test
+    fun testConnectOnListen() {
+        val controller = DreamsSmartspaceController(context,
+        smartspaceManager, execution, uiExecutor, viewComponentFactory, precondition,
+                Optional.of(targetFilter), Optional.of(plugin))
+
+        `when`(precondition.conditionsMet()).thenReturn(true)
+        controller.addListener(listener)
+
+        verify(smartspaceManager).createSmartspaceSession(any())
+
+        var targetListener = withArgCaptor<SmartspaceSession.OnTargetsAvailableListener> {
+            verify(session).addOnTargetsAvailableListener(any(), capture())
+        }
+
+        `when`(targetFilter.filterSmartspaceTarget(any())).thenReturn(true)
+
+        var target = Mockito.mock(SmartspaceTarget::class.java)
+        targetListener.onTargetsAvailable(listOf(target))
+
+        var targets = withArgCaptor<List<SmartspaceTarget>> {
+            verify(plugin).onTargetsAvailable(capture())
+        }
+
+        assertThat(targets.contains(target)).isTrue()
+
+        controller.removeListener(listener)
+
+        verify(session).close()
+    }
+
+    /**
+     * A class which implements SmartspaceView and extends View. This is mocked to provide the right
+     * object inheritance and interface implementation used in DreamSmartspaceController
+     */
+    private class TestView(context: Context?) : View(context),
+            BcSmartspaceDataPlugin.SmartspaceView {
+        override fun registerDataProvider(plugin: BcSmartspaceDataPlugin?) {}
+
+        override fun setPrimaryTextColor(color: Int) {}
+
+        override fun setDozeAmount(amount: Float) {}
+
+        override fun setIntentStarter(intentStarter: BcSmartspaceDataPlugin.IntentStarter?) {}
+
+        override fun setFalsingManager(falsingManager: FalsingManager?) {}
+
+        override fun setDnd(image: Drawable?, description: String?) {}
+
+        override fun setNextAlarm(image: Drawable?, description: String?) {}
+
+        override fun setMediaTarget(target: SmartspaceTarget?) {}
+
+        override fun getSelectedPage(): Int { return 0; }
+    }
+
+    /**
+     * Ensures session begins when a view is attached.
+     */
+    @Test
+    fun testConnectOnViewCreate() {
+        val controller = DreamsSmartspaceController(context,
+                smartspaceManager, execution, uiExecutor, viewComponentFactory, precondition,
+                Optional.of(targetFilter),
+                Optional.of(plugin))
+
+        `when`(precondition.conditionsMet()).thenReturn(true)
+        controller.buildAndConnectView(Mockito.mock(ViewGroup::class.java))
+
+        var stateChangeListener = withArgCaptor<View.OnAttachStateChangeListener> {
+            verify(viewComponentFactory).create(any(), eq(plugin), capture())
+        }
+
+        var mockView = Mockito.mock(TestView::class.java)
+        `when`(precondition.conditionsMet()).thenReturn(true)
+        stateChangeListener.onViewAttachedToWindow(mockView)
+
+        verify(smartspaceManager).createSmartspaceSession(any())
+
+        stateChangeListener.onViewDetachedFromWindow(mockView)
+
+        verify(session).close()
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
new file mode 100644
index 0000000..d29e9a6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
@@ -0,0 +1,132 @@
+/*
+ * 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.smartspace
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.smartspace.preconditions.LockscreenPrecondition
+import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.util.concurrency.Execution
+import com.google.common.truth.Truth.assertThat
+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.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class LockscreenPreconditionTest : SysuiTestCase() {
+    @Mock
+    private lateinit var featureFlags: FeatureFlags
+
+    @Mock
+    private lateinit var deviceProvisionedController: DeviceProvisionedController
+
+    @Mock
+    private lateinit var execution: Execution
+
+    @Mock
+    private lateinit var listener: SmartspacePrecondition.Listener
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    /**
+     * Ensures fully enabled state is published.
+     */
+    @Test
+    fun testFullyEnabled() {
+        `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(true)
+        `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+        `when`(featureFlags.isEnabled(Mockito.eq(Flags.SMARTSPACE) ?: Flags.SMARTSPACE))
+                .thenReturn(true)
+        val precondition = LockscreenPrecondition(featureFlags, deviceProvisionedController,
+                execution)
+        precondition.addListener(listener)
+
+        `verify`(listener).onCriteriaChanged()
+        assertThat(precondition.conditionsMet()).isTrue()
+    }
+
+    /**
+     * Ensures fully enabled state is published.
+     */
+    @Test
+    fun testProvisioning() {
+        `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(true)
+        `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(false)
+        `when`(featureFlags.isEnabled(Mockito.eq(Flags.SMARTSPACE) ?: Flags.SMARTSPACE))
+                .thenReturn(true)
+        val precondition =
+                LockscreenPrecondition(featureFlags, deviceProvisionedController, execution)
+        precondition.addListener(listener)
+
+        verify(listener).onCriteriaChanged()
+        assertThat(precondition.conditionsMet()).isFalse()
+
+        var argumentCaptor = ArgumentCaptor.forClass(DeviceProvisionedController
+                .DeviceProvisionedListener::class.java)
+        verify(deviceProvisionedController).addCallback(argumentCaptor.capture())
+
+        Mockito.clearInvocations(listener)
+
+        `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+        argumentCaptor.value.onDeviceProvisionedChanged()
+        verify(listener).onCriteriaChanged()
+        assertThat(precondition.conditionsMet()).isTrue()
+    }
+
+    /**
+     * Makes sure user setup changes are propagated.
+     */
+    @Test
+    fun testUserSetup() {
+        `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(false)
+        `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+        `when`(featureFlags.isEnabled(Mockito.eq(Flags.SMARTSPACE) ?: Flags.SMARTSPACE))
+                .thenReturn(true)
+        val precondition =
+                LockscreenPrecondition(featureFlags, deviceProvisionedController, execution)
+        precondition.addListener(listener)
+
+        verify(listener).onCriteriaChanged()
+        assertThat(precondition.conditionsMet()).isFalse()
+
+        var argumentCaptor = ArgumentCaptor.forClass(DeviceProvisionedController
+                .DeviceProvisionedListener::class.java)
+        verify(deviceProvisionedController).addCallback(argumentCaptor.capture())
+
+        Mockito.clearInvocations(listener)
+
+        `when`(deviceProvisionedController.isCurrentUserSetup).thenReturn(true)
+        argumentCaptor.value.onUserSetupChanged()
+        verify(listener).onCriteriaChanged()
+        assertThat(precondition.conditionsMet()).isTrue()
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenTargetFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenTargetFilterTest.kt
new file mode 100644
index 0000000..185a838
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenTargetFilterTest.kt
@@ -0,0 +1,149 @@
+/*
+ * 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.smartspace
+
+import android.app.smartspace.SmartspaceTarget
+import android.content.ContentResolver
+import android.database.ContentObserver
+import android.net.Uri
+import android.os.Handler
+import android.os.UserHandle
+import android.provider.Settings
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.smartspace.filters.LockscreenTargetFilter
+import com.android.systemui.util.concurrency.Execution
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.withArgCaptor
+import com.android.systemui.util.settings.SecureSettings
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.atLeast
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+import java.util.concurrent.Executor
+
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner::class)
+class LockscreenTargetFilterTest : SysuiTestCase() {
+    @Mock
+    private lateinit var secureSettings: SecureSettings
+
+    @Mock
+    private lateinit var userTracker: UserTracker
+
+    @Mock
+    private lateinit var execution: Execution
+
+    @Mock
+    private lateinit var handler: Handler
+
+    @Mock
+    private lateinit var contentResolver: ContentResolver
+
+    @Mock
+    private lateinit var uiExecution: Executor
+
+    @Mock
+    private lateinit var userHandle: UserHandle
+
+    @Mock
+    private lateinit var listener: SmartspaceTargetFilter.Listener
+
+    @Mock
+    private lateinit var lockScreenAllowPrivateNotificationsUri: Uri
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        `when`(userTracker.userHandle).thenReturn(userHandle)
+        `when`(secureSettings
+                .getUriFor(eq(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS)))
+                .thenReturn(lockScreenAllowPrivateNotificationsUri)
+    }
+
+    /**
+     * Ensures {@link Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS} is
+     * tracked.
+     */
+    @Test
+    fun testLockscreenAllowPrivateNotifications() {
+        var setting = Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
+        `when`(secureSettings
+                .getIntForUser(eq(setting) ?: setting, anyInt(), anyInt()))
+                .thenReturn(0)
+        var filter = LockscreenTargetFilter(secureSettings, userTracker, execution, handler,
+                contentResolver, uiExecution)
+
+        filter.addListener(listener)
+        var smartspaceTarget = mock(SmartspaceTarget::class.java)
+        `when`(smartspaceTarget.userHandle).thenReturn(userHandle)
+        `when`(smartspaceTarget.isSensitive).thenReturn(true)
+        assertThat(filter.filterSmartspaceTarget(smartspaceTarget)).isFalse()
+
+        var settingCaptor = ArgumentCaptor.forClass(ContentObserver::class.java)
+
+        verify(contentResolver).registerContentObserver(eq(lockScreenAllowPrivateNotificationsUri),
+                anyBoolean(), settingCaptor.capture(), anyInt())
+
+        `when`(secureSettings
+                .getIntForUser(eq(setting) ?: setting, anyInt(), anyInt()))
+                .thenReturn(1)
+
+        clearInvocations(listener)
+        settingCaptor.value.onChange(false, mock(Uri::class.java))
+        verify(listener, atLeast(1)).onCriteriaChanged()
+        assertThat(filter.filterSmartspaceTarget(smartspaceTarget)).isTrue()
+    }
+
+    /**
+     * Ensures user switches are tracked.
+     */
+    @Test
+    fun testUserSwitchCallback() {
+        var setting = Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
+        `when`(secureSettings
+                .getIntForUser(eq(setting) ?: setting, anyInt(), anyInt()))
+                .thenReturn(0)
+        var filter = LockscreenTargetFilter(secureSettings, userTracker, execution, handler,
+                contentResolver, uiExecution)
+
+        filter.addListener(listener)
+
+        var userTrackerCallback = withArgCaptor<UserTracker.Callback> {
+            verify(userTracker).addCallback(capture(), any())
+        }
+
+        clearInvocations(listener)
+        userTrackerCallback.onUserChanged(0, context)
+
+        verify(listener).onCriteriaChanged()
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 3c1a73e..ad643fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -226,6 +226,10 @@
     @After
     public void tearDown() throws Exception {
         mTextView.setAnimationsEnabled(true);
+        if (mController != null) {
+            mController.destroy();
+            mController = null;
+        }
     }
 
     private void createController() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index 25a5b90..64a0a23 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -44,6 +44,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.ArgumentMatchers.eq
 
 private fun <T> anyObject(): T {
     return Mockito.anyObject<T>()
@@ -87,6 +88,8 @@
         row = helper.createRow()
         context.getOrCreateTestableResources()
                 .addOverride(R.bool.config_use_split_notification_shade, false)
+        context.getOrCreateTestableResources()
+            .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
         transitionController = LockscreenShadeTransitionController(
             statusBarStateController = statusbarStateController,
             logger = logger,
@@ -247,6 +250,60 @@
     }
 
     @Test
+    fun testDragDownAmount_depthDistanceIsZero_doesNotSetProgress() {
+        context.getOrCreateTestableResources()
+            .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 0)
+        configurationController.notifyConfigurationChanged()
+
+        transitionController.dragDownAmount = 10f
+
+        verify(depthController, never()).transitionToFullShadeProgress
+    }
+
+    @Test
+    fun setDragAmount_setsKeyguardTransitionProgress() {
+        transitionController.dragDownAmount = 10f
+
+        verify(notificationPanelController).setKeyguardTransitionProgress(anyFloat(), anyInt())
+    }
+
+    @Test
+    fun setDragAmount_setsKeyguardAlphaBasedOnDistance() {
+        val alphaDistance = context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
+        transitionController.dragDownAmount = 10f
+
+        val expectedAlpha = 1 - 10f / alphaDistance
+        verify(notificationPanelController)
+                .setKeyguardTransitionProgress(eq(expectedAlpha), anyInt())
+    }
+
+    @Test
+    fun setDragAmount_notInSplitShade_setsKeyguardTranslationToZero() {
+        val mediaTranslationY = 123
+        disableSplitShade()
+        whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
+                .thenReturn(mediaTranslationY)
+
+        transitionController.dragDownAmount = 10f
+
+        verify(notificationPanelController).setKeyguardTransitionProgress(anyFloat(), eq(0))
+    }
+
+    @Test
+    fun setDragAmount_inSplitShade_setsKeyguardTranslationBasedOnMediaTranslation() {
+        val mediaTranslationY = 123
+        enableSplitShade()
+        whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
+                .thenReturn(mediaTranslationY)
+
+        transitionController.dragDownAmount = 10f
+
+        verify(notificationPanelController)
+                .setKeyguardTransitionProgress(anyFloat(), eq(mediaTranslationY))
+    }
+
+    @Test
     fun setDragDownAmount_setsValueOnMediaHierarchyManager() {
         transitionController.dragDownAmount = 10f
 
@@ -263,8 +320,16 @@
     }
 
     private fun enableSplitShade() {
+        setSplitShadeEnabled(true)
+    }
+
+    private fun disableSplitShade() {
+        setSplitShadeEnabled(false)
+    }
+
+    private fun setSplitShadeEnabled(enabled: Boolean) {
         context.getOrCreateTestableResources().addOverride(
-            R.bool.config_use_split_notification_shade, true
+                R.bool.config_use_split_notification_shade, enabled
         )
         configurationController.notifyConfigurationChanged()
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
index 353647b..4d89495 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
@@ -80,8 +80,8 @@
         Notification.Action firstAction =
                 createActionBuilder("same", R.drawable.ic_corp_icon, pendingIntent).build();
         Notification.Action secondAction =
-                createActionBuilder("same", R.drawable.ic_account_circle, pendingIntent)
-                        .build();
+                createActionBuilder("same", com.android.settingslib.R.drawable.ic_account_circle,
+                        pendingIntent).build();
 
         assertThat(NotificationUiAdjustment.needReinflate(
                 createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
index 3a60c04..9f82a567 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
@@ -31,6 +31,7 @@
     @Mock lateinit var notificationListContainer: NotificationListContainer
     @Mock lateinit var headsUpManager: HeadsUpManagerPhone
     @Mock lateinit var jankMonitor: InteractionJankMonitor
+    @Mock lateinit var onFinishAnimationCallback: Runnable
 
     private lateinit var notificationTestHelper: NotificationTestHelper
     private lateinit var notification: ExpandableNotificationRow
@@ -52,7 +53,8 @@
                 notificationListContainer,
                 headsUpManager,
                 notification,
-                jankMonitor
+                jankMonitor,
+                onFinishAnimationCallback
         )
     }
 
@@ -61,7 +63,7 @@
     }
 
     @Test
-    fun testHunIsRemovedIfWeDontAnimateLaunch() {
+    fun testHunIsRemovedAndCallbackIsInvokedIfWeDontAnimateLaunch() {
         flagNotificationAsHun()
         controller.onIntentStarted(willAnimate = false)
 
@@ -69,10 +71,11 @@
         assertFalse(notification.entry.isExpandAnimationRunning)
         verify(headsUpManager).removeNotification(
                 notificationKey, true /* releaseImmediately */, true /* animate */)
+        verify(onFinishAnimationCallback).run()
     }
 
     @Test
-    fun testHunIsRemovedWhenAnimationIsCancelled() {
+    fun testHunIsRemovedAndCallbackIsInvokedWhenAnimationIsCancelled() {
         flagNotificationAsHun()
         controller.onLaunchAnimationCancelled()
 
@@ -80,10 +83,11 @@
         assertFalse(notification.entry.isExpandAnimationRunning)
         verify(headsUpManager).removeNotification(
                 notificationKey, true /* releaseImmediately */, true /* animate */)
+        verify(onFinishAnimationCallback).run()
     }
 
     @Test
-    fun testHunIsRemovedWhenAnimationEnds() {
+    fun testHunIsRemovedAndCallbackIsInvokedWhenAnimationEnds() {
         flagNotificationAsHun()
         controller.onLaunchAnimationEnd(isExpandingFullyAbove = true)
 
@@ -91,6 +95,7 @@
         assertFalse(notification.entry.isExpandAnimationRunning)
         verify(headsUpManager).removeNotification(
                 notificationKey, true /* releaseImmediately */, false /* animate */)
+        verify(onFinishAnimationCallback).run()
     }
 
     @Test
@@ -99,4 +104,4 @@
 
         assertTrue(notification.entry.isExpandAnimationRunning)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinatorTest.kt
new file mode 100644
index 0000000..c6c043a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ActivityLaunchAnimCoordinatorTest.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.coordinator
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender
+import com.android.systemui.statusbar.phone.NotifActivityLaunchEvents
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.withArgCaptor
+import dagger.BindsInstance
+import dagger.Component
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+class ActivityLaunchAnimCoordinatorTest : SysuiTestCase() {
+
+    val activityLaunchEvents: NotifActivityLaunchEvents = mock()
+    val pipeline: NotifPipeline = mock()
+
+    val coordinator: ActivityLaunchAnimCoordinator =
+            DaggerTestActivityStarterCoordinatorComponent
+                    .factory()
+                    .create(activityLaunchEvents)
+                    .coordinator
+
+    @Test
+    fun testNoLifetimeExtensionIfNoAssociatedActivityLaunch() {
+        coordinator.attach(pipeline)
+        val lifetimeExtender = withArgCaptor<NotifLifetimeExtender> {
+            verify(pipeline).addNotificationLifetimeExtender(capture())
+        }
+        val fakeEntry = mock<NotificationEntry>().also {
+            whenever(it.key).thenReturn("0")
+        }
+        assertFalse(lifetimeExtender.maybeExtendLifetime(fakeEntry, 0))
+    }
+
+    @Test
+    fun testNoLifetimeExtensionIfAssociatedActivityLaunchAlreadyEnded() {
+        coordinator.attach(pipeline)
+        val lifetimeExtender = withArgCaptor<NotifLifetimeExtender> {
+            verify(pipeline).addNotificationLifetimeExtender(capture())
+        }
+        val eventListener = withArgCaptor<NotifActivityLaunchEvents.Listener> {
+            verify(activityLaunchEvents).registerListener(capture())
+        }
+        val fakeEntry = mock<NotificationEntry>().also {
+            whenever(it.key).thenReturn("0")
+        }
+        eventListener.onStartLaunchNotifActivity(fakeEntry)
+        eventListener.onFinishLaunchNotifActivity(fakeEntry)
+        assertFalse(lifetimeExtender.maybeExtendLifetime(fakeEntry, 0))
+    }
+
+    @Test
+    fun testLifetimeExtensionWhileActivityLaunchInProgress() {
+        coordinator.attach(pipeline)
+        val lifetimeExtender = withArgCaptor<NotifLifetimeExtender> {
+            verify(pipeline).addNotificationLifetimeExtender(capture())
+        }
+        val eventListener = withArgCaptor<NotifActivityLaunchEvents.Listener> {
+            verify(activityLaunchEvents).registerListener(capture())
+        }
+        val onEndLifetimeExtensionCallback =
+                mock<NotifLifetimeExtender.OnEndLifetimeExtensionCallback>()
+        lifetimeExtender.setCallback(onEndLifetimeExtensionCallback)
+
+        val fakeEntry = mock<NotificationEntry>().also {
+            whenever(it.key).thenReturn("0")
+        }
+        eventListener.onStartLaunchNotifActivity(fakeEntry)
+        assertTrue(lifetimeExtender.maybeExtendLifetime(fakeEntry, 0))
+
+        eventListener.onFinishLaunchNotifActivity(fakeEntry)
+        verify(onEndLifetimeExtensionCallback).onEndLifetimeExtension(lifetimeExtender, fakeEntry)
+    }
+
+    @Test
+    fun testCancelLifetimeExtensionDoesNotInvokeCallback() {
+        coordinator.attach(pipeline)
+        val lifetimeExtender = withArgCaptor<NotifLifetimeExtender> {
+            verify(pipeline).addNotificationLifetimeExtender(capture())
+        }
+        val eventListener = withArgCaptor<NotifActivityLaunchEvents.Listener> {
+            verify(activityLaunchEvents).registerListener(capture())
+        }
+        val onEndLifetimeExtensionCallback =
+                mock<NotifLifetimeExtender.OnEndLifetimeExtensionCallback>()
+        lifetimeExtender.setCallback(onEndLifetimeExtensionCallback)
+
+        val fakeEntry = mock<NotificationEntry>().also {
+            whenever(it.key).thenReturn("0")
+        }
+        eventListener.onStartLaunchNotifActivity(fakeEntry)
+        assertTrue(lifetimeExtender.maybeExtendLifetime(fakeEntry, 0))
+
+        lifetimeExtender.cancelLifetimeExtension(fakeEntry)
+        eventListener.onFinishLaunchNotifActivity(fakeEntry)
+        verify(onEndLifetimeExtensionCallback, never())
+                .onEndLifetimeExtension(lifetimeExtender, fakeEntry)
+    }
+}
+
+@CoordinatorScope
+@Component(modules = [ActivityLaunchAnimCoordinatorModule::class])
+interface TestActivityStarterCoordinatorComponent {
+    val coordinator: ActivityLaunchAnimCoordinator
+
+    @Component.Factory
+    interface Factory {
+        fun create(
+            @BindsInstance activityLaunchEvents: NotifActivityLaunchEvents
+        ): TestActivityStarterCoordinatorComponent
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java
deleted file mode 100644
index 1f52b9c..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.collection.coordinator;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.communal.CommunalStateController;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotifPipeline;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
-import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-
-@SmallTest
-public class CommunalCoordinatorTest extends SysuiTestCase {
-    private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
-
-    @Mock
-    CommunalStateController mCommunalStateController;
-    @Mock
-    NotificationEntryManager mNotificationEntryManager;
-    @Mock
-    NotificationLockscreenUserManager mNotificationLockscreenUserManager;
-    @Mock
-    NotifPipeline mNotifPipeline;
-    @Mock
-    NotificationEntry mNotificationEntry;
-    @Mock
-    Pluggable.PluggableListener mFilterListener;
-
-    CommunalCoordinator mCoordinator;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mCoordinator = new CommunalCoordinator(mExecutor, mNotificationEntryManager,
-                mNotificationLockscreenUserManager, mCommunalStateController);
-    }
-
-    @Test
-    public void testNotificationSuppressionInCommunal() {
-        mCoordinator.attach(mNotifPipeline);
-        final ArgumentCaptor<CommunalStateController.Callback> stateCallbackCaptor =
-                ArgumentCaptor.forClass(CommunalStateController.Callback.class);
-        verify(mCommunalStateController).addCallback(stateCallbackCaptor.capture());
-
-        final CommunalStateController.Callback stateCallback = stateCallbackCaptor.getValue();
-
-        final ArgumentCaptor<NotifFilter> filterCaptor =
-                ArgumentCaptor.forClass(NotifFilter.class);
-        verify(mNotifPipeline).addPreGroupFilter(filterCaptor.capture());
-
-        final NotifFilter filter = filterCaptor.getValue();
-
-        // Verify that notifications are not filtered out by default.
-        assertThat(filter.shouldFilterOut(mNotificationEntry, 0)).isFalse();
-
-        filter.setInvalidationListener(mFilterListener);
-
-        // Verify that notifications are filtered out when communal is showing and that the filter
-        // pipeline is notified.
-        when(mCommunalStateController.getCommunalViewShowing()).thenReturn(true);
-        stateCallback.onCommunalViewShowingChanged();
-        // Make sure callback depends on executor to run.
-        verify(mFilterListener, never()).onPluggableInvalidated(any());
-        verify(mNotificationEntryManager, never()).updateNotifications(any());
-
-        mExecutor.runAllReady();
-
-        verify(mFilterListener).onPluggableInvalidated(any());
-        verify(mNotificationEntryManager).updateNotifications(any());
-        assertThat(filter.shouldFilterOut(mNotificationEntry, 0)).isTrue();
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
index 144eefb..699f77f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
@@ -170,11 +170,41 @@
     }
 
     @Test
+    fun testCancelAndReAddStickyNotification() {
+        whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true)
+        addHUN(mEntry)
+        whenever(mHeadsUpManager.canRemoveImmediately(anyString())).thenReturn(false, true, false)
+        whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L)
+        assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0))
+        addHUN(mEntry)
+        assertFalse(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0))
+        mExecutor.advanceClockToLast()
+        mExecutor.runAllReady()
+        assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0))
+        verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(false))
+        verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(true))
+    }
+
+    @Test
+    fun hunNotRemovedWhenExtensionCancelled() {
+        whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true)
+        addHUN(mEntry)
+        whenever(mHeadsUpManager.canRemoveImmediately(anyString())).thenReturn(false)
+        whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L)
+        assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0))
+        mNotifLifetimeExtender.cancelLifetimeExtension(mEntry)
+        mExecutor.advanceClockToLast()
+        mExecutor.runAllReady()
+        verify(mHeadsUpManager, times(0)).removeNotification(anyString(), any())
+    }
+
+    @Test
     fun testCancelUpdatedStickyNotification() {
         whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true)
         addHUN(mEntry)
         whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L, 500L)
         assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0))
+        addHUN(mEntry)
         mExecutor.advanceClockToLast()
         mExecutor.runAllReady()
         verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(false))
@@ -305,6 +335,7 @@
         mHuns.add(entry)
         whenever(mHeadsUpManager.topEntry).thenReturn(entry)
         mOnHeadsUpChangedListener.onHeadsUpStateChanged(entry, true)
+        mNotifLifetimeExtender.cancelLifetimeExtension(entry)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java
index d094749..52bacd2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java
@@ -16,18 +16,8 @@
 
 package com.android.systemui.statusbar.notification.collection.coordinator;
 
-import static android.app.Notification.VISIBILITY_PUBLIC;
-import static android.app.Notification.VISIBILITY_SECRET;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-
-import static com.android.systemui.statusbar.notification.collection.EntryUtilKt.modifyEntry;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.os.Handler;
 import android.os.UserHandle;
@@ -39,40 +29,41 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.RankingBuilder;
 import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider;
-import com.android.systemui.statusbar.notification.collection.GroupEntry;
-import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Before;
-import org.junit.Test;
+import org.junit.Ignore;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+/**
+ * TODO(b/224771204) Create test cases
+ */
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
+@Ignore
 public class KeyguardCoordinatorTest extends SysuiTestCase {
     private static final int NOTIF_USER_ID = 0;
     private static final int CURR_USER_ID = 1;
 
     @Mock private Handler mMainHandler;
     @Mock private KeyguardStateController mKeyguardStateController;
-    @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
     @Mock private BroadcastDispatcher mBroadcastDispatcher;
     @Mock private StatusBarStateController mStatusBarStateController;
     @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @Mock private HighPriorityProvider mHighPriorityProvider;
     @Mock private SectionHeaderVisibilityProvider mSectionHeaderVisibilityProvider;
     @Mock private NotifPipeline mNotifPipeline;
+    @Mock private KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;
 
     private NotificationEntry mEntry;
     private NotifFilter mKeyguardFilter;
@@ -81,9 +72,9 @@
     public void setup() {
         MockitoAnnotations.initMocks(this);
         KeyguardCoordinator keyguardCoordinator = new KeyguardCoordinator(
-                mContext, mMainHandler, mKeyguardStateController, mLockscreenUserManager,
-                mBroadcastDispatcher, mStatusBarStateController,
-                mKeyguardUpdateMonitor, mHighPriorityProvider, mSectionHeaderVisibilityProvider);
+                mStatusBarStateController,
+                mKeyguardUpdateMonitor, mHighPriorityProvider, mSectionHeaderVisibilityProvider,
+                mKeyguardNotificationVisibilityProvider);
 
         mEntry = new NotificationEntryBuilder()
                 .setUser(new UserHandle(NOTIF_USER_ID))
@@ -94,171 +85,4 @@
         verify(mNotifPipeline, times(1)).addFinalizeFilter(filterCaptor.capture());
         mKeyguardFilter = filterCaptor.getValue();
     }
-
-    @Test
-    public void unfilteredState() {
-        // GIVEN an 'unfiltered-keyguard-showing' state
-        setupUnfilteredState(mEntry);
-
-        // THEN don't filter out the entry
-        assertFalse(mKeyguardFilter.shouldFilterOut(mEntry, 0));
-    }
-
-    @Test
-    public void keyguardNotShowing() {
-        // GIVEN the lockscreen isn't showing
-        setupUnfilteredState(mEntry);
-        when(mKeyguardStateController.isShowing()).thenReturn(false);
-
-        // THEN don't filter out the entry
-        assertFalse(mKeyguardFilter.shouldFilterOut(mEntry, 0));
-    }
-
-    @Test
-    public void doNotShowLockscreenNotifications() {
-        // GIVEN an 'unfiltered-keyguard-showing' state
-        setupUnfilteredState(mEntry);
-
-        // WHEN we shouldn't show any lockscreen notifications
-        when(mLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false);
-
-        // THEN filter out the entry
-        assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0));
-    }
-
-    @Test
-    public void lockdown() {
-        // GIVEN an 'unfiltered-keyguard-showing' state
-        setupUnfilteredState(mEntry);
-
-        // WHEN the notification's user is in lockdown:
-        when(mKeyguardUpdateMonitor.isUserInLockdown(NOTIF_USER_ID)).thenReturn(true);
-
-        // THEN filter out the entry
-        assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0));
-    }
-
-    @Test
-    public void publicMode_settingsDisallow() {
-        // GIVEN an 'unfiltered-keyguard-showing' state
-        setupUnfilteredState(mEntry);
-
-        // WHEN the notification's user is in public mode and settings are configured to disallow
-        // notifications in public mode
-        when(mLockscreenUserManager.isLockscreenPublicMode(NOTIF_USER_ID)).thenReturn(true);
-        when(mLockscreenUserManager.userAllowsNotificationsInPublic(NOTIF_USER_ID))
-                .thenReturn(false);
-
-        // THEN filter out the entry
-        assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0));
-    }
-
-    @Test
-    public void publicMode_notifDisallowed() {
-        // GIVEN an 'unfiltered-keyguard-showing' state
-        setupUnfilteredState(mEntry);
-
-        // WHEN the notification's user is in public mode and settings are configured to disallow
-        // notifications in public mode
-        when(mLockscreenUserManager.isLockscreenPublicMode(CURR_USER_ID)).thenReturn(true);
-        mEntry.setRanking(new RankingBuilder()
-                .setKey(mEntry.getKey())
-                .setVisibilityOverride(VISIBILITY_SECRET).build());
-
-        // THEN filter out the entry
-        assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0));
-    }
-
-    @Test
-    public void doesNotExceedThresholdToShow() {
-        // GIVEN an 'unfiltered-keyguard-showing' state
-        setupUnfilteredState(mEntry);
-
-        // WHEN the notification doesn't exceed the threshold to show on the lockscreen
-        mEntry.setRanking(new RankingBuilder()
-                .setKey(mEntry.getKey())
-                .setImportance(IMPORTANCE_MIN)
-                .build());
-        when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false);
-
-        // THEN filter out the entry
-        assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0));
-    }
-
-    @Test
-    public void summaryExceedsThresholdToShow() {
-        // GIVEN the notification doesn't exceed the threshold to show on the lockscreen
-        // but it's part of a group (has a parent)
-        final NotificationEntry entryWithParent = new NotificationEntryBuilder()
-                .setUser(new UserHandle(NOTIF_USER_ID))
-                .build();
-
-        final GroupEntry parent = new GroupEntryBuilder()
-                .setKey("test_group_key")
-                .setSummary(new NotificationEntryBuilder()
-                        .setImportance(IMPORTANCE_HIGH)
-                        .build())
-                .addChild(entryWithParent)
-                .build();
-
-        setupUnfilteredState(entryWithParent);
-        entryWithParent.setRanking(new RankingBuilder()
-                .setKey(entryWithParent.getKey())
-                .setImportance(IMPORTANCE_MIN)
-                .build());
-
-        // WHEN its parent does exceed threshold tot show on the lockscreen
-        when(mHighPriorityProvider.isHighPriority(parent)).thenReturn(true);
-
-        // THEN don't filter out the entry
-        assertFalse(mKeyguardFilter.shouldFilterOut(entryWithParent, 0));
-
-        // WHEN its parent doesn't exceed threshold to show on lockscreen
-        when(mHighPriorityProvider.isHighPriority(parent)).thenReturn(false);
-        modifyEntry(parent.getSummary(), builder -> builder
-                .setImportance(IMPORTANCE_MIN)
-                .done());
-
-        // THEN filter out the entry
-        assertTrue(mKeyguardFilter.shouldFilterOut(entryWithParent, 0));
-    }
-
-    /**
-     * setup a state where the notification will not be filtered by the
-     * KeyguardNotificationCoordinator when the keyguard is showing.
-     */
-    private void setupUnfilteredState(NotificationEntry entry) {
-        // keyguard is showing
-        when(mKeyguardStateController.isShowing()).thenReturn(true);
-
-        // show notifications on the lockscreen
-        when(mLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(true);
-
-        // neither the current user nor the notification's user is in lockdown
-        when(mLockscreenUserManager.getCurrentUserId()).thenReturn(CURR_USER_ID);
-        when(mKeyguardUpdateMonitor.isUserInLockdown(NOTIF_USER_ID)).thenReturn(false);
-        when(mKeyguardUpdateMonitor.isUserInLockdown(CURR_USER_ID)).thenReturn(false);
-
-        // not in public mode
-        when(mLockscreenUserManager.isLockscreenPublicMode(CURR_USER_ID)).thenReturn(false);
-        when(mLockscreenUserManager.isLockscreenPublicMode(NOTIF_USER_ID)).thenReturn(false);
-
-        // entry's ranking - should show on all lockscreens
-        // + priority of the notification exceeds the threshold to be shown on the lockscreen
-        entry.setRanking(new RankingBuilder()
-                .setKey(mEntry.getKey())
-                .setVisibilityOverride(VISIBILITY_PUBLIC)
-                .setImportance(IMPORTANCE_HIGH)
-                .build());
-
-        // settings allows notifications in public mode
-        when(mLockscreenUserManager.userAllowsNotificationsInPublic(CURR_USER_ID)).thenReturn(true);
-        when(mLockscreenUserManager.userAllowsNotificationsInPublic(NOTIF_USER_ID))
-                .thenReturn(true);
-
-        // notification doesn't have a summary
-
-        // notification is high priority, so it shouldn't be filtered
-        when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(true);
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
index ee11171..6f8e5d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
@@ -41,7 +41,7 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
-import com.android.systemui.statusbar.notification.collection.render.NotifPanelEventSource;
+import com.android.systemui.statusbar.phone.NotifPanelEvents;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
@@ -67,12 +67,12 @@
     @Mock private StatusBarStateController mStatusBarStateController;
     @Mock private Pluggable.PluggableListener<NotifStabilityManager> mInvalidateListener;
     @Mock private HeadsUpManager mHeadsUpManager;
-    @Mock private NotifPanelEventSource mNotifPanelEventSource;
+    @Mock private NotifPanelEvents mNotifPanelEvents;
     @Mock private VisualStabilityProvider mVisualStabilityProvider;
 
     @Captor private ArgumentCaptor<WakefulnessLifecycle.Observer> mWakefulnessObserverCaptor;
     @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mSBStateListenerCaptor;
-    @Captor private ArgumentCaptor<NotifPanelEventSource.Callbacks> mNotifPanelEventsCallbackCaptor;
+    @Captor private ArgumentCaptor<NotifPanelEvents.Listener> mNotifPanelEventsCallbackCaptor;
     @Captor private ArgumentCaptor<NotifStabilityManager> mNotifStabilityManagerCaptor;
 
     private FakeSystemClock mFakeSystemClock = new FakeSystemClock();
@@ -80,7 +80,7 @@
 
     private WakefulnessLifecycle.Observer mWakefulnessObserver;
     private StatusBarStateController.StateListener mStatusBarStateListener;
-    private NotifPanelEventSource.Callbacks mNotifPanelEventsCallback;
+    private NotifPanelEvents.Listener mNotifPanelEventsCallback;
     private NotifStabilityManager mNotifStabilityManager;
     private NotificationEntry mEntry;
 
@@ -92,7 +92,7 @@
                 mFakeExecutor,
                 mDumpManager,
                 mHeadsUpManager,
-                mNotifPanelEventSource,
+                mNotifPanelEvents,
                 mStatusBarStateController,
                 mVisualStabilityProvider,
                 mWakefulnessLifecycle);
@@ -106,7 +106,7 @@
         verify(mStatusBarStateController).addCallback(mSBStateListenerCaptor.capture());
         mStatusBarStateListener = mSBStateListenerCaptor.getValue();
 
-        verify(mNotifPanelEventSource).registerCallbacks(mNotifPanelEventsCallbackCaptor.capture());
+        verify(mNotifPanelEvents).registerListener(mNotifPanelEventsCallbackCaptor.capture());
         mNotifPanelEventsCallback = mNotifPanelEventsCallbackCaptor.getValue();
 
         verify(mNotifPipeline).setVisualStabilityManager(mNotifStabilityManagerCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
new file mode 100644
index 0000000..de9ea27
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.interruption;
+
+import static android.app.Notification.VISIBILITY_PUBLIC;
+import static android.app.Notification.VISIBILITY_SECRET;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+
+import static com.android.systemui.statusbar.notification.collection.EntryUtilKt.modifyEntry;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.os.Handler;
+import android.os.UserHandle;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.RankingBuilder;
+import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider;
+import com.android.systemui.statusbar.notification.collection.GroupEntry;
+import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class KeyguardNotificationVisibilityProviderTest  extends SysuiTestCase {
+    private static final int NOTIF_USER_ID = 0;
+    private static final int CURR_USER_ID = 1;
+
+    @Mock
+    private Handler mMainHandler;
+    @Mock private KeyguardStateController mKeyguardStateController;
+    @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
+    @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    @Mock private HighPriorityProvider mHighPriorityProvider;
+    @Mock private SectionHeaderVisibilityProvider mSectionHeaderVisibilityProvider;
+    @Mock private KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;
+    @Mock private StatusBarStateController mStatusBarStateController;
+    @Mock private BroadcastDispatcher mBroadcastDispatcher;
+
+    private NotificationEntry mEntry;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        // TODO refactor the test of KeyguardNotificationVisibilityProvider out
+        mKeyguardNotificationVisibilityProvider = spy(new KeyguardNotificationVisibilityProvider(
+                mContext,
+                mMainHandler,
+                mKeyguardStateController,
+                mLockscreenUserManager,
+                mKeyguardUpdateMonitor,
+                mHighPriorityProvider,
+                mStatusBarStateController,
+                mBroadcastDispatcher
+        ));
+
+        mEntry = new NotificationEntryBuilder()
+                .setUser(new UserHandle(NOTIF_USER_ID))
+                .build();
+    }
+
+    @Test
+    public void unfilteredState() {
+        // GIVEN an 'unfiltered-keyguard-showing' state
+        setupUnfilteredState(mEntry);
+
+        // THEN don't filter out the entry
+        assertFalse(mKeyguardNotificationVisibilityProvider.hideNotification(mEntry));
+    }
+
+    @Test
+    public void keyguardNotShowing() {
+        // GIVEN the lockscreen isn't showing
+        setupUnfilteredState(mEntry);
+        when(mKeyguardStateController.isShowing()).thenReturn(false);
+
+        // THEN don't filter out the entry
+        assertFalse(mKeyguardNotificationVisibilityProvider.hideNotification(mEntry));
+    }
+
+    @Test
+    public void doNotShowLockscreenNotifications() {
+        // GIVEN an 'unfiltered-keyguard-showing' state
+        setupUnfilteredState(mEntry);
+
+        // WHEN we shouldn't show any lockscreen notifications
+        when(mLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false);
+
+        // THEN filter out the entry
+        assertTrue(mKeyguardNotificationVisibilityProvider.hideNotification(mEntry));
+    }
+
+    @Test
+    public void lockdown() {
+        // GIVEN an 'unfiltered-keyguard-showing' state
+        setupUnfilteredState(mEntry);
+
+        // WHEN the notification's user is in lockdown:
+        when(mKeyguardUpdateMonitor.isUserInLockdown(NOTIF_USER_ID)).thenReturn(true);
+
+        // THEN filter out the entry
+        assertTrue(mKeyguardNotificationVisibilityProvider.hideNotification(mEntry));
+    }
+
+    @Test
+    public void publicMode_settingsDisallow() {
+        // GIVEN an 'unfiltered-keyguard-showing' state
+        setupUnfilteredState(mEntry);
+
+        // WHEN the notification's user is in public mode and settings are configured to disallow
+        // notifications in public mode
+        when(mLockscreenUserManager.isLockscreenPublicMode(NOTIF_USER_ID)).thenReturn(true);
+        when(mLockscreenUserManager.userAllowsNotificationsInPublic(NOTIF_USER_ID))
+                .thenReturn(false);
+
+        // THEN filter out the entry
+        assertTrue(mKeyguardNotificationVisibilityProvider.hideNotification(mEntry));
+    }
+
+    @Test
+    public void publicMode_notifDisallowed() {
+        // GIVEN an 'unfiltered-keyguard-showing' state
+        setupUnfilteredState(mEntry);
+
+        // WHEN the notification's user is in public mode and settings are configured to disallow
+        // notifications in public mode
+        when(mLockscreenUserManager.isLockscreenPublicMode(CURR_USER_ID)).thenReturn(true);
+        mEntry.setRanking(new RankingBuilder()
+                .setKey(mEntry.getKey())
+                .setVisibilityOverride(VISIBILITY_SECRET).build());
+
+        // THEN filter out the entry
+        assertTrue(mKeyguardNotificationVisibilityProvider.hideNotification(mEntry));
+    }
+
+    @Test
+    public void doesNotExceedThresholdToShow() {
+        // GIVEN an 'unfiltered-keyguard-showing' state
+        setupUnfilteredState(mEntry);
+
+        // WHEN the notification doesn't exceed the threshold to show on the lockscreen
+        mEntry.setRanking(new RankingBuilder()
+                .setKey(mEntry.getKey())
+                .setImportance(IMPORTANCE_MIN)
+                .build());
+        when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false);
+
+        // THEN filter out the entry
+        assertTrue(mKeyguardNotificationVisibilityProvider.hideNotification(mEntry));
+    }
+
+    @Test
+    public void summaryExceedsThresholdToShow() {
+        // GIVEN the notification doesn't exceed the threshold to show on the lockscreen
+        // but it's part of a group (has a parent)
+        final NotificationEntry entryWithParent = new NotificationEntryBuilder()
+                .setUser(new UserHandle(NOTIF_USER_ID))
+                .build();
+
+        final GroupEntry parent = new GroupEntryBuilder()
+                .setKey("test_group_key")
+                .setSummary(new NotificationEntryBuilder()
+                        .setImportance(IMPORTANCE_HIGH)
+                        .build())
+                .addChild(entryWithParent)
+                .build();
+
+        setupUnfilteredState(entryWithParent);
+        entryWithParent.setRanking(new RankingBuilder()
+                .setKey(entryWithParent.getKey())
+                .setImportance(IMPORTANCE_MIN)
+                .build());
+
+        // WHEN its parent does exceed threshold tot show on the lockscreen
+        when(mHighPriorityProvider.isHighPriority(parent)).thenReturn(true);
+
+        // THEN don't filter out the entry
+        assertFalse(mKeyguardNotificationVisibilityProvider.hideNotification(entryWithParent));
+
+        // WHEN its parent doesn't exceed threshold to show on lockscreen
+        when(mHighPriorityProvider.isHighPriority(parent)).thenReturn(false);
+        modifyEntry(parent.getSummary(), builder -> builder
+                .setImportance(IMPORTANCE_MIN)
+                .done());
+
+        // THEN filter out the entry
+        assertTrue(mKeyguardNotificationVisibilityProvider.hideNotification(entryWithParent));
+    }
+
+    /**
+     * setup a state where the notification will not be filtered by the
+     * KeyguardNotificationCoordinator when the keyguard is showing.
+     */
+    private void setupUnfilteredState(NotificationEntry entry) {
+        // keyguard is showing
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+
+        // show notifications on the lockscreen
+        when(mLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(true);
+
+        // neither the current user nor the notification's user is in lockdown
+        when(mLockscreenUserManager.getCurrentUserId()).thenReturn(CURR_USER_ID);
+        when(mKeyguardUpdateMonitor.isUserInLockdown(NOTIF_USER_ID)).thenReturn(false);
+        when(mKeyguardUpdateMonitor.isUserInLockdown(CURR_USER_ID)).thenReturn(false);
+
+        // not in public mode
+        when(mLockscreenUserManager.isLockscreenPublicMode(CURR_USER_ID)).thenReturn(false);
+        when(mLockscreenUserManager.isLockscreenPublicMode(NOTIF_USER_ID)).thenReturn(false);
+
+        // entry's ranking - should show on all lockscreens
+        // + priority of the notification exceeds the threshold to be shown on the lockscreen
+        entry.setRanking(new RankingBuilder()
+                .setKey(mEntry.getKey())
+                .setVisibilityOverride(VISIBILITY_PUBLIC)
+                .setImportance(IMPORTANCE_HIGH)
+                .build());
+
+        // settings allows notifications in public mode
+        when(mLockscreenUserManager.userAllowsNotificationsInPublic(CURR_USER_ID)).thenReturn(true);
+        when(mLockscreenUserManager.userAllowsNotificationsInPublic(NOTIF_USER_ID))
+                .thenReturn(true);
+
+        // notification doesn't have a summary
+
+        // notification is high priority, so it shouldn't be filtered
+        when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(true);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index 2e1297b..8a2dc26 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -30,6 +30,9 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.Notification;
@@ -48,6 +51,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationFilter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -86,6 +90,10 @@
     BatteryController mBatteryController;
     @Mock
     Handler mMockHandler;
+    @Mock
+    NotifPipelineFlags mFlags;
+    @Mock
+    KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;
 
     private NotificationInterruptStateProviderImpl mNotifInterruptionStateProvider;
 
@@ -104,8 +112,9 @@
                         mStatusBarStateController,
                         mHeadsUpManager,
                         mLogger,
-                        mMockHandler);
-
+                        mMockHandler,
+                        mFlags,
+                        mKeyguardNotificationVisibilityProvider);
         mNotifInterruptionStateProvider.mUseHeadsUp = true;
     }
 
@@ -194,6 +203,16 @@
     }
 
     @Test
+    public void testDoNotRunFilterOnNewPipeline() {
+        when(mFlags.isNewPipelineEnabled()).thenReturn(true);
+        // WHEN this entry should be filtered out
+        NotificationEntry entry  = createNotification(IMPORTANCE_DEFAULT);
+        mNotifInterruptionStateProvider.shouldHeadsUp(entry);
+        verify(mFlags, times(1)).isNewPipelineEnabled();
+        verify(mNotificationFilter, times(0)).shouldFilterOut(eq(entry));
+    }
+
+    @Test
     public void testShouldNotHeadsUp_suppressedForGroups() throws RemoteException {
         // GIVEN state for "heads up when awake" is true
         ensureStateForHeadsUpWhenAwake();
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 1561b5a..bf16e0a 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
@@ -69,11 +69,11 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController.NotificationPanelEvent;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -278,18 +278,17 @@
                 mStateListenerArgumentCaptor.capture(), anyInt());
         StatusBarStateController.StateListener stateListener =
                 mStateListenerArgumentCaptor.getValue();
-        when(mNotificationStackScrollLayout.isUsingSplitNotificationShade()).thenReturn(true);
         stateListener.onStateChanged(SHADE);
         mController.getView().removeAllViews();
 
-        mController.setQsExpanded(false);
+        mController.setQsFullScreen(false);
         reset(mNotificationStackScrollLayout);
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
                 /* visible= */ true,
                 /* notifVisibleInShade= */ false);
 
-        mController.setQsExpanded(true);
+        mController.setQsFullScreen(true);
         reset(mNotificationStackScrollLayout);
         mController.updateShowEmptyShadeView();
         verify(mNotificationStackScrollLayout).updateEmptyShadeView(
@@ -411,11 +410,11 @@
             boolean toShow) {
         if (toShow) {
             statusBarStateListener.onStateChanged(SHADE);
-            mController.setQsExpanded(false);
+            mController.setQsFullScreen(false);
             mController.getView().removeAllViews();
         } else {
             statusBarStateListener.onStateChanged(KEYGUARD);
-            mController.setQsExpanded(true);
+            mController.setQsFullScreen(true);
             mController.getView().addContainerView(mock(ExpandableNotificationRow.class));
         }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesTest.java
index 3810783..c72f895 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesTest.java
@@ -131,6 +131,7 @@
 import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
+import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
@@ -309,7 +310,9 @@
                         mDreamManager, mAmbientDisplayConfiguration, mNotificationFilter,
                         mStatusBarStateController, mBatteryController, mHeadsUpManager,
                         mock(NotificationInterruptLogger.class),
-                        new Handler(TestableLooper.get(this).getLooper()));
+                        new Handler(TestableLooper.get(this).getLooper()),
+                        mock(NotifPipelineFlags.class),
+                        mock(KeyguardNotificationVisibilityProvider.class));
 
         mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
         mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
@@ -994,9 +997,12 @@
                 BatteryController batteryController,
                 HeadsUpManager headsUpManager,
                 NotificationInterruptLogger logger,
-                Handler mainHandler) {
+                Handler mainHandler,
+                NotifPipelineFlags flags,
+                KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider) {
             super(contentResolver, powerManager, dreamManager, ambientDisplayConfiguration, filter,
-                    batteryController, controller, headsUpManager, logger, mainHandler);
+                    batteryController, controller, headsUpManager, logger, mainHandler,
+                    flags, keyguardNotificationVisibilityProvider);
             mUseHeadsUp = true;
         }
     }
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 1af7035..4bac08e 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
@@ -28,7 +28,6 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeast;
@@ -57,13 +56,11 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.ViewPropertyAnimator;
 import android.view.ViewStub;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 
-import androidx.constraintlayout.widget.ConstraintLayout;
 import androidx.constraintlayout.widget.ConstraintSet;
 import androidx.test.filters.SmallTest;
 
@@ -88,12 +85,6 @@
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.classifier.FalsingCollectorFake;
 import com.android.systemui.classifier.FalsingManagerFake;
-import com.android.systemui.communal.CommunalHostView;
-import com.android.systemui.communal.CommunalHostViewController;
-import com.android.systemui.communal.CommunalSource;
-import com.android.systemui.communal.CommunalSourceMonitor;
-import com.android.systemui.communal.CommunalStateController;
-import com.android.systemui.communal.dagger.CommunalViewComponent;
 import com.android.systemui.controls.dagger.ControlsComponent;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.dump.DumpManager;
@@ -157,7 +148,6 @@
 import org.mockito.MockitoAnnotations;
 import org.mockito.stubbing.Answer;
 
-import java.lang.ref.WeakReference;
 import java.util.List;
 import java.util.Optional;
 
@@ -271,21 +261,6 @@
     @Mock
     private KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
     @Mock
-    private CommunalViewComponent.Factory mCommunalViewComponentFactory;
-    @Mock
-    private CommunalViewComponent mCommunalViewComponent;
-    @Mock
-    private CommunalHostViewController mCommunalHostViewController;
-    @Mock
-    private CommunalSourceMonitor mCommunalSourceMonitor;
-    @Mock
-    private CommunalSource mCommunalSource;
-    @Mock
-    private CommunalHostView mCommunalHostView;
-    @Mock
-    private CommunalStateController mCommunalStateController;
-    private CommunalStateController.Callback mCommunalStateControllerCallback;
-    @Mock
     private KeyguardClockSwitchController mKeyguardClockSwitchController;
     @Mock
     private KeyguardStatusViewController mKeyguardStatusViewController;
@@ -361,6 +336,7 @@
     private SysUiState mSysUiState;
     @Mock
     private NotificationListContainer mNotificationListContainer;
+    private NotificationPanelViewController.PanelEventsEmitter mPanelEventsEmitter;
     private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
     private SysuiStatusBarStateController mStatusBarStateController;
     private NotificationPanelViewController mNotificationPanelViewController;
@@ -400,7 +376,6 @@
         when(mView.findViewById(R.id.keyguard_clock_container)).thenReturn(mKeyguardClockSwitch);
         when(mView.findViewById(R.id.notification_stack_scroller))
                 .thenReturn(mNotificationStackScrollLayout);
-        when(mView.findViewById(R.id.communal_host)).thenReturn(mCommunalHostView);
         when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000);
         when(mNotificationStackScrollLayoutController.getHeadsUpCallback())
                 .thenReturn(mHeadsUpCallback);
@@ -412,8 +387,6 @@
         when(mView.findViewById(R.id.keyguard_status_view))
                 .thenReturn(mock(KeyguardStatusView.class));
         mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null);
-        mNotificationContainerParent.addView(newViewWithId(R.id.qs_frame));
-        mNotificationContainerParent.addView(newViewWithId(R.id.notification_stack_scroller));
         mNotificationContainerParent.addView(mKeyguardStatusView);
         mNotificationContainerParent.onFinishInflate();
         when(mView.findViewById(R.id.notification_container_parent))
@@ -466,10 +439,6 @@
                 .thenReturn(mKeyguardStatusBarViewComponent);
         when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
                 .thenReturn(mKeyguardStatusBarViewController);
-        when(mCommunalViewComponentFactory.build(any()))
-                .thenReturn(mCommunalViewComponent);
-        when(mCommunalViewComponent.getCommunalHostViewController())
-                .thenReturn(mCommunalHostViewController);
         when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean()))
                 .thenReturn(mKeyguardStatusView);
         when(mLayoutInflater.inflate(eq(R.layout.keyguard_user_switcher), any(), anyBoolean()))
@@ -488,6 +457,7 @@
         }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
 
         mMainHandler = new Handler(Looper.getMainLooper());
+        mPanelEventsEmitter = new NotificationPanelViewController.PanelEventsEmitter();
 
         mNotificationPanelViewController = new NotificationPanelViewController(mView,
                 mResources,
@@ -497,13 +467,13 @@
                 coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController,
                 mFalsingManager, new FalsingCollectorFake(),
                 mNotificationLockscreenUserManager, mNotificationEntryManager,
-                mCommunalStateController, mKeyguardStateController,
+                mKeyguardStateController,
                 mStatusBarStateController,
                 mStatusBarWindowStateController,
                 mNotificationShadeWindowController,
                 mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper,
                 mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor,
-                mCommunalSourceMonitor, mMetricsLogger, mActivityManager, mConfigurationController,
+                mMetricsLogger, mActivityManager, mConfigurationController,
                 () -> flingAnimationUtilsBuilder, mStatusBarTouchableRegionManager,
                 mConversationNotificationManager, mMediaHiearchyManager,
                 mStatusBarKeyguardViewManager,
@@ -513,7 +483,6 @@
                 mKeyguardQsUserSwitchComponentFactory,
                 mKeyguardUserSwitcherComponentFactory,
                 mKeyguardStatusBarViewComponentFactory,
-                mCommunalViewComponentFactory,
                 mLockscreenShadeTransitionController,
                 mGroupManager,
                 mNotificationAreaController,
@@ -546,7 +515,8 @@
                 mQsFrameTranslateController,
                 mSysUiState,
                 mKeyguardUnlockAnimationController,
-                mNotificationListContainer);
+                mNotificationListContainer,
+                mPanelEventsEmitter);
         mNotificationPanelViewController.initDependencies(
                 mCentralSurfaces,
                 () -> {},
@@ -705,31 +675,6 @@
     }
 
     @Test
-    public void testAllChildrenOfNotificationContainer_haveIds() {
-        enableSplitShade(/* enabled= */ true);
-        mNotificationContainerParent.removeAllViews();
-        mNotificationContainerParent.addView(newViewWithId(1));
-        mNotificationContainerParent.addView(newViewWithId(View.NO_ID));
-
-        mNotificationPanelViewController.updateResources();
-
-        assertThat(mNotificationContainerParent.getChildAt(0).getId()).isEqualTo(1);
-        assertThat(mNotificationContainerParent.getChildAt(1).getId()).isNotEqualTo(View.NO_ID);
-    }
-
-    @Test
-    public void testSinglePaneShadeLayout_isAlignedToParent() {
-        enableSplitShade(/* enabled= */ false);
-
-        mNotificationPanelViewController.updateResources();
-
-        assertThat(getConstraintSetLayout(R.id.qs_frame).endToEnd)
-                .isEqualTo(ConstraintSet.PARENT_ID);
-        assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startToStart)
-                .isEqualTo(ConstraintSet.PARENT_ID);
-    }
-
-    @Test
     public void testKeyguardStatusViewInSplitShade_changesConstraintsDependingOnNotifications() {
         mStatusBarStateController.setState(KEYGUARD);
         enableSplitShade(/* enabled= */ true);
@@ -778,46 +723,6 @@
     }
 
     @Test
-    public void testSplitShadeLayout_isAlignedToGuideline() {
-        enableSplitShade(/* enabled= */ true);
-
-        mNotificationPanelViewController.updateResources();
-
-        assertThat(getConstraintSetLayout(R.id.qs_frame).endToEnd)
-                .isEqualTo(R.id.qs_edge_guideline);
-        assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startToStart)
-                .isEqualTo(R.id.qs_edge_guideline);
-    }
-
-    @Test
-    public void testSplitShadeLayout_childrenHaveInsideMarginsOfZero() {
-        enableSplitShade(/* enabled= */ true);
-
-        mNotificationPanelViewController.updateResources();
-
-        assertThat(getConstraintSetLayout(R.id.qs_frame).startMargin).isEqualTo(10);
-        assertThat(getConstraintSetLayout(R.id.qs_frame).endMargin).isEqualTo(0);
-        assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startMargin)
-                .isEqualTo(0);
-        assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).endMargin)
-                .isEqualTo(10);
-    }
-
-    @Test
-    public void testSinglePaneLayout_childrenHaveEqualMargins() {
-        enableSplitShade(/* enabled= */ false);
-
-        mNotificationPanelViewController.updateResources();
-
-        assertThat(getConstraintSetLayout(R.id.qs_frame).startMargin).isEqualTo(10);
-        assertThat(getConstraintSetLayout(R.id.qs_frame).endMargin).isEqualTo(10);
-        assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startMargin)
-                .isEqualTo(10);
-        assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).endMargin)
-                .isEqualTo(10);
-    }
-
-    @Test
     public void testCanCollapsePanelOnTouch_trueForKeyGuard() {
         mStatusBarStateController.setState(KEYGUARD);
 
@@ -1018,81 +923,6 @@
         verify(mKeyguardStatusViewController, never()).displayClock(LARGE, /* animate */ true);
     }
 
-    @Test
-    public void testCommunalhostViewControllerInit() {
-        verify(mCommunalHostViewController, times(1)).init();
-        clearInvocations(mCommunalHostViewController);
-        givenViewAttached();
-        verify(mCommunalHostViewController, never()).init();
-    }
-
-    @Test
-    public void testCommunalSourceListening() {
-        final ArgumentCaptor<CommunalSourceMonitor.Callback> monitorCallback =
-                ArgumentCaptor.forClass(CommunalSourceMonitor.Callback.class);
-
-        givenViewAttached();
-        verify(mCommunalSourceMonitor).addCallback(monitorCallback.capture());
-
-        final ArgumentCaptor<WeakReference<CommunalSource>> sourceCapture =
-                ArgumentCaptor.forClass(WeakReference.class);
-
-        monitorCallback.getValue().onSourceAvailable(new WeakReference<>(mCommunalSource));
-        mExecutor.runAllReady();
-        verify(mCommunalHostViewController).show(sourceCapture.capture());
-        assertThat(sourceCapture.getValue().get()).isEqualTo(mCommunalSource);
-
-        clearInvocations(mCommunalHostViewController);
-        givenViewDetached();
-        verify(mCommunalSourceMonitor).removeCallback(any());
-    }
-
-    @Test
-    public void testKeyguardStatusViewUpdatedWithCommunalPresence() {
-        givenViewAttached();
-
-        when(mResources.getBoolean(
-                com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true);
-        updateMultiUserSetting(true);
-
-        ArgumentCaptor<CommunalStateController.Callback> communalCallbackCapture =
-                ArgumentCaptor.forClass(CommunalStateController.Callback.class);
-        verify(mCommunalStateController).addCallback(communalCallbackCapture.capture());
-        final CommunalStateController.Callback communalStateControllerCallback =
-                communalCallbackCapture.getValue();
-
-        clearInvocations(mKeyguardStatusViewController, mKeyguardUserSwitcherController);
-        // Ensure changes in communal visibility leads to setting the keyguard status view
-        // visibility.
-        communalStateControllerCallback.onCommunalViewShowingChanged();
-        verify(mKeyguardStatusViewController).setKeyguardStatusViewVisibility(anyInt(),
-                anyBoolean(), anyBoolean(), anyInt());
-        verify(mKeyguardUserSwitcherController).setKeyguardUserSwitcherVisibility(anyInt(),
-                anyBoolean(), anyBoolean(), anyInt());
-    }
-
-    @Test
-    public void testCommunalAlphaUpdate() {
-        // Verify keyguard content alpha changes are propagate. Note the actual value set is not
-        // checked since an interpolation is applied to the incoming value.
-        mNotificationPanelViewController.setKeyguardOnlyContentAlpha(0.8f);
-        verify(mCommunalHostViewController).setAlpha(anyFloat());
-    }
-
-    @Test
-    public void testCommunalPositionUpdate() {
-        // Verify that the communal position is updated on interaction with the
-        // NotificationPanelViewController. Note that there a number of paths where the position
-        // might be updated and therefore the check isn't strictly on a single invocation.
-        clearInvocations(mCommunalHostViewController);
-        final View.OnLayoutChangeListener layoutChangeListener =
-                mNotificationPanelViewController.createLayoutChangeListener();
-        mNotificationPanelViewController.mStatusBarStateController.setState(KEYGUARD);
-        layoutChangeListener.onLayoutChange(mView, 0, 0, 200, 200, 0, 0, 200, 200);
-        verify(mCommunalHostViewController, atLeast(1))
-                .updatePosition(anyInt(), anyBoolean());
-    }
-
     private void triggerPositionClockAndNotifications() {
         mNotificationPanelViewController.closeQs();
     }
@@ -1117,17 +947,6 @@
         }
     }
 
-
-    private View newViewWithId(int id) {
-        View view = new View(mContext);
-        view.setId(id);
-        ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(
-                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-        // required as cloning ConstraintSet fails if view doesn't have layout params
-        view.setLayoutParams(layoutParams);
-        return view;
-    }
-
     private ConstraintSet.Layout getConstraintSetLayout(@IdRes int id) {
         ConstraintSet constraintSet = new ConstraintSet();
         constraintSet.clone(mNotificationContainerParent);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
index 00af446..83eabb6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
@@ -2,9 +2,16 @@
 
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import android.view.View
+import android.view.ViewGroup
 import android.view.WindowInsets
 import android.view.WindowManagerPolicyConstants
+import androidx.annotation.AnyRes
+import androidx.annotation.IdRes
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.constraintlayout.widget.ConstraintSet
 import androidx.test.filters.SmallTest
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
@@ -12,6 +19,7 @@
 import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener
 import com.android.systemui.recents.OverviewProxyService
 import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
+import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -40,6 +48,7 @@
         const val GESTURES_NAVIGATION = WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL
         const val BUTTONS_NAVIGATION = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON
         const val NOTIFICATIONS_MARGIN = 50
+        const val SCRIM_MARGIN = 10
     }
 
     @Mock
@@ -56,8 +65,10 @@
     lateinit var taskbarVisibilityCaptor: ArgumentCaptor<OverviewProxyListener>
     @Captor
     lateinit var windowInsetsCallbackCaptor: ArgumentCaptor<Consumer<WindowInsets>>
+    @Captor
+    lateinit var constraintSetCaptor: ArgumentCaptor<ConstraintSet>
 
-    private lateinit var notificationsQSContainerController: NotificationsQSContainerController
+    private lateinit var controller: NotificationsQSContainerController
     private lateinit var navigationModeCallback: ModeChangedListener
     private lateinit var taskbarVisibilityCallback: OverviewProxyListener
     private lateinit var windowInsetsCallback: Consumer<WindowInsets>
@@ -65,31 +76,41 @@
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
-        notificationsQSContainerController = NotificationsQSContainerController(
+        mContext.ensureTestableResources()
+        whenever(notificationsQSContainer.context).thenReturn(mContext)
+        whenever(notificationsQSContainer.resources).thenReturn(mContext.resources)
+        controller = NotificationsQSContainerController(
                 notificationsQSContainer,
                 navigationModeController,
                 overviewProxyService,
                 featureFlags
         )
-        whenever(notificationsQSContainer.defaultNotificationsMarginBottom)
-                .thenReturn(NOTIFICATIONS_MARGIN)
+
+        overrideResource(R.dimen.split_shade_notifications_scrim_margin_bottom, SCRIM_MARGIN)
+        overrideResource(R.dimen.notification_panel_margin_bottom, NOTIFICATIONS_MARGIN)
+        overrideResource(R.bool.config_use_split_notification_shade, false)
         whenever(navigationModeController.addListener(navigationModeCaptor.capture()))
                 .thenReturn(GESTURES_NAVIGATION)
         doNothing().`when`(overviewProxyService).addCallback(taskbarVisibilityCaptor.capture())
         doNothing().`when`(notificationsQSContainer)
                 .setInsetsChangedListener(windowInsetsCallbackCaptor.capture())
+        doNothing().`when`(notificationsQSContainer).applyConstraints(constraintSetCaptor.capture())
 
-        notificationsQSContainerController.init()
-        notificationsQSContainerController.onViewAttached()
+        controller.init()
+        controller.onViewAttached()
 
         navigationModeCallback = navigationModeCaptor.value
         taskbarVisibilityCallback = taskbarVisibilityCaptor.value
         windowInsetsCallback = windowInsetsCallbackCaptor.value
     }
 
+    private fun overrideResource(@AnyRes id: Int, value: Any) {
+        mContext.orCreateTestableResources.addOverride(id, value)
+    }
+
     @Test
     fun testTaskbarVisibleInSplitShade() {
-        notificationsQSContainerController.splitShadeEnabled = true
+        enableSplitShade()
         useNewFooter(false)
 
         given(taskbarVisible = true,
@@ -107,7 +128,7 @@
 
     @Test
     fun testTaskbarVisibleInSplitShade_newFooter() {
-        notificationsQSContainerController.splitShadeEnabled = true
+        enableSplitShade()
         useNewFooter(true)
 
         given(taskbarVisible = true,
@@ -115,20 +136,20 @@
                 insets = windowInsets().withStableBottom())
         then(expectedContainerPadding = 0, // taskbar should disappear when shade is expanded
                 expectedNotificationsMargin = NOTIFICATIONS_MARGIN,
-                expectedQsPadding = STABLE_INSET_BOTTOM)
+                expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
 
         given(taskbarVisible = true,
                 navigationMode = BUTTONS_NAVIGATION,
                 insets = windowInsets().withStableBottom())
         then(expectedContainerPadding = STABLE_INSET_BOTTOM,
                 expectedNotificationsMargin = NOTIFICATIONS_MARGIN,
-                expectedQsPadding = STABLE_INSET_BOTTOM)
+                expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
     }
 
     @Test
     fun testTaskbarNotVisibleInSplitShade() {
         // when taskbar is not visible, it means we're on the home screen
-        notificationsQSContainerController.splitShadeEnabled = true
+        enableSplitShade()
         useNewFooter(false)
 
         given(taskbarVisible = false,
@@ -146,26 +167,26 @@
     @Test
     fun testTaskbarNotVisibleInSplitShade_newFooter() {
         // when taskbar is not visible, it means we're on the home screen
-        notificationsQSContainerController.splitShadeEnabled = true
+        enableSplitShade()
         useNewFooter(true)
 
         given(taskbarVisible = false,
                 navigationMode = GESTURES_NAVIGATION,
                 insets = windowInsets().withStableBottom())
         then(expectedContainerPadding = 0,
-                expectedQsPadding = STABLE_INSET_BOTTOM)
+                expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
 
         given(taskbarVisible = false,
                 navigationMode = BUTTONS_NAVIGATION,
                 insets = windowInsets().withStableBottom())
         then(expectedContainerPadding = 0, // qs goes full height as it's not obscuring nav buttons
                 expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN,
-                expectedQsPadding = STABLE_INSET_BOTTOM)
+                expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
     }
 
     @Test
     fun testTaskbarNotVisibleInSplitShadeWithCutout() {
-        notificationsQSContainerController.splitShadeEnabled = true
+        enableSplitShade()
         useNewFooter(false)
 
         given(taskbarVisible = false,
@@ -182,25 +203,26 @@
 
     @Test
     fun testTaskbarNotVisibleInSplitShadeWithCutout_newFooter() {
-        notificationsQSContainerController.splitShadeEnabled = true
+        enableSplitShade()
         useNewFooter(true)
 
         given(taskbarVisible = false,
                 navigationMode = GESTURES_NAVIGATION,
                 insets = windowInsets().withCutout())
-        then(expectedContainerPadding = CUTOUT_HEIGHT)
+        then(expectedContainerPadding = CUTOUT_HEIGHT,
+            expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
 
         given(taskbarVisible = false,
                 navigationMode = BUTTONS_NAVIGATION,
                 insets = windowInsets().withCutout().withStableBottom())
         then(expectedContainerPadding = 0,
                 expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN,
-                expectedQsPadding = STABLE_INSET_BOTTOM)
+                expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
     }
 
     @Test
     fun testTaskbarVisibleInSinglePaneShade() {
-        notificationsQSContainerController.splitShadeEnabled = false
+        disableSplitShade()
         useNewFooter(false)
 
         given(taskbarVisible = true,
@@ -216,7 +238,7 @@
 
     @Test
     fun testTaskbarVisibleInSinglePaneShade_newFooter() {
-        notificationsQSContainerController.splitShadeEnabled = false
+        disableSplitShade()
         useNewFooter(true)
 
         given(taskbarVisible = true,
@@ -234,7 +256,7 @@
 
     @Test
     fun testTaskbarNotVisibleInSinglePaneShade() {
-        notificationsQSContainerController.splitShadeEnabled = false
+        disableSplitShade()
         useNewFooter(false)
 
         given(taskbarVisible = false,
@@ -255,7 +277,7 @@
 
     @Test
     fun testTaskbarNotVisibleInSinglePaneShade_newFooter() {
-        notificationsQSContainerController.splitShadeEnabled = false
+        disableSplitShade()
         useNewFooter(true)
 
         given(taskbarVisible = false,
@@ -276,8 +298,8 @@
 
     @Test
     fun testCustomizingInSinglePaneShade() {
-        notificationsQSContainerController.splitShadeEnabled = false
-        notificationsQSContainerController.setCustomizerShowing(true)
+        disableSplitShade()
+        controller.setCustomizerShowing(true)
         useNewFooter(false)
 
         // always sets spacings to 0
@@ -296,8 +318,8 @@
 
     @Test
     fun testCustomizingInSinglePaneShade_newFooter() {
-        notificationsQSContainerController.splitShadeEnabled = false
-        notificationsQSContainerController.setCustomizerShowing(true)
+        disableSplitShade()
+        controller.setCustomizerShowing(true)
         useNewFooter(true)
 
         // always sets spacings to 0
@@ -316,8 +338,8 @@
 
     @Test
     fun testDetailShowingInSinglePaneShade() {
-        notificationsQSContainerController.splitShadeEnabled = false
-        notificationsQSContainerController.setDetailShowing(true)
+        disableSplitShade()
+        controller.setDetailShowing(true)
         useNewFooter(false)
 
         // always sets spacings to 0
@@ -336,8 +358,8 @@
 
     @Test
     fun testDetailShowingInSinglePaneShade_newFooter() {
-        notificationsQSContainerController.splitShadeEnabled = false
-        notificationsQSContainerController.setDetailShowing(true)
+        disableSplitShade()
+        controller.setDetailShowing(true)
         useNewFooter(true)
 
         // always sets spacings to 0
@@ -356,8 +378,8 @@
 
     @Test
     fun testDetailShowingInSplitShade() {
-        notificationsQSContainerController.splitShadeEnabled = true
-        notificationsQSContainerController.setDetailShowing(true)
+        enableSplitShade()
+        controller.setDetailShowing(true)
         useNewFooter(false)
 
         given(taskbarVisible = false,
@@ -374,8 +396,8 @@
 
     @Test
     fun testDetailShowingInSplitShade_newFooter() {
-        notificationsQSContainerController.splitShadeEnabled = true
-        notificationsQSContainerController.setDetailShowing(true)
+        enableSplitShade()
+        controller.setDetailShowing(true)
         useNewFooter(true)
 
         given(taskbarVisible = false,
@@ -392,16 +414,107 @@
 
     @Test
     fun testNotificationsMarginBottomIsUpdated() {
-        notificationsQSContainerController.splitShadeEnabled = true
+        Mockito.clearInvocations(notificationsQSContainer)
+        enableSplitShade()
         verify(notificationsQSContainer).setNotificationsMarginBottom(NOTIFICATIONS_MARGIN)
 
-        whenever(notificationsQSContainer.defaultNotificationsMarginBottom).thenReturn(100)
-        notificationsQSContainerController.updateMargins()
-        notificationsQSContainerController.splitShadeEnabled = false
-
+        overrideResource(R.dimen.notification_panel_margin_bottom, 100)
+        disableSplitShade()
         verify(notificationsQSContainer).setNotificationsMarginBottom(100)
     }
 
+    @Test
+    fun testSplitShadeLayout_isAlignedToGuideline() {
+        enableSplitShade()
+        controller.updateResources()
+        assertThat(getConstraintSetLayout(R.id.qs_frame).endToEnd)
+                .isEqualTo(R.id.qs_edge_guideline)
+        assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startToStart)
+                .isEqualTo(R.id.qs_edge_guideline)
+    }
+
+    @Test
+    fun testSinglePaneLayout_childrenHaveEqualMargins() {
+        disableSplitShade()
+        controller.updateResources()
+        val qsStartMargin = getConstraintSetLayout(R.id.qs_frame).startMargin
+        val qsEndMargin = getConstraintSetLayout(R.id.qs_frame).endMargin
+        val notifStartMargin = getConstraintSetLayout(R.id.notification_stack_scroller).startMargin
+        val notifEndMargin = getConstraintSetLayout(R.id.notification_stack_scroller).endMargin
+        assertThat(qsStartMargin == qsEndMargin &&
+                notifStartMargin == notifEndMargin &&
+                qsStartMargin == notifStartMargin
+        ).isTrue()
+    }
+
+    @Test
+    fun testSplitShadeLayout_childrenHaveInsideMarginsOfZero() {
+        enableSplitShade()
+        controller.updateResources()
+        assertThat(getConstraintSetLayout(R.id.qs_frame).endMargin).isEqualTo(0)
+        assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startMargin)
+                .isEqualTo(0)
+    }
+
+    @Test
+    fun testSplitShadeLayout_qsFrameHasHorizontalMarginsOfZero() {
+        enableSplitShade()
+        controller.updateResources()
+        assertThat(getConstraintSetLayout(R.id.qs_frame).endMargin).isEqualTo(0)
+        assertThat(getConstraintSetLayout(R.id.qs_frame).startMargin).isEqualTo(0)
+    }
+
+    @Test
+    fun testSinglePaneShadeLayout_qsFrameHasHorizontalMarginsSetToCorrectValue() {
+        disableSplitShade()
+        controller.updateResources()
+        val notificationPanelMarginHorizontal = context.resources
+                .getDimensionPixelSize(R.dimen.notification_panel_margin_horizontal)
+        assertThat(getConstraintSetLayout(R.id.qs_frame).endMargin)
+                .isEqualTo(notificationPanelMarginHorizontal)
+        assertThat(getConstraintSetLayout(R.id.qs_frame).startMargin)
+                .isEqualTo(notificationPanelMarginHorizontal)
+    }
+
+    @Test
+    fun testSinglePaneShadeLayout_isAlignedToParent() {
+        disableSplitShade()
+        controller.updateResources()
+        assertThat(getConstraintSetLayout(R.id.qs_frame).endToEnd)
+                .isEqualTo(ConstraintSet.PARENT_ID)
+        assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).startToStart)
+                .isEqualTo(ConstraintSet.PARENT_ID)
+    }
+
+    @Test
+    fun testAllChildrenOfNotificationContainer_haveIds() {
+        // set dimen to 0 to avoid triggering updating bottom spacing
+        overrideResource(R.dimen.split_shade_notifications_scrim_margin_bottom, 0)
+        val container = NotificationsQuickSettingsContainer(context, null)
+        container.removeAllViews()
+        container.addView(newViewWithId(1))
+        container.addView(newViewWithId(View.NO_ID))
+        val controller = NotificationsQSContainerController(container, navigationModeController,
+                overviewProxyService, featureFlags)
+        controller.updateResources()
+
+        assertThat(container.getChildAt(0).id).isEqualTo(1)
+        assertThat(container.getChildAt(1).id).isNotEqualTo(View.NO_ID)
+    }
+
+    private fun disableSplitShade() {
+        setSplitShadeEnabled(false)
+    }
+
+    private fun enableSplitShade() {
+        setSplitShadeEnabled(true)
+    }
+
+    private fun setSplitShadeEnabled(enabled: Boolean) {
+        overrideResource(R.bool.config_use_split_notification_shade, enabled)
+        controller.updateResources()
+    }
+
     private fun given(
         taskbarVisible: Boolean,
         navigationMode: Int,
@@ -448,4 +561,18 @@
     private fun useNewFooter(useNewFooter: Boolean) {
         whenever(featureFlags.isEnabled(Flags.NEW_FOOTER)).thenReturn(useNewFooter)
     }
-}
\ No newline at end of file
+
+    private fun getConstraintSetLayout(@IdRes id: Int): ConstraintSet.Layout {
+        return constraintSetCaptor.value.getConstraint(id).layout
+    }
+
+    private fun newViewWithId(id: Int): View {
+        val view = View(mContext)
+        view.id = id
+        val layoutParams = ConstraintLayout.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+        // required as cloning ConstraintSet fails if view doesn't have layout params
+        view.layoutParams = layoutParams
+        return view
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 10f4435..0b25467 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -1234,10 +1234,8 @@
         mScrimController.transitionTo(ScrimState.KEYGUARD);
         mScrimController.setUnocclusionAnimationRunning(true);
 
-        assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ KEYGUARD_SCRIM_ALPHA,
-                /* expansion */ 0.0f);
-        assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ KEYGUARD_SCRIM_ALPHA,
-                /* expansion */ 1.0f);
+        assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0f, /* expansion */ 0f);
+        assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0f, /* expansion */ 1.0f);
 
         // Verify normal behavior after
         mScrimController.setUnocclusionAnimationRunning(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index ace7415..d48ce8c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -57,6 +57,7 @@
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationClickNotifier;
@@ -84,6 +85,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.Mockito;
@@ -130,7 +132,6 @@
     private NotifPipeline mNotifPipeline;
     @Mock
     private NotificationVisibilityProvider mVisibilityProvider;
-
     @Mock
     private ActivityIntentHelper mActivityIntentHelper;
     @Mock
@@ -145,14 +146,14 @@
     private ActivityLaunchAnimator mActivityLaunchAnimator;
     @Mock
     private InteractionJankMonitor mJankMonitor;
+    private StatusBarNotificationActivityStarter.LaunchEventsEmitter mLaunchEventsEmitter;
     private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
-
     private NotificationTestHelper mNotificationTestHelper;
     private ExpandableNotificationRow mNotificationRow;
     private ExpandableNotificationRow mBubbleNotificationRow;
 
     private final Answer<Void> mCallOnDismiss = answerVoid(
-            (ActivityStarter.OnDismissAction dismissAction, Runnable cancel,
+            (OnDismissAction dismissAction, Runnable cancel,
                     Boolean afterKeyguardGone) -> dismissAction.onDismiss());
     private ArrayList<NotificationEntry> mActiveNotifications;
 
@@ -188,10 +189,11 @@
         when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
         when(mOnUserInteractionCallback.getGroupSummaryToDismiss(mNotificationRow.getEntry()))
                 .thenReturn(null);
-        when(mVisibilityProvider.obtain(anyString(), anyBoolean())).thenAnswer(
-                invocation-> NotificationVisibility.obtain(invocation.getArgument(0), 0, 1, false));
-        when(mVisibilityProvider.obtain(any(NotificationEntry.class), anyBoolean())).thenAnswer(
-                invocation-> NotificationVisibility.obtain(
+        when(mVisibilityProvider.obtain(anyString(), anyBoolean()))
+                .thenAnswer(invocation -> NotificationVisibility.obtain(
+                        invocation.getArgument(0), 0, 1, false));
+        when(mVisibilityProvider.obtain(any(NotificationEntry.class), anyBoolean()))
+                .thenAnswer(invocation -> NotificationVisibility.obtain(
                         invocation.<NotificationEntry>getArgument(0).getKey(), 0, 1, false));
 
         HeadsUpManagerPhone headsUpManager = mock(HeadsUpManagerPhone.class);
@@ -201,7 +203,7 @@
                         NotificationListContainer.class),
                         headsUpManager,
                         mJankMonitor);
-
+        mLaunchEventsEmitter = new StatusBarNotificationActivityStarter.LaunchEventsEmitter();
         mNotificationActivityStarter =
                 new StatusBarNotificationActivityStarter(
                         getContext(),
@@ -237,12 +239,13 @@
                         mock(NotificationPresenter.class),
                         mock(NotificationPanelViewController.class),
                         mActivityLaunchAnimator,
-                        notificationAnimationProvider
+                        notificationAnimationProvider,
+                        mLaunchEventsEmitter
                 );
 
         // set up dismissKeyguardThenExecute to synchronously invoke the OnDismissAction arg
         doAnswer(mCallOnDismiss).when(mActivityStarter).dismissKeyguardThenExecute(
-                any(ActivityStarter.OnDismissAction.class), any(), anyBoolean());
+                any(OnDismissAction.class), any(), anyBoolean());
 
         // set up addAfterKeyguardGoneRunnable to synchronously invoke the Runnable arg
         doAnswer(answerVoid(Runnable::run))
@@ -402,4 +405,46 @@
         // THEN display should try wake up for the full screen intent
         verify(mCentralSurfaces).wakeUpForFullScreenIntent();
     }
+
+    @Test
+    public void testNotifActivityStarterEventSourceStartEvent_onNotificationClicked() {
+        NotifActivityLaunchEvents.Listener listener =
+                mock(NotifActivityLaunchEvents.Listener.class);
+        mLaunchEventsEmitter.registerListener(listener);
+        mNotificationActivityStarter
+                .onNotificationClicked(mNotificationRow.getEntry().getSbn(), mNotificationRow);
+        verify(listener).onStartLaunchNotifActivity(mNotificationRow.getEntry());
+    }
+
+    @Test
+    public void testNotifActivityStarterEventSourceFinishEvent_dismissKeyguardCancelled() {
+        NotifActivityLaunchEvents.Listener listener =
+                mock(NotifActivityLaunchEvents.Listener.class);
+        mLaunchEventsEmitter.registerListener(listener);
+        // set up dismissKeyguardThenExecute to synchronously invoke the cancel runnable arg
+        doAnswer(answerVoid(
+                (OnDismissAction dismissAction, Runnable cancel, Boolean afterKeyguardGone) ->
+                        cancel.run()))
+                .when(mActivityStarter)
+                .dismissKeyguardThenExecute(any(OnDismissAction.class), any(), anyBoolean());
+        mNotificationActivityStarter
+                .onNotificationClicked(mNotificationRow.getEntry().getSbn(), mNotificationRow);
+        verify(listener).onFinishLaunchNotifActivity(mNotificationRow.getEntry());
+    }
+
+    @Test
+    public void testNotifActivityStarterEventSourceFinishEvent_postPanelCollapse()
+            throws Exception {
+        NotifActivityLaunchEvents.Listener listener =
+                mock(NotifActivityLaunchEvents.Listener.class);
+        mLaunchEventsEmitter.registerListener(listener);
+        mNotificationActivityStarter
+                .onNotificationClicked(mNotificationRow.getEntry().getSbn(), mNotificationRow);
+        ArgumentCaptor<ActivityLaunchAnimator.Controller> controllerCaptor =
+                ArgumentCaptor.forClass(ActivityLaunchAnimator.Controller.class);
+        verify(mActivityLaunchAnimator).startPendingIntentWithAnimation(
+                controllerCaptor.capture(), anyBoolean(), any(), any());
+        controllerCaptor.getValue().onIntentStarted(false);
+        verify(listener).onFinishLaunchNotifActivity(mNotificationRow.getEntry());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
index 4a579cb..f58403d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
@@ -26,7 +26,6 @@
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.CommunalStateController
 import com.android.systemui.keyguard.ScreenLifecycle
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.qs.user.UserSwitchDialogController
@@ -55,9 +54,6 @@
     private lateinit var userSwitcherController: UserSwitcherController
 
     @Mock
-    private lateinit var communalStateController: CommunalStateController
-
-    @Mock
     private lateinit var keyguardStateController: KeyguardStateController
 
     @Mock
@@ -99,7 +95,6 @@
                 context.resources,
                 screenLifecycle,
                 userSwitcherController,
-                communalStateController,
                 keyguardStateController,
                 falsingManager,
                 configurationController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index 20a3fda..3a0a7c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -114,15 +114,13 @@
         mContext.unregisterReceiver(mReceiver);
     }
 
-    private void setTestPendingIntent(RemoteInputView view, RemoteInputViewController controller) {
+    private void setTestPendingIntent(RemoteInputViewController controller) {
         PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0,
                 new Intent(TEST_ACTION), PendingIntent.FLAG_MUTABLE);
         RemoteInput input = new RemoteInput.Builder(TEST_RESULT_KEY).build();
         RemoteInput[] inputs = {input};
 
-        view.setPendingIntent(pendingIntent);
         controller.setPendingIntent(pendingIntent);
-        view.setRemoteInput(inputs, input, null /* editedSuggestionInfo */);
         controller.setRemoteInput(input);
         controller.setRemoteInputs(inputs);
     }
@@ -137,7 +135,7 @@
         RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
         RemoteInputViewController controller = bindController(view, row.getEntry());
 
-        setTestPendingIntent(view, controller);
+        setTestPendingIntent(controller);
 
         view.focus();
 
@@ -177,7 +175,7 @@
         RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
         RemoteInputViewController controller = bindController(view, row.getEntry());
 
-        setTestPendingIntent(view, controller);
+        setTestPendingIntent(controller);
 
         view.focus();
 
@@ -235,7 +233,7 @@
         RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
         RemoteInputViewController controller = bindController(view, row.getEntry());
 
-        setTestPendingIntent(view, controller);
+        setTestPendingIntent(controller);
 
         // Open view, send a reply
         view.focus();
@@ -265,7 +263,7 @@
         RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
         RemoteInputViewController controller = bindController(view, row.getEntry());
 
-        setTestPendingIntent(view, controller);
+        setTestPendingIntent(controller);
 
         // Open view, attach an image
         view.focus();
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 91c347f..1caacb8 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
@@ -41,6 +41,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
@@ -83,6 +84,7 @@
     @Mock private lateinit var userManager: UserManager
     @Mock private lateinit var activityStarter: ActivityStarter
     @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
+    @Mock private lateinit var broadcastSender: BroadcastSender
     @Mock private lateinit var telephonyListenerManager: TelephonyListenerManager
     @Mock private lateinit var secureSettings: SecureSettings
     @Mock private lateinit var falsingManager: FalsingManager
@@ -159,6 +161,7 @@
                 handler,
                 activityStarter,
                 broadcastDispatcher,
+                broadcastSender,
                 uiEventLogger,
                 falsingManager,
                 telephonyListenerManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 82880fe..78ee9e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -98,6 +98,7 @@
 import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
+import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
@@ -343,7 +344,9 @@
                         mock(BatteryController.class),
                         mock(HeadsUpManager.class),
                         mock(NotificationInterruptLogger.class),
-                        mock(Handler.class)
+                        mock(Handler.class),
+                        mock(NotifPipelineFlags.class),
+                        mock(KeyguardNotificationVisibilityProvider.class)
                 );
 
         when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
index cc848bc3..fafe4b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
@@ -85,6 +85,7 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
+import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
@@ -309,7 +310,9 @@
                         mock(BatteryController.class),
                         mock(HeadsUpManager.class),
                         mock(NotificationInterruptLogger.class),
-                        mock(Handler.class)
+                        mock(Handler.class),
+                        mock(NotifPipelineFlags.class),
+                        mock(KeyguardNotificationVisibilityProvider.class)
                 );
         when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(true);
         when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
index e698f1e..a7f0dc2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
@@ -23,7 +23,9 @@
 import android.service.dreams.IDreamManager;
 
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationFilter;
+import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -42,7 +44,9 @@
             BatteryController batteryController,
             HeadsUpManager headsUpManager,
             NotificationInterruptLogger logger,
-            Handler mainHandler) {
+            Handler mainHandler,
+            NotifPipelineFlags flags,
+            KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider) {
         super(contentResolver,
                 powerManager,
                 dreamManager,
@@ -52,7 +56,9 @@
                 statusBarStateController,
                 headsUpManager,
                 logger,
-                mainHandler);
+                mainHandler,
+                flags,
+                keyguardNotificationVisibilityProvider);
         mUseHeadsUp = true;
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
index 7726938..185942e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
@@ -32,6 +32,7 @@
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.tracing.ProtoTracer;
 import com.android.wm.shell.ShellCommandHandler;
@@ -66,6 +67,7 @@
 
     @Mock CommandQueue mCommandQueue;
     @Mock ConfigurationController mConfigurationController;
+    @Mock KeyguardStateController mKeyguardStateController;
     @Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @Mock NavigationModeController mNavigationModeController;
     @Mock ScreenLifecycle mScreenLifecycle;
@@ -90,9 +92,9 @@
                 Optional.of(mSplitScreen), Optional.of(mOneHanded), Optional.of(mHideDisplayCutout),
                 Optional.of(mShellCommandHandler), Optional.of(mCompatUI),
                 Optional.of(mDragAndDrop),
-                mCommandQueue, mConfigurationController, mKeyguardUpdateMonitor,
-                mNavigationModeController, mScreenLifecycle, mSysUiState, mProtoTracer,
-                mWakefulnessLifecycle, mUserInfoController, mSysUiMainExecutor);
+                mCommandQueue, mConfigurationController, mKeyguardStateController,
+                mKeyguardUpdateMonitor, mNavigationModeController, mScreenLifecycle, mSysUiState,
+                mProtoTracer, mWakefulnessLifecycle, mUserInfoController, mSysUiMainExecutor);
     }
 
     @Test
@@ -132,6 +134,6 @@
     public void initCompatUI_registersCallbacks() {
         mWMShell.initCompatUi(mCompatUI);
 
-        verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class));
+        verify(mKeyguardStateController).addCallback(any(KeyguardStateController.Callback.class));
     }
 }
diff --git a/proto/src/camera.proto b/proto/src/camera.proto
index 4082118..38d74e4 100644
--- a/proto/src/camera.proto
+++ b/proto/src/camera.proto
@@ -66,5 +66,5 @@
     // The dynamic range profile of the stream
     optional int64 dynamic_range_profile = 14;
     // The stream use case
-    optional int32 stream_use_case = 15;
+    optional int64 stream_use_case = 15;
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 7f10314..5ef1008 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -281,9 +281,9 @@
 
         void onDoubleTapAndHold(int displayId);
 
-        void requestImeLocked(AccessibilityServiceConnection connection);
+        void requestImeLocked(AbstractAccessibilityServiceConnection connection);
 
-        void unbindImeLocked(AccessibilityServiceConnection connection);
+        void unbindImeLocked(AbstractAccessibilityServiceConnection connection);
     }
 
     public AbstractAccessibilityServiceConnection(Context context, ComponentName componentName,
@@ -387,7 +387,6 @@
                 & AccessibilityServiceInfo.FLAG_REQUEST_FINGERPRINT_GESTURES) != 0;
         mRequestAccessibilityButton = (info.flags
                 & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
-        // TODO(b/218193835): request ime when ime flag is set and clean up when ime flag is unset
         mRequestImeApis = (info.flags
                 & AccessibilityServiceInfo.FLAG_INPUT_METHOD_EDITOR) != 0;
     }
@@ -439,6 +438,7 @@
                 // If the XML manifest had data to configure the service its info
                 // should be already set. In such a case update only the dynamically
                 // configurable properties.
+                boolean oldRequestIme = mRequestImeApis;
                 AccessibilityServiceInfo oldInfo = mAccessibilityServiceInfo;
                 if (oldInfo != null) {
                     oldInfo.updateDynamicallyConfigurableProperties(mIPlatformCompat, info);
@@ -447,6 +447,11 @@
                     setDynamicallyConfigurableProperties(info);
                 }
                 mSystemSupport.onClientChangeLocked(true);
+                if (!oldRequestIme && mRequestImeApis) {
+                    mSystemSupport.requestImeLocked(this);
+                } else if (oldRequestIme && !mRequestImeApis) {
+                    mSystemSupport.unbindImeLocked(this);
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(identity);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 0ea087d..249ee16 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -4305,7 +4305,7 @@
     }
 
     @Override
-    public void requestImeLocked(AccessibilityServiceConnection connection) {
+    public void requestImeLocked(AbstractAccessibilityServiceConnection connection) {
         mMainHandler.sendMessage(obtainMessage(
                 AccessibilityManagerService::createSessionForConnection, this, connection));
         mMainHandler.sendMessage(obtainMessage(
@@ -4313,12 +4313,12 @@
     }
 
     @Override
-    public void unbindImeLocked(AccessibilityServiceConnection connection) {
+    public void unbindImeLocked(AbstractAccessibilityServiceConnection connection) {
         mMainHandler.sendMessage(obtainMessage(
                 AccessibilityManagerService::unbindInputForConnection, this, connection));
     }
 
-    private void createSessionForConnection(AccessibilityServiceConnection connection) {
+    private void createSessionForConnection(AbstractAccessibilityServiceConnection connection) {
         synchronized (mLock) {
             if (mInputSessionRequested) {
                 connection.createImeSessionLocked();
@@ -4326,7 +4326,7 @@
         }
     }
 
-    private void bindAndStartInputForConnection(AccessibilityServiceConnection connection) {
+    private void bindAndStartInputForConnection(AbstractAccessibilityServiceConnection connection) {
         synchronized (mLock) {
             if (mInputBinding != null) {
                 connection.bindInputLocked(mInputBinding);
@@ -4336,7 +4336,7 @@
         }
     }
 
-    private void unbindInputForConnection(AccessibilityServiceConnection connection) {
+    private void unbindInputForConnection(AbstractAccessibilityServiceConnection connection) {
         InputMethodManagerInternal.get().unbindAccessibilityFromCurrentClient(connection.mId);
         synchronized (mLock) {
             connection.unbindInputLocked();
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index 86777a2..e20b15a 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -1327,14 +1327,13 @@
         if (mState.isServiceDetectingGestures() && mState.isTouchInteracting()) {
             // Cancel without deleting events.
             mHandler.removeCallbacks(mSendHoverEnterAndMoveDelayed);
-            mSendHoverEnterAndMoveDelayed.run();
-            mSendHoverEnterAndMoveDelayed.clear();
-            final MotionEvent prototype = mState.getLastReceivedEvent();
-            final MotionEvent rawEvent = mState.getLastReceivedRawEvent();
             final int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
             final int pointerIdBits = (1 << pointerId);
             final int policyFlags = mState.getLastReceivedPolicyFlags();
-            mSendHoverExitDelayed.post(prototype, rawEvent, pointerIdBits, policyFlags);
+            mSendHoverEnterAndMoveDelayed.setPointerIdBits(pointerIdBits);
+            mSendHoverEnterAndMoveDelayed.setPolicyFlags(policyFlags);
+            mSendHoverEnterAndMoveDelayed.run();
+            mSendHoverEnterAndMoveDelayed.clear();
         }
     }
 
diff --git a/services/api/current.txt b/services/api/current.txt
index 45c0059..5a28802 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -38,7 +38,7 @@
 package com.android.server.am {
 
   public interface ActivityManagerLocal {
-    method public boolean bindSdkSandboxService(@NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull String, int) throws android.os.RemoteException;
+    method public boolean bindSdkSandboxService(@NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull String, @NonNull String, int) throws android.os.RemoteException;
     method public boolean canStartForegroundService(int, int, @NonNull String);
   }
 
diff --git a/services/backup/backuplib/java/com/android/server/backup/TransportManager.java b/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
index 21a22f4..930f49e 100644
--- a/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
+++ b/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
@@ -16,6 +16,9 @@
 
 package com.android.server.backup;
 
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.annotation.WorkerThread;
@@ -28,7 +31,6 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.os.Binder;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.util.ArrayMap;
@@ -42,8 +44,8 @@
 import com.android.server.backup.transport.BackupTransportClient;
 import com.android.server.backup.transport.OnTransportRegisteredListener;
 import com.android.server.backup.transport.TransportConnection;
-import com.android.server.backup.transport.TransportConnectionManager;
 import com.android.server.backup.transport.TransportConnectionListener;
+import com.android.server.backup.transport.TransportConnectionManager;
 import com.android.server.backup.transport.TransportNotAvailableException;
 import com.android.server.backup.transport.TransportNotRegisteredException;
 import com.android.server.backup.transport.TransportStats;
@@ -58,6 +60,7 @@
 /** Handles in-memory bookkeeping of all BackupTransport objects. */
 public class TransportManager {
     private static final String TAG = "BackupTransportManager";
+    private static final boolean MORE_DEBUG = false;
 
     @VisibleForTesting
     public static final String SERVICE_ACTION_TRANSPORT_HOST = "android.backup.TRANSPORT_HOST";
@@ -130,14 +133,61 @@
         }
     }
 
+    void onPackageEnabled(String packageName) {
+        onPackageAdded(packageName);
+    }
+
+    void onPackageDisabled(String packageName) {
+        onPackageRemoved(packageName);
+    }
+
     @WorkerThread
     void onPackageChanged(String packageName, String... components) {
+        // Determine if the overall package has changed and not just its
+        // components - see {@link EXTRA_CHANGED_COMPONENT_NAME_LIST}.  When we
+        // know a package was enabled/disabled we'll handle that directly and
+        // not continue with onPackageChanged.
+        if (components.length == 1 && components[0].equals(packageName)) {
+            int enabled;
+            try {
+                enabled = mPackageManager.getApplicationEnabledSetting(packageName);
+            } catch (IllegalArgumentException ex) {
+                // packageName doesn't exist: likely due to a race with it being uninstalled.
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Package " + packageName + " was changed, but no longer exists.");
+                }
+                return;
+            }
+            switch (enabled) {
+                case COMPONENT_ENABLED_STATE_ENABLED: {
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Package " + packageName + " was enabled.");
+                    }
+                    onPackageEnabled(packageName);
+                    return;
+                }
+                case COMPONENT_ENABLED_STATE_DISABLED: {
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Package " + packageName + " was disabled.");
+                    }
+                    onPackageDisabled(packageName);
+                    return;
+                }
+                default: {
+                    Slog.w(TAG, "Package " + packageName + " enabled setting: " + enabled);
+                    return;
+                }
+            }
+        }
         // Unfortunately this can't be atomic because we risk a deadlock if
         // registerTransportsFromPackage() is put inside the synchronized block
         Set<ComponentName> transportComponents = new ArraySet<>(components.length);
         for (String componentName : components) {
             transportComponents.add(new ComponentName(packageName, componentName));
         }
+        if (transportComponents.isEmpty()) {
+            return;
+        }
         synchronized (mTransportLock) {
             mRegisteredTransportsDescriptionMap.keySet().removeIf(transportComponents::contains);
         }
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index e10151d..1af35af 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -89,8 +89,6 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.WorkSource;
-import android.os.storage.IStorageManager;
-import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.ArraySet;
@@ -325,7 +323,6 @@
     private final ActivityManagerInternal mActivityManagerInternal;
     private PowerManager mPowerManager;
     private final AlarmManager mAlarmManager;
-    private final IStorageManager mStorageManager;
     private final BackupManagerConstants mConstants;
     private final BackupWakeLock mWakelock;
     private final BackupHandler mBackupHandler;
@@ -536,7 +533,6 @@
         mBackupPasswordManager = null;
         mPackageManagerBinder = null;
         mActivityManager = null;
-        mStorageManager = null;
         mBackupManagerBinder = null;
         mScheduledBackupEligibility = null;
     }
@@ -560,7 +556,6 @@
 
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-        mStorageManager = IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
 
         Objects.requireNonNull(parent, "parent cannot be null");
         mBackupManagerBinder = BackupManagerService.asInterface(parent.asBinder());
@@ -2077,26 +2072,6 @@
         }
     }
 
-    /** For adb backup/restore. */
-    public boolean deviceIsEncrypted() {
-        try {
-            return mStorageManager.getEncryptionState()
-                    != StorageManager.ENCRYPTION_STATE_NONE
-                    && mStorageManager.getPasswordType()
-                    != StorageManager.CRYPT_TYPE_DEFAULT;
-        } catch (Exception e) {
-            // If we can't talk to the storagemanager service we have a serious problem; fail
-            // "secure" i.e. assuming that the device is encrypted.
-            Slog.e(
-                    TAG,
-                    addUserIdToLogMessage(
-                            mUserId,
-                            "Unable to communicate with storagemanager service: "
-                                    + e.getMessage()));
-            return true;
-        }
-    }
-
     // ----- Full-data backup scheduling -----
 
     /**
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
index 7ee307e..ec58e17 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
@@ -320,12 +320,6 @@
         try {
             boolean encrypting = (mEncryptPassword != null && mEncryptPassword.length() > 0);
 
-            // Only allow encrypted backups of encrypted devices
-            if (mUserBackupManagerService.deviceIsEncrypted() && !encrypting) {
-                Slog.e(TAG, "Unencrypted backup of encrypted device; aborting");
-                return;
-            }
-
             OutputStream finalOutput = ofstream;
 
             // Verify that the given password matches the currently-active
diff --git a/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchManagerService.java b/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchManagerService.java
index daead0a..ac2d1dd 100644
--- a/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchManagerService.java
+++ b/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchManagerService.java
@@ -43,6 +43,8 @@
 import com.android.server.wm.ActivityTaskManagerInternal;
 
 import java.io.FileDescriptor;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.function.Consumer;
 
 /**
@@ -62,7 +64,7 @@
 
     public CloudSearchManagerService(Context context) {
         super(context, new FrameworkResourcesServiceNameResolver(context,
-                        R.string.config_defaultCloudSearchService), null,
+                        R.array.config_defaultCloudSearchServices, true), null,
                 PACKAGE_UPDATE_POLICY_NO_REFRESH | PACKAGE_RESTART_POLICY_NO_REFRESH);
         mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
         mContext = context;
@@ -70,7 +72,25 @@
 
     @Override
     protected CloudSearchPerUserService newServiceLocked(int resolvedUserId, boolean disabled) {
-        return new CloudSearchPerUserService(this, mLock, resolvedUserId);
+        return new CloudSearchPerUserService(this, mLock, resolvedUserId, "");
+    }
+
+    @Override
+    protected List<CloudSearchPerUserService> newServiceListLocked(int resolvedUserId,
+            boolean disabled, String[] serviceNames) {
+        if (serviceNames == null) {
+            return new ArrayList<>();
+        }
+        List<CloudSearchPerUserService> serviceList =
+                new ArrayList<>(serviceNames.length);
+        for (int i = 0; i < serviceNames.length; i++) {
+            if (serviceNames[i] == null) {
+                continue;
+            }
+            serviceList.add(new CloudSearchPerUserService(this, mLock, resolvedUserId,
+                    serviceNames[i]));
+        }
+        return serviceList;
     }
 
     @Override
@@ -109,21 +129,30 @@
         @Override
         public void search(@NonNull SearchRequest searchRequest,
                 @NonNull ICloudSearchManagerCallback callBack) {
-            searchRequest.setSource(
+            searchRequest.setCallerPackageName(
                     mContext.getPackageManager().getNameForUid(Binder.getCallingUid()));
-            runForUserLocked("search", searchRequest.getRequestId(), (service) ->
-                    service.onSearchLocked(searchRequest, callBack));
+            runForUser("search", (service) -> {
+                synchronized (service.mLock) {
+                    service.onSearchLocked(searchRequest, callBack);
+                }
+            });
         }
 
         @Override
         public void returnResults(IBinder token, String requestId, SearchResponse response) {
-            runForUserLocked("returnResults", requestId, (service) ->
-                    service.onReturnResultsLocked(token, requestId, response));
+            runForUser("returnResults", (service) -> {
+                synchronized (service.mLock) {
+                    service.onReturnResultsLocked(token, requestId, response);
+                }
+            });
         }
 
         public void destroy(@NonNull SearchRequest searchRequest) {
-            runForUserLocked("destroyCloudSearchSession", searchRequest.getRequestId(),
-                    (service) -> service.onDestroyLocked(searchRequest.getRequestId()));
+            runForUser("destroyCloudSearchSession", (service) -> {
+                synchronized (service.mLock) {
+                    service.onDestroyLocked(searchRequest.getRequestId());
+                }
+            });
         }
 
         public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
@@ -134,8 +163,7 @@
                     .exec(this, in, out, err, args, callback, resultReceiver);
         }
 
-        private void runForUserLocked(@NonNull final String func,
-                @NonNull final String  requestId,
+        private void runForUser(@NonNull final String func,
                 @NonNull final Consumer<CloudSearchPerUserService> c) {
             ActivityManagerInternal am = LocalServices.getService(ActivityManagerInternal.class);
             final int userId = am.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
@@ -143,7 +171,7 @@
                     null, null);
 
             if (DEBUG) {
-                Slog.d(TAG, "runForUserLocked:" + func + " from pid=" + Binder.getCallingPid()
+                Slog.d(TAG, "runForUser:" + func + " from pid=" + Binder.getCallingPid()
                         + ", uid=" + Binder.getCallingUid());
             }
             Context ctx = getContext();
@@ -160,8 +188,11 @@
             final long origId = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
-                    final CloudSearchPerUserService service = getServiceForUserLocked(userId);
-                    c.accept(service);
+                    final List<CloudSearchPerUserService> services =
+                            getServiceListForUserLocked(userId);
+                    for (int i = 0; i < services.size(); i++) {
+                        c.accept(services.get(i));
+                    }
                 }
             } finally {
                 Binder.restoreCallingIdentity(origId);
diff --git a/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchManagerServiceShellCommand.java b/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchManagerServiceShellCommand.java
index 51f5fd9..c64982d 100644
--- a/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchManagerServiceShellCommand.java
+++ b/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchManagerServiceShellCommand.java
@@ -54,7 +54,12 @@
                             return 0;
                         }
                         final int duration = Integer.parseInt(getNextArgRequired());
-                        mService.setTemporaryService(userId, serviceName, duration);
+                        String[] services = serviceName.split(";");
+                        if (services.length == 0) {
+                            return 0;
+                        } else {
+                            mService.setTemporaryServices(userId, services, duration);
+                        }
                         pw.println("CloudSearchService temporarily set to " + serviceName
                                 + " for " + duration + "ms");
                         break;
diff --git a/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchPerUserService.java b/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchPerUserService.java
index 32d66af..116c739 100644
--- a/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchPerUserService.java
+++ b/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchPerUserService.java
@@ -49,6 +49,8 @@
     @GuardedBy("mLock")
     private final CircularQueue<String, CloudSearchCallbackInfo> mCallbackQueue =
             new CircularQueue<>(QUEUE_SIZE);
+    private final String mServiceName;
+    private final ComponentName mRemoteComponentName;
     @Nullable
     @GuardedBy("mLock")
     private RemoteCloudSearchService mRemoteService;
@@ -60,8 +62,10 @@
     private boolean mZombie;
 
     protected CloudSearchPerUserService(CloudSearchManagerService master,
-            Object lock, int userId) {
+            Object lock, int userId, String serviceName) {
         super(master, lock, userId);
+        mServiceName = serviceName;
+        mRemoteComponentName = ComponentName.unflattenFromString(mServiceName);
     }
 
     @Override // from PerUserSystemService
@@ -108,7 +112,7 @@
                 ? searchRequest.getSearchConstraints().getString(
                 SearchRequest.CONSTRAINT_SEARCH_PROVIDER_FILTER) : "";
 
-        String remoteServicePackageName = getServiceComponentName().getPackageName();
+        String remoteServicePackageName = mRemoteComponentName.getPackageName();
         // By default, all providers are marked as wanted.
         boolean wantedProvider = true;
         if (filterList.length() > 0) {
@@ -150,11 +154,19 @@
     /**
      * Used to return results back to the clients.
      */
+    @GuardedBy("mLock")
     public void onReturnResultsLocked(@NonNull IBinder token,
             @NonNull String requestId,
             @NonNull SearchResponse response) {
+        if (mRemoteService == null) {
+            return;
+        }
+        ICloudSearchService serviceInterface = mRemoteService.getServiceInterface();
+        if (serviceInterface == null || token != serviceInterface.asBinder()) {
+            return;
+        }
         if (mCallbackQueue.containsKey(requestId)) {
-            response.setSource(mRemoteService.getComponentName().getPackageName());
+            response.setSource(mServiceName);
             final CloudSearchCallbackInfo sessionInfo = mCallbackQueue.getElement(requestId);
             try {
                 if (response.getStatusCode() == SearchResponse.SEARCH_STATUS_OK) {
@@ -163,6 +175,10 @@
                     sessionInfo.mCallback.onSearchFailed(response);
                 }
             } catch (RemoteException e) {
+                if (mMaster.debug) {
+                    Slog.e(TAG, "Exception in posting results");
+                    e.printStackTrace();
+                }
                 onDestroyLocked(requestId);
             }
         }
@@ -297,7 +313,7 @@
     @Nullable
     private RemoteCloudSearchService getRemoteServiceLocked() {
         if (mRemoteService == null) {
-            final String serviceName = getComponentNameLocked();
+            final String serviceName = getComponentNameForMultipleLocked(mServiceName);
             if (serviceName == null) {
                 if (mMaster.verbose) {
                     Slog.v(TAG, "getRemoteServiceLocked(): not set");
diff --git a/services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java b/services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java
index 1ba198a..823743d 100644
--- a/services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java
+++ b/services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java
@@ -94,7 +94,7 @@
             int reason) {
         if (DEBUG) {
             Log.i(TAG, "onDevice_Disconnected() " + btDeviceToString(device));
-            Log.d(TAG, "  reason=" + disconnectReasonText(reason));
+            Log.d(TAG, "  reason=" + disconnectReasonToString(reason));
         }
 
         final MacAddress macAddress = MacAddress.fromString(device.getAddress());
diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index b991ba8..3a26c46 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -22,6 +22,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.WindowConfiguration;
 import android.app.compat.CompatChanges;
 import android.companion.virtual.VirtualDeviceManager.ActivityListener;
 import android.companion.virtual.VirtualDeviceParams;
@@ -119,6 +120,7 @@
             @ActivityPolicy int defaultActivityPolicy,
             @NonNull ActivityListener activityListener,
             @NonNull Consumer<ActivityInfo> activityBlockedCallback) {
+        super();
         mAllowedUsers = allowedUsers;
         mAllowedActivities = new ArraySet<>(allowedActivities);
         mBlockedActivities = new ArraySet<>(blockedActivities);
@@ -134,7 +136,11 @@
     }
 
     @Override
-    public boolean canContainActivities(@NonNull List<ActivityInfo> activities) {
+    public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
+            @WindowConfiguration.WindowingMode int windowingMode) {
+        if (!isWindowingModeSupported(windowingMode)) {
+            return false;
+        }
         // Can't display all the activities if any of them don't want to be displayed.
         final int activityCount = activities.size();
         for (int i = 0; i < activityCount; i++) {
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index c9d7040..68cd288 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -45,9 +45,9 @@
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.pm.PackageList;
 import com.android.server.pm.PackageSetting;
+import com.android.server.pm.dex.DynamicCodeLogger;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.pm.pkg.AndroidPackageApi;
-import com.android.server.pm.pkg.PackageState;
 import com.android.server.pm.pkg.PackageStateInternal;
 import com.android.server.pm.pkg.SharedUserApi;
 import com.android.server.pm.pkg.component.ParsedMainComponent;
@@ -68,6 +68,7 @@
  * @hide Only for use within the system server.
  */
 public abstract class PackageManagerInternal {
+
     @IntDef(prefix = "PACKAGE_", value = {
             PACKAGE_SYSTEM,
             PACKAGE_SETUP_WIZARD,
@@ -688,8 +689,6 @@
     @Nullable
     public abstract PackageStateInternal getPackageStateInternal(@NonNull String packageName);
 
-    public abstract @Nullable PackageState getPackageState(@NonNull String packageName);
-
     @NonNull
     public abstract ArrayMap<String, ? extends PackageStateInternal> getPackageStates();
 
@@ -902,6 +901,11 @@
     public abstract void freeStorage(String volumeUuid, long bytes,
             @StorageManager.AllocateFlags int flags) throws IOException;
 
+    /**
+     * Blocking call to clear all cached app data above quota.
+     */
+    public abstract void freeAllAppCacheAboveQuota(@NonNull String volumeUuid) throws IOException;
+
     /** Returns {@code true} if the specified component is enabled and matches the given flags. */
     public abstract boolean isEnabledAndMatches(@NonNull ParsedMainComponent component,
             @PackageManager.ComponentInfoFlagsBits long flags, int userId);
@@ -1362,4 +1366,8 @@
      */
     @NonNull
     public abstract PackageDataSnapshot snapshot();
+
+    public abstract void shutdown();
+
+    public abstract DynamicCodeLogger getDynamicCodeLogger();
 }
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index be2b7f7..f1fa982 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -131,7 +131,7 @@
         final UserManager userManager = context.getSystemService(UserManager.class);
         final int result = userManager.removeUserWhenPossible(
                 UserHandle.of(userId), /* overrideDevicePolicy= */ false);
-        if (result == UserManager.REMOVE_RESULT_ERROR) {
+        if (!UserManager.isRemoveResultSuccessful(result)) {
             Slogf.e(TAG, "Can't remove user %d", userId);
             return false;
         }
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index b59cd4c..1a39ffa 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1166,9 +1166,17 @@
             final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
             try {
                 if (allowlist) {
-                    cm.updateMeteredNetworkAllowList(uid, enable);
+                    if (enable) {
+                        cm.addUidToMeteredNetworkAllowList(uid);
+                    } else {
+                        cm.removeUidFromMeteredNetworkAllowList(uid);
+                    }
                 } else {
-                    cm.updateMeteredNetworkDenyList(uid, enable);
+                    if (enable) {
+                        cm.addUidToMeteredNetworkDenyList(uid);
+                    } else {
+                        cm.removeUidFromMeteredNetworkDenyList(uid);
+                    }
                 }
                 synchronized (mRulesLock) {
                     if (enable) {
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index d4764a6..677fc79 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -75,7 +75,6 @@
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ProviderInfo;
 import android.content.pm.UserInfo;
-import android.content.res.Configuration;
 import android.content.res.ObbInfo;
 import android.database.ContentObserver;
 import android.net.Uri;
@@ -124,7 +123,6 @@
 import android.provider.MediaStore;
 import android.provider.Settings;
 import android.service.storage.ExternalStorageService;
-import android.sysprop.VoldProperties;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
@@ -176,9 +174,6 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.PrintWriter;
-import java.math.BigInteger;
-import java.security.GeneralSecurityException;
-import java.security.spec.KeySpec;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -198,10 +193,6 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.PBEKeySpec;
-
 /**
  * Service responsible for various storage media. Connects to {@code vold} to
  * watch for and manage dynamically added storage, such as SD cards and USB mass
@@ -1414,39 +1405,6 @@
     private void handleDaemonConnected() {
         initIfBootedAndConnected();
         resetIfBootedAndConnected();
-
-        // On an encrypted device we can't see system properties yet, so pull
-        // the system locale out of the mount service.
-        if ("".equals(VoldProperties.encrypt_progress().orElse(""))) {
-            copyLocaleFromMountService();
-        }
-    }
-
-    private void copyLocaleFromMountService() {
-        String systemLocale;
-        try {
-            systemLocale = getField(StorageManager.SYSTEM_LOCALE_KEY);
-        } catch (RemoteException e) {
-            return;
-        }
-        if (TextUtils.isEmpty(systemLocale)) {
-            return;
-        }
-
-        Slog.d(TAG, "Got locale " + systemLocale + " from mount service");
-        Locale locale = Locale.forLanguageTag(systemLocale);
-        Configuration config = new Configuration();
-        config.setLocale(locale);
-        try {
-            ActivityManager.getService().updatePersistentConfigurationWithAttribution(config,
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Error setting system locale from mount service", e);
-        }
-
-        // Temporary workaround for http://b/17945169.
-        Slog.d(TAG, "Setting system properties to " + systemLocale + " from mount service");
-        SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
     }
 
     private final IVoldListener mListener = new IVoldListener.Stub() {
@@ -3130,8 +3088,8 @@
     }
 
     @Override
-    public void mountObb(String rawPath, String canonicalPath, String key,
-            IObbActionListener token, int nonce, ObbInfo obbInfo) {
+    public void mountObb(String rawPath, String canonicalPath, IObbActionListener token,
+            int nonce, ObbInfo obbInfo) {
         Objects.requireNonNull(rawPath, "rawPath cannot be null");
         Objects.requireNonNull(canonicalPath, "canonicalPath cannot be null");
         Objects.requireNonNull(token, "token cannot be null");
@@ -3140,7 +3098,7 @@
         final int callingUid = Binder.getCallingUid();
         final ObbState obbState = new ObbState(rawPath, canonicalPath,
                 callingUid, token, nonce, null);
-        final ObbAction action = new MountObbAction(obbState, key, callingUid, obbInfo);
+        final ObbAction action = new MountObbAction(obbState, callingUid, obbInfo);
         mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
 
         if (DEBUG_OBB)
@@ -3171,203 +3129,6 @@
         }
     }
 
-    @Override
-    public int getEncryptionState() {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
-                "no permission to access the crypt keeper");
-
-        try {
-            return mVold.fdeComplete();
-        } catch (Exception e) {
-            Slog.wtf(TAG, e);
-            return StorageManager.ENCRYPTION_STATE_ERROR_UNKNOWN;
-        }
-    }
-
-    @Override
-    public int decryptStorage(String password) {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
-                "no permission to access the crypt keeper");
-
-        if (TextUtils.isEmpty(password)) {
-            throw new IllegalArgumentException("password cannot be empty");
-        }
-
-        if (DEBUG_EVENTS) {
-            Slog.i(TAG, "decrypting storage...");
-        }
-
-        try {
-            mVold.fdeCheckPassword(password);
-            mHandler.postDelayed(() -> {
-                try {
-                    mVold.fdeRestart();
-                } catch (Exception e) {
-                    Slog.wtf(TAG, e);
-                }
-            }, DateUtils.SECOND_IN_MILLIS);
-            return 0;
-        } catch (ServiceSpecificException e) {
-            Slog.e(TAG, "fdeCheckPassword failed", e);
-            return e.errorCode;
-        } catch (Exception e) {
-            Slog.wtf(TAG, e);
-            return StorageManager.ENCRYPTION_STATE_ERROR_UNKNOWN;
-        }
-    }
-
-    @Override
-    public int encryptStorage(int type, String password) {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
-            "no permission to access the crypt keeper");
-
-        if (type == StorageManager.CRYPT_TYPE_DEFAULT) {
-            password = "";
-        } else if (TextUtils.isEmpty(password)) {
-            throw new IllegalArgumentException("password cannot be empty");
-        }
-
-        if (DEBUG_EVENTS) {
-            Slog.i(TAG, "encrypting storage...");
-        }
-
-        try {
-            mVold.fdeEnable(type, password, 0);
-        } catch (Exception e) {
-            Slog.wtf(TAG, e);
-            return -1;
-        }
-
-        return 0;
-    }
-
-    /** Set the password for encrypting the main key.
-     *  @param type One of the CRYPTO_TYPE_XXX consts defined in StorageManager.
-     *  @param password The password to set.
-     */
-    @Override
-    public int changeEncryptionPassword(int type, String password) {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
-            "no permission to access the crypt keeper");
-
-        if (StorageManager.isFileEncryptedNativeOnly()) {
-            // Not supported on FBE devices
-            return -1;
-        }
-
-        if (type == StorageManager.CRYPT_TYPE_DEFAULT) {
-            password = "";
-        } else if (TextUtils.isEmpty(password)) {
-            throw new IllegalArgumentException("password cannot be empty");
-        }
-
-        if (DEBUG_EVENTS) {
-            Slog.i(TAG, "changing encryption password...");
-        }
-
-        try {
-            mVold.fdeChangePassword(type, password);
-            return 0;
-        } catch (Exception e) {
-            Slog.wtf(TAG, e);
-            return -1;
-        }
-    }
-
-    /**
-     * Validate a user-supplied password string with cryptfs
-     */
-    @Override
-    public int verifyEncryptionPassword(String password) throws RemoteException {
-        // Only the system process is permitted to validate passwords
-        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
-            throw new SecurityException("no permission to access the crypt keeper");
-        }
-
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
-            "no permission to access the crypt keeper");
-
-        if (TextUtils.isEmpty(password)) {
-            throw new IllegalArgumentException("password cannot be empty");
-        }
-
-        if (DEBUG_EVENTS) {
-            Slog.i(TAG, "validating encryption password...");
-        }
-
-        try {
-            mVold.fdeVerifyPassword(password);
-            return 0;
-        } catch (Exception e) {
-            Slog.wtf(TAG, e);
-            return -1;
-        }
-    }
-
-    /**
-     * Get the type of encryption used to encrypt the main key.
-     * @return The type, one of the CRYPT_TYPE_XXX consts from StorageManager.
-     */
-    @Override
-    public int getPasswordType() {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
-            "no permission to access the crypt keeper");
-
-        try {
-            return mVold.fdeGetPasswordType();
-        } catch (Exception e) {
-            Slog.wtf(TAG, e);
-            return -1;
-        }
-    }
-
-    /**
-     * Set a field in the crypto header.
-     * @param field field to set
-     * @param contents contents to set in field
-     */
-    @Override
-    public void setField(String field, String contents) throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
-            "no permission to access the crypt keeper");
-
-        if (!StorageManager.isBlockEncrypted()) {
-            // Only supported on FDE devices
-            return;
-        }
-
-        try {
-            mVold.fdeSetField(field, contents);
-            return;
-        } catch (Exception e) {
-            Slog.wtf(TAG, e);
-            return;
-        }
-    }
-
-    /**
-     * Gets a field from the crypto header.
-     * @param field field to get
-     * @return contents of field
-     */
-    @Override
-    public String getField(String field) throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
-            "no permission to access the crypt keeper");
-
-        if (!StorageManager.isBlockEncrypted()) {
-            // Only supported on FDE devices
-            return null;
-        }
-
-        try {
-            return mVold.fdeGetField(field);
-        } catch (Exception e) {
-            Slog.wtf(TAG, e);
-            return null;
-        }
-    }
-
     /**
      * Is userdata convertible to file based encryption?
      * @return non zero for convertible
@@ -3450,33 +3211,6 @@
     }
 
     @Override
-    public String getPassword() throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
-                "only keyguard can retrieve password");
-
-        try {
-            return mVold.fdeGetPassword();
-        } catch (Exception e) {
-            Slog.wtf(TAG, e);
-            return null;
-        }
-    }
-
-    @Override
-    public void clearPassword() throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
-                "only keyguard can clear password");
-
-        try {
-            mVold.fdeClearPassword();
-            return;
-        } catch (Exception e) {
-            Slog.wtf(TAG, e);
-            return;
-        }
-    }
-
-    @Override
     public void createUserKey(int userId, int serialNumber, boolean ephemeral) {
         enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
 
@@ -3677,11 +3411,20 @@
                     mInstaller.tryMountDataMirror(volumeUuid);
                 }
             }
-        } catch (RemoteException | Installer.InstallerException e) {
+        } catch (Exception e) {
             Slog.wtf(TAG, e);
             // Make sure to re-throw this exception; we must not ignore failure
             // to prepare the user storage as it could indicate that encryption
             // wasn't successfully set up.
+            //
+            // Very unfortunately, these errors need to be ignored for broken
+            // users that already existed on-disk from older Android versions.
+            UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class);
+            if (umInternal.shouldIgnorePrepareStorageErrors(userId)) {
+                Slog.wtf(TAG, "ignoring error preparing storage for existing user " + userId
+                        + "; device may be insecure!");
+                return;
+            }
             throw new RuntimeException(e);
         }
     }
@@ -4586,13 +4329,11 @@
     }
 
     class MountObbAction extends ObbAction {
-        private final String mKey;
         private final int mCallingUid;
         private ObbInfo mObbInfo;
 
-        MountObbAction(ObbState obbState, String key, int callingUid, ObbInfo obbInfo) {
+        MountObbAction(ObbState obbState, int callingUid, ObbInfo obbInfo) {
             super(obbState);
-            mKey = key;
             mCallingUid = callingUid;
             mObbInfo = obbInfo;
         }
@@ -4615,29 +4356,8 @@
                         "Attempt to mount OBB which is already mounted: " + mObbInfo.filename);
             }
 
-            final String hashedKey;
-            final String binderKey;
-            if (mKey == null) {
-                hashedKey = "none";
-                binderKey = "";
-            } else {
-                try {
-                    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
-
-                    KeySpec ks = new PBEKeySpec(mKey.toCharArray(), mObbInfo.salt,
-                            PBKDF2_HASH_ROUNDS, CRYPTO_ALGORITHM_KEY_SIZE);
-                    SecretKey key = factory.generateSecret(ks);
-                    BigInteger bi = new BigInteger(key.getEncoded());
-                    hashedKey = bi.toString(16);
-                    binderKey = hashedKey;
-                } catch (GeneralSecurityException e) {
-                    throw new ObbException(ERROR_INTERNAL, e);
-                }
-            }
-
             try {
-                mObbState.volId = mVold.createObb(mObbState.canonicalPath, binderKey,
-                        mObbState.ownerGid);
+                mObbState.volId = mVold.createObb(mObbState.canonicalPath, mObbState.ownerGid);
                 mVold.mount(mObbState.volId, 0, -1, null);
 
                 if (DEBUG_OBB)
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 40ab0c0..839cdc6 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -91,7 +91,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
-import com.android.internal.telephony.ICarrierPrivilegesListener;
+import com.android.internal.telephony.ICarrierPrivilegesCallback;
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
 import com.android.internal.telephony.IPhoneStateListener;
 import com.android.internal.telephony.ITelephonyRegistry;
@@ -153,7 +153,7 @@
         IPhoneStateListener callback;
         IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback;
         IOnSubscriptionsChangedListener onOpportunisticSubscriptionsChangedListenerCallback;
-        ICarrierPrivilegesListener carrierPrivilegesListener;
+        ICarrierPrivilegesCallback carrierPrivilegesCallback;
 
         int callerUid;
         int callerPid;
@@ -178,8 +178,8 @@
             return (onOpportunisticSubscriptionsChangedListenerCallback != null);
         }
 
-        boolean matchCarrierPrivilegesListener() {
-            return carrierPrivilegesListener != null;
+        boolean matchCarrierPrivilegesCallback() {
+            return carrierPrivilegesCallback != null;
         }
 
         boolean canReadCallLog() {
@@ -199,7 +199,7 @@
                     + onSubscriptionsChangedListenerCallback
                     + " onOpportunisticSubscriptionsChangedListenererCallback="
                     + onOpportunisticSubscriptionsChangedListenerCallback
-                    + " carrierPrivilegesListener=" + carrierPrivilegesListener
+                    + " carrierPrivilegesCallback=" + carrierPrivilegesCallback
                     + " subId=" + subId + " phoneId=" + phoneId + " events=" + eventList + "}";
         }
     }
@@ -414,7 +414,9 @@
             mPreciseDataConnectionStates;
 
     /** Per-phoneId snapshot of privileged packages (names + UIDs). */
-    private List<Pair<List<String>, int[]>> mCarrierPrivilegeStates;
+    @NonNull private List<Pair<List<String>, int[]>> mCarrierPrivilegeStates;
+    /** Per-phoneId of CarrierService (PackageName, UID) pair. */
+    @NonNull private List<Pair<String, Integer>> mCarrierServiceStates;
 
     /**
      * Support backward compatibility for {@link android.telephony.TelephonyDisplayInfo}.
@@ -705,6 +707,7 @@
                 cutListToSize(mPhysicalChannelConfigs, mNumPhones);
                 cutListToSize(mLinkCapacityEstimateLists, mNumPhones);
                 cutListToSize(mCarrierPrivilegeStates, mNumPhones);
+                cutListToSize(mCarrierServiceStates, mNumPhones);
                 return;
             }
 
@@ -746,6 +749,7 @@
                 mAllowedNetworkTypeValue[i] = -1;
                 mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST);
                 mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0]));
+                mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID));
             }
         }
     }
@@ -813,6 +817,7 @@
         mDataEnabledReason = new int[numPhones];
         mLinkCapacityEstimateLists = new ArrayList<>();
         mCarrierPrivilegeStates = new ArrayList<>();
+        mCarrierServiceStates = new ArrayList<>();
 
         for (int i = 0; i < numPhones; i++) {
             mCallState[i] =  TelephonyManager.CALL_STATE_IDLE;
@@ -851,6 +856,7 @@
             mAllowedNetworkTypeValue[i] = -1;
             mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST);
             mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0]));
+            mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID));
         }
 
         mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -2013,10 +2019,8 @@
             return;
         }
 
-        ApnSetting apnSetting = preciseState.getApnSetting();
-
         synchronized (mRecords) {
-            if (validatePhoneId(phoneId)) {
+            if (validatePhoneId(phoneId) && preciseState.getApnSetting() != null) {
                 Pair<Integer, ApnSetting> key = Pair.create(preciseState.getTransportType(),
                         preciseState.getApnSetting());
                 PreciseDataConnectionState oldState = mPreciseDataConnectionStates.get(phoneId)
@@ -2786,16 +2790,16 @@
     }
 
     @Override
-    public void addCarrierPrivilegesListener(
+    public void addCarrierPrivilegesCallback(
             int phoneId,
-            ICarrierPrivilegesListener callback,
-            String callingPackage,
-            String callingFeatureId) {
+            @NonNull ICarrierPrivilegesCallback callback,
+            @NonNull String callingPackage,
+            @NonNull String callingFeatureId) {
         int callerUserId = UserHandle.getCallingUserId();
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
-                "addCarrierPrivilegesListener");
+                "addCarrierPrivilegesCallback");
         if (VDBG) {
             log(
                     "listen carrier privs: E pkg=" + pii(callingPackage) + " phoneId=" + phoneId
@@ -2815,7 +2819,7 @@
             if (r == null) return;
 
             r.context = mContext;
-            r.carrierPrivilegesListener = callback;
+            r.carrierPrivilegesCallback = callback;
             r.callingPackage = callingPackage;
             r.callingFeatureId = callingFeatureId;
             r.callerUid = Binder.getCallingUid();
@@ -2827,10 +2831,18 @@
             }
 
             Pair<List<String>, int[]> state = mCarrierPrivilegeStates.get(phoneId);
+            Pair<String, Integer> carrierServiceState = mCarrierServiceStates.get(phoneId);
             try {
-                r.carrierPrivilegesListener.onCarrierPrivilegesChanged(
-                        Collections.unmodifiableList(state.first),
-                        Arrays.copyOf(state.second, state.second.length));
+                if (r.matchCarrierPrivilegesCallback()) {
+                    // Here, two callbacks are triggered in quick succession on the same binder.
+                    // In typical case, we expect the callers to care about only one or the other.
+                    r.carrierPrivilegesCallback.onCarrierPrivilegesChanged(
+                            Collections.unmodifiableList(state.first),
+                            Arrays.copyOf(state.second, state.second.length));
+
+                    r.carrierPrivilegesCallback.onCarrierServiceChanged(carrierServiceState.first,
+                            carrierServiceState.second);
+                }
             } catch (RemoteException ex) {
                 remove(r.binder);
             }
@@ -2838,12 +2850,12 @@
     }
 
     @Override
-    public void removeCarrierPrivilegesListener(
-            ICarrierPrivilegesListener callback, String callingPackage) {
+    public void removeCarrierPrivilegesCallback(
+            @NonNull ICarrierPrivilegesCallback callback, @NonNull String callingPackage) {
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
-                "removeCarrierPrivilegesListener");
+                "removeCarrierPrivilegesCallback");
         remove(callback.asBinder());
     }
 
@@ -2868,13 +2880,13 @@
             for (Record r : mRecords) {
                 // Listeners are per-slot, not per-subscription. This is to provide a stable
                 // view across SIM profile switches.
-                if (!r.matchCarrierPrivilegesListener()
+                if (!r.matchCarrierPrivilegesCallback()
                         || !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) {
                     continue;
                 }
                 try {
                     // Make sure even in-process listeners can't modify the values.
-                    r.carrierPrivilegesListener.onCarrierPrivilegesChanged(
+                    r.carrierPrivilegesCallback.onCarrierPrivilegesChanged(
                             Collections.unmodifiableList(privilegedPackageNames),
                             Arrays.copyOf(privilegedUids, privilegedUids.length));
                 } catch (RemoteException ex) {
@@ -2885,6 +2897,34 @@
         }
     }
 
+    @Override
+    public void notifyCarrierServiceChanged(int phoneId, @Nullable String packageName, int uid) {
+        if (!checkNotifyPermission("notifyCarrierServiceChanged")) return;
+        if (!validatePhoneId(phoneId)) return;
+        if (VDBG) {
+            log("notifyCarrierServiceChanged: phoneId=" + phoneId
+                    + ", package=" + pii(packageName) + ", uid=" + uid);
+        }
+
+        synchronized (mRecords) {
+            mCarrierServiceStates.set(
+                    phoneId, new Pair<>(packageName, uid));
+            for (Record r : mRecords) {
+                // Listeners are per-slot, not per-subscription.
+                if (!r.matchCarrierPrivilegesCallback()
+                        || !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) {
+                    continue;
+                }
+                try {
+                    r.carrierPrivilegesCallback.onCarrierServiceChanged(packageName, uid);
+                } catch (RemoteException ex) {
+                    mRemoveList.add(r.binder);
+                }
+            }
+            handleRemoveListLocked();
+        }
+    }
+
     @NeverCompile // Avoid size overhead of debugging code.
     @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
@@ -2940,6 +2980,9 @@
                 pw.println(
                         "mCarrierPrivilegeState=<packages=" + pii(carrierPrivilegeState.first)
                                 + ", uids=" + Arrays.toString(carrierPrivilegeState.second) + ">");
+                Pair<String, Integer> carrierServiceState = mCarrierServiceStates.get(i);
+                pw.println("mCarrierServiceState=<package=" + pii(carrierServiceState.first)
+                        + ", uid=" + carrierServiceState.second + ">");
                 pw.decreaseIndent();
             }
 
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index d4ad718..48e3264 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2722,7 +2722,7 @@
     int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
             String resolvedType, final IServiceConnection connection, int flags,
             String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid,
-            String callingPackage, final int userId)
+            String sdkSandboxClientAppPackage, String callingPackage, final int userId)
             throws TransactionTooLargeException {
         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
                 + " type=" + resolvedType + " conn=" + connection.asBinder()
@@ -2807,8 +2807,9 @@
         final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0;
 
         ServiceLookupResult res = retrieveServiceLocked(service, instanceName,
-                isSdkSandboxService, sdkSandboxClientAppUid, resolvedType, callingPackage,
-                callingPid, callingUid, userId, true, callerFg, isBindExternal, allowInstant);
+                isSdkSandboxService, sdkSandboxClientAppUid, sdkSandboxClientAppPackage,
+                resolvedType, callingPackage, callingPid, callingUid, userId, true, callerFg,
+                isBindExternal, allowInstant);
         if (res == null) {
             return 0;
         }
@@ -3228,14 +3229,14 @@
             int callingPid, int callingUid, int userId,
             boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
             boolean allowInstant) {
-        return retrieveServiceLocked(service, instanceName, false, 0, resolvedType, callingPackage,
-                callingPid, callingUid, userId, createIfNeeded, callingFromFg, isBindExternal,
-                allowInstant);
+        return retrieveServiceLocked(service, instanceName, false, 0, null, resolvedType,
+                callingPackage, callingPid, callingUid, userId, createIfNeeded, callingFromFg,
+                isBindExternal, allowInstant);
     }
 
     private ServiceLookupResult retrieveServiceLocked(Intent service,
             String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid,
-            String resolvedType,
+            String sdkSandboxClientAppPackage, String resolvedType,
             String callingPackage, int callingPid, int callingUid, int userId,
             boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
             boolean allowInstant) {
@@ -3416,7 +3417,8 @@
                                                                                   : null;
                     r = new ServiceRecord(mAm, className, name, definingPackageName,
                             definingUid, filter, sInfo, callingFromFg, res,
-                            sdkSandboxProcessName, sdkSandboxClientAppUid);
+                            sdkSandboxProcessName, sdkSandboxClientAppUid,
+                            sdkSandboxClientAppPackage);
                     res.setService(r);
                     smap.mServicesByInstanceName.put(name, r);
                     smap.mServicesByIntent.put(filter, r);
@@ -4195,7 +4197,7 @@
             if (r.isSdkSandbox) {
                 final int uid = Process.toSdkSandboxUid(r.sdkSandboxClientAppUid);
                 app = mAm.startSdkSandboxProcessLocked(procName, r.appInfo, true, intentFlags,
-                        hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, uid);
+                        hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, uid, r.sdkSandboxClientAppPackage);
                 r.isolationHostProc = app;
             } else {
                 app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 5fe8719..c426662 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -127,7 +127,15 @@
     static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE = "kill_bg_restricted_cached_idle";
     static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME =
             "kill_bg_restricted_cached_idle_settle_time";
+    /**
+     * Note this key is on {@link DeviceConfig#NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS}.
+     * @see #mEnableComponentAlias
+     */
     static final String KEY_ENABLE_COMPONENT_ALIAS = "enable_experimental_component_alias";
+    /**
+     * Note this key is on {@link DeviceConfig#NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS}.
+     * @see #mComponentAliasOverrides
+     */
     static final String KEY_COMPONENT_ALIAS_OVERRIDES = "component_alias_overrides";
 
     private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
@@ -650,6 +658,38 @@
     // initialized in the constructor.
     public int CUR_MAX_EMPTY_PROCESSES;
 
+
+    /** @see #mNoKillCachedProcessesUntilBootCompleted */
+    private static final String KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED =
+            "no_kill_cached_processes_until_boot_completed";
+
+    /** @see #mNoKillCachedProcessesPostBootCompletedDurationMillis */
+    private static final String KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS =
+            "no_kill_cached_processes_post_boot_completed_duration_millis";
+
+    /** @see #mNoKillCachedProcessesUntilBootCompleted */
+    private static final boolean DEFAULT_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED = false;
+
+    /** @see #mNoKillCachedProcessesPostBootCompletedDurationMillis */
+    private static final long
+            DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS = 0;
+
+    /**
+     * If true, do not kill excessive cached processes proactively, until user-0 is unlocked.
+     * @see #mNoKillCachedProcessesPostBootCompletedDurationMillis
+     */
+    volatile boolean mNoKillCachedProcessesUntilBootCompleted =
+            DEFAULT_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED;
+
+    /**
+     * Do not kill excessive cached processes proactively, for this duration after each user is
+     * unlocked.
+     * Note we don't proactively kill extra cached processes after this. The next oomadjuster pass
+     * will naturally do it.
+     */
+    volatile long mNoKillCachedProcessesPostBootCompletedDurationMillis =
+            DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS;
+
     // The number of empty apps at which we don't consider it necessary to do
     // memory trimming.
     public int CUR_TRIM_EMPTY_PROCESSES = computeEmptyProcessLimit(MAX_CACHED_PROCESSES) / 2;
@@ -659,6 +699,14 @@
     public int CUR_TRIM_CACHED_PROCESSES =
             (MAX_CACHED_PROCESSES - computeEmptyProcessLimit(MAX_CACHED_PROCESSES)) / 3;
 
+    /** @see #mNoKillCachedProcessesUntilBootCompleted */
+    private static final String KEY_MAX_EMPTY_TIME_MILLIS =
+            "max_empty_time_millis";
+
+    private static final long DEFAULT_MAX_EMPTY_TIME_MILLIS = 30 * 60 * 1000;
+
+    volatile long mMaxEmptyTimeMillis = DEFAULT_MAX_EMPTY_TIME_MILLIS;
+
     /**
      * Packages that can't be killed even if it's requested to be killed on imperceptible.
      */
@@ -859,16 +907,41 @@
                             case KEY_ENABLE_EXTRA_SERVICE_RESTART_DELAY_ON_MEM_PRESSURE:
                                 updateEnableExtraServiceRestartDelayOnMemPressure();
                                 break;
-                            case KEY_ENABLE_COMPONENT_ALIAS:
-                            case KEY_COMPONENT_ALIAS_OVERRIDES:
-                                updateComponentAliases();
-                                break;
                             case KEY_PROCESS_KILL_TIMEOUT:
                                 updateProcessKillTimeout();
                                 break;
                             case KEY_DEFER_BOOT_COMPLETED_BROADCAST:
                                 updateDeferBootCompletedBroadcast();
                                 break;
+                            case KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED:
+                                updateNoKillCachedProcessesUntilBootCompleted();
+                                break;
+                            case KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS:
+                                updateNoKillCachedProcessesPostBootCompletedDurationMillis();
+                                break;
+                            case KEY_MAX_EMPTY_TIME_MILLIS:
+                                updateMaxEmptyTimeMillis();
+                                break;
+                            default:
+                                break;
+                        }
+                    }
+                }
+            };
+
+    private final OnPropertiesChangedListener mOnDeviceConfigChangedForComponentAliasListener =
+            new OnPropertiesChangedListener() {
+                @Override
+                public void onPropertiesChanged(Properties properties) {
+                    for (String name : properties.getKeyset()) {
+                        if (name == null) {
+                            return;
+                        }
+                        switch (name) {
+                            case KEY_ENABLE_COMPONENT_ALIAS:
+                            case KEY_COMPONENT_ALIAS_OVERRIDES:
+                                updateComponentAliases();
+                                break;
                             default:
                                 break;
                         }
@@ -942,6 +1015,10 @@
         DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                 ActivityThread.currentApplication().getMainExecutor(),
                 mOnDeviceConfigChangedListener);
+        DeviceConfig.addOnPropertiesChangedListener(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS,
+                ActivityThread.currentApplication().getMainExecutor(),
+                mOnDeviceConfigChangedForComponentAliasListener);
         loadDeviceConfigConstants();
         // The following read from Settings.
         updateActivityStartsLoggingEnabled();
@@ -951,6 +1028,9 @@
     private void loadDeviceConfigConstants() {
         mOnDeviceConfigChangedListener.onPropertiesChanged(
                 DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER));
+        mOnDeviceConfigChangedForComponentAliasListener.onPropertiesChanged(
+                DeviceConfig.getProperties(
+                        DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS));
     }
 
     public void setOverrideMaxCachedProcesses(int value) {
@@ -1288,6 +1368,27 @@
                 DEFAULT_DEFER_BOOT_COMPLETED_BROADCAST);
     }
 
+    private void updateNoKillCachedProcessesUntilBootCompleted() {
+        mNoKillCachedProcessesUntilBootCompleted = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED,
+                DEFAULT_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED);
+    }
+
+    private void updateNoKillCachedProcessesPostBootCompletedDurationMillis() {
+        mNoKillCachedProcessesPostBootCompletedDurationMillis = DeviceConfig.getLong(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS,
+                DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS);
+    }
+
+    private void updateMaxEmptyTimeMillis() {
+        mMaxEmptyTimeMillis = DeviceConfig.getLong(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_MAX_EMPTY_TIME_MILLIS,
+                DEFAULT_MAX_EMPTY_TIME_MILLIS);
+    }
+
     private long[] parseLongArray(@NonNull String key, @NonNull long[] def) {
         final String val = DeviceConfig.getString(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                 key, null);
@@ -1309,11 +1410,11 @@
 
     private void updateComponentAliases() {
         mEnableComponentAlias = DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS,
                 KEY_ENABLE_COMPONENT_ALIAS,
                 DEFAULT_ENABLE_COMPONENT_ALIAS);
         mComponentAliasOverrides = DeviceConfig.getString(
-                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS,
                 KEY_COMPONENT_ALIAS_OVERRIDES,
                 DEFAULT_COMPONENT_ALIAS_OVERRIDES);
         mService.mComponentAliasResolver.update(mEnableComponentAlias, mComponentAliasOverrides);
@@ -1562,6 +1663,12 @@
         pw.print("="); pw.println(mComponentAliasOverrides);
         pw.print("  "); pw.print(KEY_DEFER_BOOT_COMPLETED_BROADCAST);
         pw.print("="); pw.println(mDeferBootCompletedBroadcast);
+        pw.print("  "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED);
+        pw.print("="); pw.println(mNoKillCachedProcessesUntilBootCompleted);
+        pw.print("  "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS);
+        pw.print("="); pw.println(mNoKillCachedProcessesPostBootCompletedDurationMillis);
+        pw.print("  "); pw.print(KEY_MAX_EMPTY_TIME_MILLIS);
+        pw.print("="); pw.println(mMaxEmptyTimeMillis);
 
         pw.println();
         if (mOverrideMaxCachedProcesses >= 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerLocal.java b/services/core/java/com/android/server/am/ActivityManagerLocal.java
index 3226a2b..1d2c36b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerLocal.java
+++ b/services/core/java/com/android/server/am/ActivityManagerLocal.java
@@ -74,6 +74,8 @@
      * @param conn Receives information as the service is started and stopped.
      *        This must be a valid ServiceConnection object; it must not be null.
      * @param clientAppUid Uid of the app for which the sdk sandbox process needs to be spawned.
+     * @param clientAppPackage Package of the app for which the sdk sandbox process needs to
+     *        be spawned. This package must belong to the clientAppUid.
      * @param processName Unique identifier for the service instance. Each unique name here will
      *        result in a different service instance being created. Identifiers must only contain
      *        ASCII letters, digits, underscores, and periods.
@@ -87,6 +89,7 @@
      */
     @SuppressLint("RethrowRemoteException")
     boolean bindSdkSandboxService(@NonNull Intent service, @NonNull ServiceConnection conn,
-            int clientAppUid, @NonNull String processName, @Context.BindServiceFlags int flags)
+            int clientAppUid, @NonNull String clientAppPackage, @NonNull String processName,
+            @Context.BindServiceFlags int flags)
             throws RemoteException;
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 47f9fd5..0735648 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -36,6 +36,7 @@
 import static android.app.ActivityManager.StopUserOnSwitch;
 import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
+import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.OP_NONE;
 import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
 import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES;
@@ -79,6 +80,7 @@
 import static android.os.Process.ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS;
 import static android.os.Process.ZYGOTE_PROCESS;
 import static android.os.Process.getTotalMemory;
+import static android.os.Process.isSdkSandboxUid;
 import static android.os.Process.isThreadInProcess;
 import static android.os.Process.killProcess;
 import static android.os.Process.killProcessQuiet;
@@ -1894,6 +1896,7 @@
                         0,
                         false,
                         0,
+                        null,
                         new HostingRecord("system"));
                 app.setPersistent(true);
                 app.setPid(MY_PID);
@@ -2782,7 +2785,8 @@
                     false /* knownToBeDead */, 0 /* intentFlags */,
                     sNullHostingRecord  /* hostingRecord */, ZYGOTE_POLICY_FLAG_EMPTY,
                     true /* allowWhileBooting */, true /* isolated */,
-                    uid, false /* supplemental */, 0 /* supplementalUid */,
+                    uid, false /* isSdkSandbox */, 0 /* sdkSandboxUid */,
+                    null /* sdkSandboxClientAppPackage */,
                     abiOverride, entryPoint, entryPointArgs, crashHandler);
             return proc != null;
         }
@@ -2791,11 +2795,12 @@
     @GuardedBy("this")
     final ProcessRecord startSdkSandboxProcessLocked(String processName,
             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
-            HostingRecord hostingRecord, int zygotePolicyFlags, int sdkSandboxUid) {
+            HostingRecord hostingRecord, int zygotePolicyFlags, int sdkSandboxUid,
+            String sdkSandboxClientAppPackage) {
         return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                 hostingRecord, zygotePolicyFlags, false /* allowWhileBooting */,
                 false /* isolated */, 0 /* isolatedUid */,
-                true /* isSdkSandbox */, sdkSandboxUid,
+                true /* isSdkSandbox */, sdkSandboxUid, sdkSandboxClientAppPackage,
                 null /* ABI override */, null /* entryPoint */,
                 null /* entryPointArgs */, null /* crashHandler */);
     }
@@ -2807,7 +2812,8 @@
             boolean isolated) {
         return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                 hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
-                false /* isSdkSandbox */, 0 /* sdkSandboxClientdAppUid */,
+                false /* isSdkSandbox */, 0 /* sdkSandboxClientAppUid */,
+                null /* sdkSandboxClientAppPackage */,
                 null /* ABI override */, null /* entryPoint */,
                 null /* entryPointArgs */, null /* crashHandler */);
     }
@@ -3779,7 +3785,7 @@
                     synchronized (mProcLock) {
                         mProcessList.killPackageProcessesLSP(packageName, appId, targetUserId,
                                 ProcessList.SERVICE_ADJ, ApplicationExitInfo.REASON_USER_REQUESTED,
-                                ApplicationExitInfo.SUBREASON_UNKNOWN, "kill background");
+                                ApplicationExitInfo.SUBREASON_KILL_BACKGROUND, "kill background");
                     }
                 }
             }
@@ -3809,7 +3815,7 @@
                     mProcessList.killPackageProcessesLSP(null /* packageName */, -1 /* appId */,
                             UserHandle.USER_ALL, ProcessList.CACHED_APP_MIN_ADJ,
                             ApplicationExitInfo.REASON_USER_REQUESTED,
-                            ApplicationExitInfo.SUBREASON_UNKNOWN,
+                            ApplicationExitInfo.SUBREASON_KILL_BACKGROUND,
                             "kill all background");
                 }
 
@@ -4351,7 +4357,7 @@
                         ProcessList.INVALID_ADJ, true, false, true,
                         false, true /* setRemoved */, false,
                         ApplicationExitInfo.REASON_USER_REQUESTED,
-                        ApplicationExitInfo.SUBREASON_UNKNOWN,
+                        ApplicationExitInfo.SUBREASON_STOP_APP,
                         "fully stop " + packageName + "/" + userId + " by user request");
             }
 
@@ -4403,7 +4409,7 @@
                     evenPersistent, true /* setRemoved */, uninstalling,
                     packageName == null ? ApplicationExitInfo.REASON_USER_STOPPED
                     : ApplicationExitInfo.REASON_USER_REQUESTED,
-                    ApplicationExitInfo.SUBREASON_UNKNOWN,
+                    ApplicationExitInfo.SUBREASON_FORCE_STOP,
                     (packageName == null ? ("stop user " + userId) : ("stop " + packageName))
                     + " due to " + reason);
         }
@@ -4772,7 +4778,8 @@
                 thread.runIsolatedEntryPoint(
                         app.getIsolatedEntryPoint(), app.getIsolatedEntryPointArgs());
             } else if (instr2 != null) {
-                thread.bindApplication(processName, appInfo, providerList,
+                thread.bindApplication(processName, appInfo, app.sdkSandboxClientAppPackage,
+                        providerList,
                         instr2.mClass,
                         profilerInfo, instr2.mArguments,
                         instr2.mWatcher,
@@ -4786,8 +4793,8 @@
                         app.getDisabledCompatChanges(), serializedSystemFontMap,
                         app.getStartElapsedTime(), app.getStartUptime());
             } else {
-                thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
-                        null, null, null, testMode,
+                thread.bindApplication(processName, appInfo, app.sdkSandboxClientAppPackage,
+                        providerList, null, profilerInfo, null, null, null, testMode,
                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
                         isRestrictedBackupMode || !normalMode, app.isPersistent(),
                         new Configuration(app.getWindowProcessController().getConfiguration()),
@@ -5748,6 +5755,18 @@
                 owningUid, exported);
     }
 
+    private void enforceDebuggable(ProcessRecord proc) {
+        if (!Build.IS_DEBUGGABLE && !proc.isDebuggable()) {
+            throw new SecurityException("Process not debuggable: " + proc.info.packageName);
+        }
+    }
+
+    private void enforceDebuggable(ApplicationInfo info) {
+        if (!Build.IS_DEBUGGABLE && (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
+            throw new SecurityException("Process not debuggable: " + info.packageName);
+        }
+    }
+
     /**
      * As the only public entry point for permissions checking, this method
      * can enforce the semantic that requesting a check on a null global
@@ -6552,7 +6571,7 @@
 
         if (app == null) {
             app = mProcessList.newProcessRecordLocked(info, customProcess, isolated, 0,
-                    false, 0,
+                    false, 0, null,
                     new HostingRecord("added application",
                         customProcess != null ? customProcess : info.processName));
             updateLruProcessLocked(app, false, null);
@@ -6785,22 +6804,25 @@
     }
 
     void setTrackAllocationApp(ApplicationInfo app, String processName) {
-        if (!Build.IS_DEBUGGABLE) {
-            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
-                throw new SecurityException("Process not debuggable: " + app.packageName);
-            }
-        }
+        enforceDebuggable(app);
 
         synchronized (mProcLock) {
             mTrackAllocationApp = processName;
         }
     }
 
-    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
+    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo,
+            ApplicationInfo sdkSandboxClientApp) {
         synchronized (mAppProfiler.mProfilerLock) {
             if (!Build.IS_DEBUGGABLE) {
                 boolean isAppDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
                 boolean isAppProfileable = app.isProfileableByShell();
+
+                if (sdkSandboxClientApp != null) {
+                    isAppDebuggable |=
+                            (sdkSandboxClientApp.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+                    isAppProfileable |= sdkSandboxClientApp.isProfileableByShell();
+                }
                 if (!isAppDebuggable && !isAppProfileable) {
                     throw new SecurityException("Process not debuggable, "
                             + "and not profileable by shell: " + app.packageName);
@@ -6811,11 +6833,7 @@
     }
 
     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
-        if (!Build.IS_DEBUGGABLE) {
-            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
-                throw new SecurityException("Process not debuggable: " + app.packageName);
-            }
-        }
+        enforceDebuggable(app);
         mNativeDebuggingApp = processName;
     }
 
@@ -8561,6 +8579,9 @@
             if (process.info.isInstantApp()) {
                 sb.append("Instant-App: true\n");
             }
+            if (isSdkSandboxUid(process.uid)) {
+                sb.append("SdkSandbox: true\n");
+            }
         }
     }
 
@@ -9752,7 +9773,7 @@
                     if (info.deniedPermissions != null) {
                         for (int j = 0; j < info.deniedPermissions.size(); j++) {
                             pw.print("      deny: ");
-                            pw.println(info.deniedPermissions.valueAt(i));
+                            pw.println(info.deniedPermissions.valueAt(j));
                         }
                     }
                 }
@@ -12391,13 +12412,13 @@
             String resolvedType, IServiceConnection connection, int flags, String instanceName,
             String callingPackage, int userId) throws TransactionTooLargeException {
         return bindServiceInstance(caller, token, service, resolvedType, connection, flags,
-                instanceName, false, 0, callingPackage, userId);
+                instanceName, false, 0, null, callingPackage, userId);
     }
 
     private int bindServiceInstance(IApplicationThread caller, IBinder token, Intent service,
             String resolvedType, IServiceConnection connection, int flags, String instanceName,
-            boolean isSdkSandboxService, int sdkSandboxClientdAppUid, String callingPackage,
-            int userId)
+            boolean isSdkSandboxService, int sdkSandboxClientAppUid,
+            String sdkSandboxClientAppPackage, String callingPackage, int userId)
             throws TransactionTooLargeException {
         enforceNotIsolatedCaller("bindService");
 
@@ -12434,8 +12455,8 @@
             }
             synchronized (this) {
                 return mServices.bindServiceLocked(caller, token, service, resolvedType, connection,
-                        flags, instanceName, isSdkSandboxService, sdkSandboxClientdAppUid,
-                        callingPackage, userId);
+                        flags, instanceName, isSdkSandboxService, sdkSandboxClientAppUid,
+                        sdkSandboxClientAppPackage, callingPackage, userId);
             }
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
@@ -13632,7 +13653,7 @@
                                                     UserHandle.getAppId(extraUid),
                                                     userId, ProcessList.INVALID_ADJ,
                                                     ApplicationExitInfo.REASON_USER_REQUESTED,
-                                                    ApplicationExitInfo.SUBREASON_UNKNOWN,
+                                                    ApplicationExitInfo.SUBREASON_PACKAGE_UPDATE,
                                                     "change " + ssp);
                                         }
                                     }
@@ -15558,12 +15579,7 @@
                     throw new IllegalArgumentException("Unknown process: " + process);
                 }
 
-                boolean isDebuggable = Build.IS_DEBUGGABLE;
-                if (!isDebuggable) {
-                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
-                        throw new SecurityException("Process not debuggable: " + proc);
-                    }
-                }
+                enforceDebuggable(proc);
 
                 mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
 
@@ -15666,10 +15682,7 @@
                     throw new SecurityException("No process found for calling pid "
                             + Binder.getCallingPid());
                 }
-                if (!Build.IS_DEBUGGABLE
-                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
-                    throw new SecurityException("Not running a debuggable build");
-                }
+                enforceDebuggable(proc);
                 processName = proc.processName;
                 uid = proc.uid;
                 if (reportPackage != null && !proc.getPkgList().containsKey(reportPackage)) {
@@ -15880,13 +15893,7 @@
             return false;
         }
 
-        if (!Build.IS_DEBUGGABLE) {
-            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
-                return false;
-            }
-        }
-
-        return true;
+        return Build.IS_DEBUGGABLE || process.isDebuggable();
     }
 
     public boolean startBinderTracking() throws RemoteException {
@@ -16018,22 +16025,29 @@
 
         @Override
         public boolean bindSdkSandboxService(Intent service, ServiceConnection conn,
-                int userAppUid, String processName, int flags) throws RemoteException {
+                int clientAppUid, String clientAppPackage, String processName, int flags)
+                throws RemoteException {
             if (service == null) {
                 throw new IllegalArgumentException("intent is null");
             }
             if (conn == null) {
                 throw new IllegalArgumentException("connection is null");
             }
+            if (clientAppPackage == null) {
+                throw new IllegalArgumentException("clientAppPackage is null");
+            }
             if (processName == null) {
                 throw new IllegalArgumentException("processName is null");
             }
             if (service.getComponent() == null) {
                 throw new IllegalArgumentException("service must specify explicit component");
             }
-            if (!UserHandle.isApp(userAppUid)) {
+            if (!UserHandle.isApp(clientAppUid)) {
                 throw new IllegalArgumentException("uid is not within application range");
             }
+            if (mAppOpsService.checkPackage(clientAppUid, clientAppPackage) != MODE_ALLOWED) {
+                throw new IllegalArgumentException("uid does not belong to provided package");
+            }
 
             Handler handler = mContext.getMainThreadHandler();
 
@@ -16042,8 +16056,8 @@
             return ActivityManagerService.this.bindServiceInstance(
                     mContext.getIApplicationThread(), mContext.getActivityToken(), service,
                     service.resolveTypeIfNeeded(mContext.getContentResolver()), sd, flags,
-                    processName, /*isSupplementalProcessService*/ true, userAppUid,
-                    mContext.getOpPackageName(), UserHandle.getUserId(userAppUid)) != 0;
+                    processName, /*isSdkSandboxService*/ true, clientAppUid, clientAppPackage,
+                    mContext.getOpPackageName(), UserHandle.getUserId(clientAppUid)) != 0;
         }
 
         @Override
@@ -16361,7 +16375,7 @@
                     if (pr.mState.getSetSchedGroup() == ProcessList.SCHED_GROUP_BACKGROUND
                             && pr.mReceivers.numberOfCurReceivers() == 0) {
                         pr.killLocked("remove task", ApplicationExitInfo.REASON_USER_REQUESTED,
-                                ApplicationExitInfo.SUBREASON_UNKNOWN, true);
+                                ApplicationExitInfo.SUBREASON_REMOVE_TASK, true);
                     } else {
                         // We delay killing processes that are not in the background or running a
                         // receiver.
@@ -16833,7 +16847,7 @@
                     }
 
                     if (profilerInfo != null) {
-                        setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
+                        setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, null);
                     }
                     wmLock.notify();
                 }
@@ -16998,7 +17012,17 @@
 
         @Override
         public void addPendingTopUid(int uid, int pid) {
-            mPendingStartActivityUids.add(uid, pid);
+            final boolean isNewPending = mPendingStartActivityUids.add(uid, pid);
+            // If the next top activity is in cached and frozen mode, WM should raise its priority
+            // to unfreeze it. This is done by calling AMS.updateOomAdj that will lower its oom adj.
+            // However, WM cannot hold the AMS clock here so the updateOomAdj operation is performed
+            // in a separate thread asynchronously. Therefore WM can't guarantee AMS will unfreeze
+            // next top activity on time. This race will fail the following binder transactions WM
+            // sends to the activity. After this race issue between WM/ATMS and AMS is solved, this
+            // workaround can be removed. (b/213288355)
+            if (isNewPending && mOomAdjuster != null) { // It can be null in unit test.
+                mOomAdjuster.mCachedAppOptimizer.unfreezeProcess(pid);
+            }
         }
 
         @Override
@@ -17611,11 +17635,7 @@
                     throw new IllegalArgumentException("Unknown process: " + process);
                 }
 
-                if (!Build.IS_DEBUGGABLE) {
-                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
-                        throw new SecurityException("Process not debuggable: " + proc);
-                    }
-                }
+                enforceDebuggable(proc);
 
                 thread.attachAgent(path);
             }
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 28b807c..2b61e7f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -343,6 +343,8 @@
                     return runSetStopUserOnSwitch(pw);
                 case "set-bg-abusive-uids":
                     return runSetBgAbusiveUids(pw);
+                case "list-bg-exemptions-config":
+                    return runListBgExemptionsConfig(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -3292,6 +3294,19 @@
         return 0;
     }
 
+    private int runListBgExemptionsConfig(PrintWriter pw) throws RemoteException {
+        final ArraySet<String> sysConfigs = mInternal.mAppRestrictionController
+                .mBgRestrictionExemptioFromSysConfig;
+        if (sysConfigs != null) {
+            for (int i = 0, size = sysConfigs.size(); i < size; i++) {
+                pw.print(sysConfigs.valueAt(i));
+                pw.print(' ');
+            }
+            pw.println();
+        }
+        return 0;
+    }
+
     private Resources getResources(PrintWriter pw) throws RemoteException {
         // system resources does not contain all the device configuration, construct it manually.
         Configuration config = mInterface.getConfiguration();
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 7579d2b..ea1e335 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -28,7 +28,6 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.BatteryConsumer.POWER_COMPONENT_ANY;
 import static android.os.BatteryConsumer.PROCESS_STATE_BACKGROUND;
-import static android.os.BatteryConsumer.PROCESS_STATE_COUNT;
 import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND;
 import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE;
 import static android.os.BatteryConsumer.PROCESS_STATE_UNSPECIFIED;
@@ -38,7 +37,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.AppRestrictionController.DEVICE_CONFIG_SUBNAMESPACE_PREFIX;
-import static com.android.server.am.BaseAppStateTracker.ONE_MINUTE;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -71,7 +69,6 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.server.am.AppBatteryTracker.AppBatteryPolicy;
 import com.android.server.am.AppRestrictionController.UidBatteryUsageProvider;
-import com.android.server.am.BaseAppStateTracker.Injector;
 import com.android.server.pm.UserManagerInternal;
 
 import java.io.PrintWriter;
@@ -684,7 +681,7 @@
         static final int BATTERY_USAGE_INDEX_FOREGROUND = PROCESS_STATE_FOREGROUND;
         static final int BATTERY_USAGE_INDEX_BACKGROUND = PROCESS_STATE_BACKGROUND;
         static final int BATTERY_USAGE_INDEX_FOREGROUND_SERVICE = PROCESS_STATE_FOREGROUND_SERVICE;
-        static final int BATTERY_USAGE_COUNT = PROCESS_STATE_COUNT;
+        static final int BATTERY_USAGE_COUNT = 4;
 
         static final Dimensions[] BATT_DIMENS = new Dimensions[] {
                 new Dimensions(AppBatteryPolicy.DEFAULT_BG_CURRENT_DRAIN_POWER_COMPONENTS,
@@ -1217,7 +1214,7 @@
             mDefaultBgCurrentDrainBgRestrictedThreshold =
                     isLowRamDeviceStatic() ? val[1] : val[0];
             mDefaultBgCurrentDrainWindowMs = resources.getInteger(
-                    R.integer.config_bg_current_drain_window);
+                    R.integer.config_bg_current_drain_window) * 1_000;
             val = getFloatArray(resources.obtainTypedArray(
                     R.array.config_bg_current_drain_high_threshold_to_restricted_bucket));
             mDefaultBgCurrentDrainRestrictedBucketHighThreshold =
@@ -1227,9 +1224,9 @@
             mDefaultBgCurrentDrainBgRestrictedHighThreshold =
                     isLowRamDeviceStatic() ? val[1] : val[0];
             mDefaultBgCurrentDrainMediaPlaybackMinDuration = resources.getInteger(
-                    R.integer.config_bg_current_drain_media_playback_min_duration);
+                    R.integer.config_bg_current_drain_media_playback_min_duration) * 1_000;
             mDefaultBgCurrentDrainLocationMinDuration = resources.getInteger(
-                    R.integer.config_bg_current_drain_location_min_duration);
+                    R.integer.config_bg_current_drain_location_min_duration) * 1_000;
             mDefaultBgCurrentDrainEventDurationBasedThresholdEnabled = resources.getBoolean(
                     R.bool.config_bg_current_drain_event_duration_based_threshold_enabled);
             mDefaultCurrentDrainTypesToRestrictedBucket = resources.getInteger(
diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java
index fc29982..d84c1fc 100644
--- a/services/core/java/com/android/server/am/AppExitInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java
@@ -1002,6 +1002,7 @@
             info.setPackageName(app.info.packageName);
             info.setPackageList(app.getPackageList());
             info.setReason(ApplicationExitInfo.REASON_UNKNOWN);
+            info.setSubReason(ApplicationExitInfo.SUBREASON_UNKNOWN);
             info.setStatus(0);
             info.setImportance(procStateToImportance(app.mState.getReportedProcState()));
             info.setPss(app.mProfile.getLastPss());
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index d6a4cf6..16a7283 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -58,7 +58,6 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Binder;
@@ -608,13 +607,7 @@
         if (check != null) {
             if ((pss * 1024) >= check && profile.getThread() != null
                     && mMemWatchDumpProcName == null) {
-                boolean isDebuggable = Build.IS_DEBUGGABLE;
-                if (!isDebuggable) {
-                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
-                        isDebuggable = true;
-                    }
-                }
-                if (isDebuggable) {
+                if (Build.IS_DEBUGGABLE || proc.isDebuggable()) {
                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
                     startHeapDumpLPf(profile, false);
                 } else {
@@ -1702,7 +1695,8 @@
         try {
             if (start) {
                 stopProfilerLPf(null, 0);
-                mService.setProfileApp(proc.info, proc.processName, profilerInfo);
+                mService.setProfileApp(proc.info, proc.processName, profilerInfo,
+                        proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null);
                 mProfileData.setProfileProc(proc);
                 mProfileType = profileType;
                 ParcelFileDescriptor fd = profilerInfo.profileFd;
@@ -1886,8 +1880,7 @@
                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
                                     if (ps == null || !ps.isActive()) {
                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
-                                                bstats.mapUid(st.uid), st.name,
-                                                elapsedRealtime, uptime);
+                                                st.uid, st.name, elapsedRealtime, uptime);
                                     }
                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
                                 }
@@ -2076,7 +2069,7 @@
             if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
                 // We need to do a debuggable check here. See setAgentApp for why the check is
                 // postponed to here.
-                if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+                if (app.isDebuggable()) {
                     String agent = mAppAgentMap.get(processName);
                     // Do not overwrite already requested agent.
                     if (profilerInfo == null) {
@@ -2133,7 +2126,7 @@
         if (preBindAgent != null) {
             thread.attachAgent(preBindAgent);
         }
-        if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+        if (app.isDebuggable()) {
             thread.attachStartupAgents(app.info.dataDir);
         }
         return profilerInfo;
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 6e6cb87..dc8403a 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -182,7 +182,7 @@
     /**
      * Whether or not to show the foreground service manager on tapping notifications.
      */
-    private static final boolean ENABLE_SHOW_FOREGROUND_SERVICE_MANAGER = false;
+    private static final boolean ENABLE_SHOW_FOREGROUND_SERVICE_MANAGER = true;
 
     private final Context mContext;
     private final HandlerThread mBgHandlerThread;
@@ -241,7 +241,7 @@
     /**
      * The pre-config packages that are exempted from the background restrictions.
      */
-    private ArraySet<String> mBgRestrictionExemptioFromSysConfig;
+    ArraySet<String> mBgRestrictionExemptioFromSysConfig;
 
     /**
      * Lock specifically for bookkeeping around the carrier-privileged app set.
@@ -1595,8 +1595,8 @@
                         cancelRequestBgRestrictedIfNecessary(packageName, uid);
                         final Intent newIntent = new Intent(ACTION_SHOW_FOREGROUND_SERVICE_MANAGER);
                         newIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-                        mContext.sendBroadcastAsUser(newIntent,
-                                UserHandle.of(UserHandle.getUserId(uid)));
+                        // Task manager runs in SystemUI, which is SYSTEM user only.
+                        mContext.sendBroadcastAsUser(newIntent, UserHandle.SYSTEM);
                         break;
                 }
             }
@@ -1670,9 +1670,10 @@
             if (ENABLE_SHOW_FOREGROUND_SERVICE_MANAGER) {
                 final Intent intent = new Intent(ACTION_SHOW_FOREGROUND_SERVICE_MANAGER);
                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+                // Task manager runs in SystemUI, which is SYSTEM user only.
                 pendingIntent = PendingIntent.getBroadcastAsUser(mContext, 0,
                         intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE,
-                        UserHandle.of(UserHandle.getUserId(uid)));
+                        UserHandle.SYSTEM);
             } else {
                 final Intent intent = new Intent(Settings.ACTION_VIEW_ADVANCED_POWER_USAGE_DETAIL);
                 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
@@ -1750,7 +1751,7 @@
                     SYSTEM_UID, UserHandle.getUserId(uid));
             final String title = mContext.getString(titleRes);
             final String message = mContext.getString(messageRes,
-                    ai != null ? pm.getText(packageName, ai.labelRes, ai) : packageName);
+                    ai != null ? ai.loadLabel(pm) : packageName);
             final Icon icon = ai != null ? Icon.createWithResource(packageName, ai.icon) : null;
 
             postNotification(notificationId, packageName, uid, title, message, icon, pendingIntent,
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 91822ac..eb7897b 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -799,6 +799,7 @@
                     final BatteryUsageStatsQuery querySinceReset =
                             new BatteryUsageStatsQuery.Builder()
                                     .includeProcessStateData()
+                                    .includeVirtualUids()
                                     .build();
                     bus = getBatteryUsageStats(List.of(querySinceReset)).get(0);
                     break;
@@ -806,6 +807,7 @@
                     final BatteryUsageStatsQuery queryPowerProfile =
                             new BatteryUsageStatsQuery.Builder()
                                     .includeProcessStateData()
+                                    .includeVirtualUids()
                                     .powerProfileModeledOnly()
                                     .build();
                     bus = getBatteryUsageStats(List.of(queryPowerProfile)).get(0);
@@ -821,6 +823,7 @@
                     final BatteryUsageStatsQuery queryBeforeReset =
                             new BatteryUsageStatsQuery.Builder()
                                     .includeProcessStateData()
+                                    .includeVirtualUids()
                                     .aggregateSnapshots(sessionStart, sessionEnd)
                                     .build();
                     bus = getBatteryUsageStats(List.of(queryBeforeReset)).get(0);
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index ea63c08..ade44ea 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -21,6 +21,9 @@
 import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE;
 import static android.text.TextUtils.formatSimple;
 
+import static com.android.internal.util.FrameworkStatsLog.BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED;
+import static com.android.internal.util.FrameworkStatsLog.BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED__EVENT__BOOT_COMPLETED;
+import static com.android.internal.util.FrameworkStatsLog.BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED__EVENT__LOCKED_BOOT_COMPLETED;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_DEFERRAL;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
@@ -29,6 +32,7 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
 
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -51,6 +55,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -64,6 +69,7 @@
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.permission.IPermissionManager;
 import android.text.TextUtils;
 import android.util.EventLog;
@@ -75,6 +81,7 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.LocalServices;
+import com.android.server.pm.UserManagerInternal;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -250,12 +257,16 @@
 
     public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
         r.enqueueClockTime = System.currentTimeMillis();
+        r.enqueueTime = SystemClock.uptimeMillis();
+        r.enqueueRealTime = SystemClock.elapsedRealtime();
         mParallelBroadcasts.add(r);
         enqueueBroadcastHelper(r);
     }
 
     public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
         r.enqueueClockTime = System.currentTimeMillis();
+        r.enqueueTime = SystemClock.uptimeMillis();
+        r.enqueueRealTime = SystemClock.elapsedRealtime();
         mDispatcher.enqueueOrderedBroadcastLocked(r);
         enqueueBroadcastHelper(r);
     }
@@ -1121,6 +1132,7 @@
         while (mParallelBroadcasts.size() > 0) {
             r = mParallelBroadcasts.remove(0);
             r.dispatchTime = SystemClock.uptimeMillis();
+            r.dispatchRealTime = SystemClock.elapsedRealtime();
             r.dispatchClockTime = System.currentTimeMillis();
 
             if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
@@ -1292,6 +1304,7 @@
                             performReceiveLocked(r.callerApp, r.resultTo,
                                     new Intent(r.intent), r.resultCode,
                                     r.resultData, r.resultExtras, false, false, r.userId);
+                            logBootCompletedBroadcastCompletionLatencyIfPossible(r);
                             // Set this to null so that the reference
                             // (local and remote) isn't kept in the mBroadcastHistory.
                             r.resultTo = null;
@@ -1408,6 +1421,7 @@
         r.receiverTime = SystemClock.uptimeMillis();
         if (recIdx == 0) {
             r.dispatchTime = r.receiverTime;
+            r.dispatchRealTime = SystemClock.elapsedRealtime();
             r.dispatchClockTime = System.currentTimeMillis();
 
             if (mLogLatencyMetrics) {
@@ -1866,6 +1880,59 @@
         return null;
     }
 
+    private void logBootCompletedBroadcastCompletionLatencyIfPossible(BroadcastRecord r) {
+        // Only log after last receiver.
+        // In case of split BOOT_COMPLETED broadcast, make sure only call this method on the
+        // last BroadcastRecord of the split broadcast which has non-null resultTo.
+        final int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
+        if (r.nextReceiver < numReceivers) {
+            return;
+        }
+        final String action = r.intent.getAction();
+        int event = 0;
+        if (Intent.ACTION_LOCKED_BOOT_COMPLETED.equals(action)) {
+            event = BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED__EVENT__LOCKED_BOOT_COMPLETED;
+        } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+            event = BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED__EVENT__BOOT_COMPLETED;
+        }
+        if (event != 0) {
+            final int dispatchLatency = (int)(r.dispatchTime - r.enqueueTime);
+            final int completeLatency = (int)
+                    (SystemClock.uptimeMillis() - r.enqueueTime);
+            final int dispatchRealLatency = (int)(r.dispatchRealTime - r.enqueueRealTime);
+            final int completeRealLatency = (int)
+                    (SystemClock.elapsedRealtime() - r.enqueueRealTime);
+            int userType = FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__TYPE_UNKNOWN;
+            // This method is called very infrequently, no performance issue we call
+            // LocalServices.getService() here.
+            final UserManagerInternal umInternal = LocalServices.getService(
+                    UserManagerInternal.class);
+            final UserInfo userInfo = umInternal.getUserInfo(r.userId);
+            if (userInfo != null) {
+                userType = UserManager.getUserTypeForStatsd(userInfo.userType);
+            }
+            Slog.i(TAG_BROADCAST,
+                    "BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED action:"
+                            + action
+                            + " dispatchLatency:" + dispatchLatency
+                            + " completeLatency:" + completeLatency
+                            + " dispatchRealLatency:" + dispatchRealLatency
+                            + " completeRealLatency:" + completeRealLatency
+                            + " receiversSize:" + r.receivers.size()
+                            + " userId:" + r.userId
+                            + " userType:" + (userInfo != null? userInfo.userType : null));
+            FrameworkStatsLog.write(
+                    BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED,
+                    event,
+                    dispatchLatency,
+                    completeLatency,
+                    dispatchRealLatency,
+                    completeRealLatency,
+                    r.userId,
+                    userType);
+        }
+    }
+
     private void maybeReportBroadcastDispatchedEventLocked(BroadcastRecord r, int targetUid) {
         // STOPSHIP (217251579): Temporarily use temp-allowlist reason to identify
         // push messages and record response events.
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 8b1e829..2ee32b6 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -84,11 +84,14 @@
     boolean deferred;
     int splitCount;         // refcount for result callback, when split
     int splitToken;         // identifier for cross-BroadcastRecord refcount
+    long enqueueTime;       // uptimeMillis when the broadcast was enqueued
+    long enqueueRealTime;   // elapsedRealtime when the broadcast was enqueued
     long enqueueClockTime;  // the clock time the broadcast was enqueued
     long dispatchTime;      // when dispatch started on this set of receivers
+    long dispatchRealTime;  // elapsedRealtime when the broadcast was dispatched
     long dispatchClockTime; // the clock time the dispatch started
     long receiverTime;      // when current receiver started for timeouts.
-    long finishTime;        // when we finished the broadcast.
+    long finishTime;        // when we finished the current receiver.
     boolean timeoutExempt;  // true if this broadcast is not subject to receiver timeouts
     int resultCode;         // current result code value.
     String resultData;      // current result data value.
@@ -169,7 +172,7 @@
         pw.print(prefix); pw.print("dispatchTime=");
                 TimeUtils.formatDuration(dispatchTime, now, pw);
                 pw.print(" (");
-                TimeUtils.formatDuration(dispatchClockTime-enqueueClockTime, pw);
+                TimeUtils.formatDuration(dispatchTime - enqueueTime, pw);
                 pw.print(" since enq)");
         if (finishTime != 0) {
             pw.print(" finishTime="); TimeUtils.formatDuration(finishTime, now, pw);
@@ -324,8 +327,11 @@
         delivery = from.delivery;
         duration = from.duration;
         resultTo = from.resultTo;
+        enqueueTime = from.enqueueTime;
+        enqueueRealTime = from.enqueueRealTime;
         enqueueClockTime = from.enqueueClockTime;
         dispatchTime = from.dispatchTime;
+        dispatchRealTime = from.dispatchRealTime;
         dispatchClockTime = from.dispatchClockTime;
         receiverTime = from.receiverTime;
         finishTime = from.finishTime;
@@ -378,7 +384,9 @@
                 requiredPermissions, excludedPermissions, appOp, options, splitReceivers, resultTo,
                 resultCode, resultData, resultExtras, ordered, sticky, initialSticky, userId,
                 allowBackgroundActivityStarts, mBackgroundActivityStartsToken, timeoutExempt);
-
+        split.enqueueTime = this.enqueueTime;
+        split.enqueueRealTime = this.enqueueRealTime;
+        split.enqueueClockTime = this.enqueueClockTime;
         split.splitToken = this.splitToken;
         return split;
     }
@@ -448,9 +456,11 @@
             final BroadcastRecord br = new BroadcastRecord(queue, intent, callerApp, callerPackage,
                     callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
                     requiredPermissions, excludedPermissions, appOp, options,
-                    uid2receiverList.valueAt(i), resultTo,
+                    uid2receiverList.valueAt(i), null /* _resultTo */,
                     resultCode, resultData, resultExtras, ordered, sticky, initialSticky, userId,
                     allowBackgroundActivityStarts, mBackgroundActivityStartsToken, timeoutExempt);
+            br.enqueueTime = this.enqueueTime;
+            br.enqueueRealTime = this.enqueueRealTime;
             br.enqueueClockTime = this.enqueueClockTime;
             ret.put(uid2receiverList.keyAt(i), br);
         }
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index b18d390..ff569a6 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -183,6 +183,8 @@
 
     private final ActivityManagerGlobalLock mProcLock;
 
+    private final Object mFreezerLock = new Object();
+
     private final OnPropertiesChangedListener mOnFlagsChangedListener =
             new OnPropertiesChangedListener() {
                 @Override
@@ -949,8 +951,8 @@
         }
     }
 
-    @GuardedBy({"mAm", "mProcLock"})
-    void unfreezeAppLSP(ProcessRecord app) {
+    @GuardedBy({"mAm", "mProcLock", "mFreezerLock"})
+    void unfreezeAppInternalLSP(ProcessRecord app) {
         final int pid = app.getPid();
         final ProcessCachedOptimizerRecord opt = app.mOptRecord;
         if (opt.isPendingFreeze()) {
@@ -1035,6 +1037,42 @@
         }
     }
 
+    @GuardedBy({"mAm", "mProcLock"})
+    void unfreezeAppLSP(ProcessRecord app) {
+        synchronized (mFreezerLock) {
+            unfreezeAppInternalLSP(app);
+        }
+    }
+
+    /**
+     * This quick function works around the race condition between WM/ATMS and AMS, allowing
+     * the former to directly unfreeze a frozen process before the latter runs updateOomAdj.
+     * After the race issue is solved, this workaround can be removed. (b/213288355)
+     * The caller of this function should still trigger updateOomAdj for AMS to unfreeze the app.
+     * @param pid pid of the process to be unfrozen
+     */
+    void unfreezeProcess(int pid) {
+        synchronized (mFreezerLock) {
+            ProcessRecord app = mFrozenProcesses.get(pid);
+            if (app == null) {
+                return;
+            }
+            Slog.d(TAG_AM, "quick sync unfreeze " + pid);
+            try {
+                freezeBinder(pid, false);
+            } catch (RuntimeException e) {
+                Slog.e(TAG_AM, "Unable to quick unfreeze binder for " + pid);
+                return;
+            }
+
+            try {
+                Process.setProcessFrozen(pid, app.uid, false);
+            } catch (Exception e) {
+                Slog.e(TAG_AM, "Unable to quick unfreeze " + pid);
+            }
+        }
+    }
+
     /**
      * To be called when the given app is killed.
      */
@@ -1464,8 +1502,6 @@
                 return;
             }
 
-            Slog.d(TAG_AM, "froze " + pid + " " + name);
-
             EventLog.writeEvent(EventLogTags.AM_FREEZE, pid, name);
 
             // See above for why we're not taking mPhenotypeFlagLock here
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 6a211d3..7ed3dcf 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -750,7 +750,7 @@
         }
         final long now = SystemClock.uptimeMillis();
         final long nowElapsed = SystemClock.elapsedRealtime();
-        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
+        final long oldTime = now - mConstants.mMaxEmptyTimeMillis;
         final boolean fullUpdate = processes == null;
         ActiveUids activeUids = uids;
         ArrayList<ProcessRecord> activeProcesses = fullUpdate ? mProcessList.getLruProcessesLOSP()
@@ -1031,15 +1031,25 @@
         }
     }
 
+    private long mNextNoKillDebugMessageTime;
+
     @GuardedBy({"mService", "mProcLock"})
     private boolean updateAndTrimProcessLSP(final long now, final long nowElapsed,
             final long oldTime, final ActiveUids activeUids) {
         ArrayList<ProcessRecord> lruList = mProcessList.getLruProcessesLOSP();
         final int numLru = lruList.size();
 
-        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
-        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES
-                - emptyProcessLimit;
+        final boolean doKillExcessiveProcesses = shouldKillExcessiveProcesses(now);
+        if (!doKillExcessiveProcesses) {
+            if (mNextNoKillDebugMessageTime < now) {
+                Slog.d(TAG, "Not killing cached processes"); // STOPSHIP Remove it b/222365734
+                mNextNoKillDebugMessageTime = now + 5000; // Every 5 seconds
+            }
+        }
+        final int emptyProcessLimit = doKillExcessiveProcesses
+                ? mConstants.CUR_MAX_EMPTY_PROCESSES : Integer.MAX_VALUE;
+        final int cachedProcessLimit = doKillExcessiveProcesses
+                ? (mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit) : Integer.MAX_VALUE;
         int lastCachedGroup = 0;
         int lastCachedGroupUid = 0;
         int numCached = 0;
@@ -1089,7 +1099,7 @@
                     case PROCESS_STATE_CACHED_EMPTY:
                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
                                 && app.getLastActivityTime() < oldTime) {
-                            app.killLocked("empty for " + ((oldTime + ProcessList.MAX_EMPTY_TIME
+                            app.killLocked("empty for " + ((now
                                     - app.getLastActivityTime()) / 1000) + "s",
                                     "empty for too long",
                                     ApplicationExitInfo.REASON_OTHER,
@@ -1258,6 +1268,25 @@
         }
     }
 
+    /**
+     * Return true if we should kill excessive cached/empty processes.
+     */
+    private boolean shouldKillExcessiveProcesses(long nowUptime) {
+        final long lastUserUnlockingUptime = mService.mUserController.getLastUserUnlockingUptime();
+
+        if (lastUserUnlockingUptime == 0) {
+            // No users have been unlocked.
+            return !mConstants.mNoKillCachedProcessesUntilBootCompleted;
+        }
+        final long noKillCachedProcessesPostBootCompletedDurationMillis =
+                mConstants.mNoKillCachedProcessesPostBootCompletedDurationMillis;
+        if ((lastUserUnlockingUptime + noKillCachedProcessesPostBootCompletedDurationMillis)
+                > nowUptime) {
+            return false;
+        }
+        return true;
+    }
+
     private final ComputeOomAdjWindowCallback mTmpComputeOomAdjWindowCallback =
             new ComputeOomAdjWindowCallback();
 
@@ -2532,7 +2561,7 @@
             if (app.getWaitingToKill() != null && app.mReceivers.numberOfCurReceivers() == 0
                     && state.getSetSchedGroup() == ProcessList.SCHED_GROUP_BACKGROUND) {
                 app.killLocked(app.getWaitingToKill(), ApplicationExitInfo.REASON_USER_REQUESTED,
-                        ApplicationExitInfo.SUBREASON_UNKNOWN, true);
+                        ApplicationExitInfo.SUBREASON_REMOVE_TASK, true);
                 success = false;
             } else {
                 int processGroup;
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index b1c91ba..81a8680 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -368,8 +368,7 @@
 
             // Apply any launch flags from the ActivityOptions. This is to ensure that the caller
             // can specify a consistent launch mode even if the PendingIntent is immutable
-            final ActivityOptions opts = options != null ? ActivityOptions.fromBundle(options)
-                    : null;
+            final ActivityOptions opts = ActivityOptions.fromBundle(options);
             if (opts != null) {
                 finalIntent.addFlags(opts.getPendingIntentLaunchFlags());
             }
diff --git a/services/core/java/com/android/server/am/PendingStartActivityUids.java b/services/core/java/com/android/server/am/PendingStartActivityUids.java
index 802ea00..455c75b 100644
--- a/services/core/java/com/android/server/am/PendingStartActivityUids.java
+++ b/services/core/java/com/android/server/am/PendingStartActivityUids.java
@@ -46,10 +46,13 @@
         mContext = context;
     }
 
-    synchronized void add(int uid, int pid) {
+    /** Returns {@code true} if the uid is put to the pending array. Otherwise it existed. */
+    synchronized boolean add(int uid, int pid) {
         if (mPendingUids.get(uid) == null) {
             mPendingUids.put(uid, new Pair<>(pid, SystemClock.elapsedRealtime()));
+            return true;
         }
+        return false;
     }
 
     synchronized void delete(int uid) {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 636b7f2..253686c 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -293,9 +293,6 @@
     // without empty apps being able to push them out of memory.
     static final int MIN_CACHED_APPS = 2;
 
-    // We allow empty processes to stick around for at most 30 minutes.
-    static final long MAX_EMPTY_TIME = 30 * 60 * 1000;
-
     // Threshold of number of cached+empty where we consider memory critical.
     static final int TRIM_CRITICAL_THRESHOLD = 3;
 
@@ -1721,8 +1718,16 @@
             int runtimeFlags = 0;
 
             boolean debuggableFlag = (app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
-            if (!debuggableFlag && app.isSdkSandbox) {
-                debuggableFlag = isAppForSdkSandboxDebuggable(app);
+            boolean isProfileableByShell = app.info.isProfileableByShell();
+            boolean isProfileable = app.info.isProfileable();
+
+            if (app.isSdkSandbox) {
+                ApplicationInfo clientInfo = app.getClientInfoForSdkSandbox();
+                if (clientInfo != null) {
+                    debuggableFlag |= (clientInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+                    isProfileableByShell |= clientInfo.isProfileableByShell();
+                    isProfileable |= clientInfo.isProfileable();
+                }
             }
 
             if (debuggableFlag) {
@@ -1744,10 +1749,10 @@
             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || mService.mSafeMode) {
                 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
             }
-            if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) {
+            if (isProfileableByShell) {
                 runtimeFlags |= Zygote.PROFILE_FROM_SHELL;
             }
-            if (app.info.isProfileable()) {
+            if (isProfileable) {
                 runtimeFlags |= Zygote.PROFILEABLE;
             }
             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
@@ -1815,7 +1820,7 @@
             }
 
             String invokeWith = null;
-            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+            if (debuggableFlag) {
                 // Debuggable apps may include a wrapper script with their library directory.
                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
@@ -1890,24 +1895,6 @@
         }
     }
 
-    /** Return true if the client app for the SDK sandbox process is debuggable. */
-    private boolean isAppForSdkSandboxDebuggable(ProcessRecord sandboxProcess) {
-        // TODO (b/221004701) use client app process name
-        final int appUid = Process.sdkSandboxToAppUid(sandboxProcess.uid);
-        IPackageManager pm = mService.getPackageManager();
-        try {
-            String[] packages = pm.getPackagesForUid(appUid);
-            for (String aPackage : packages) {
-                ApplicationInfo i = pm.getApplicationInfo(aPackage, 0, sandboxProcess.userId);
-                if ((i.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
-                    return true;
-                }
-            }
-        } catch (RemoteException e) {
-            // shouldn't happen
-        }
-        return false;
-    }
 
     @GuardedBy("mService")
     boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
@@ -2368,7 +2355,7 @@
     ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
             boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
             int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
-            boolean isSdkSandbox, int sdkSandboxUid,
+            boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage,
             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
         long startTime = SystemClock.uptimeMillis();
         ProcessRecord app;
@@ -2463,7 +2450,7 @@
         if (app == null) {
             checkSlow(startTime, "startProcess: creating new process record");
             app = newProcessRecordLocked(info, processName, isolated, isolatedUid, isSdkSandbox,
-                    sdkSandboxUid, hostingRecord);
+                    sdkSandboxUid, sdkSandboxClientAppPackage, hostingRecord);
             if (app == null) {
                 Slog.w(TAG, "Failed making new process record for "
                         + processName + "/" + info.uid + " isolated=" + isolated);
@@ -2959,7 +2946,7 @@
     @GuardedBy("mService")
     ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
             boolean isolated, int isolatedUid, boolean isSdkSandbox, int sdkSandboxUid,
-            HostingRecord hostingRecord) {
+            String sdkSandboxClientAppPackage, HostingRecord hostingRecord) {
         String proc = customProcess != null ? customProcess : info.processName;
         final int userId = UserHandle.getUserId(info.uid);
         int uid = info.uid;
@@ -2995,6 +2982,7 @@
                     FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
         }
         final ProcessRecord r = new ProcessRecord(mService, info, proc, uid,
+                sdkSandboxClientAppPackage,
                 hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName());
         final ProcessStateRecord state = r.mState;
 
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index f7cc3d7..b4ff870 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -27,6 +27,7 @@
 import android.app.ApplicationExitInfo.SubReason;
 import android.app.IApplicationThread;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ProcessInfo;
 import android.content.pm.VersionedPackage;
 import android.content.res.CompatibilityInfo;
@@ -84,6 +85,8 @@
     final int uid;              // uid of process; may be different from 'info' if isolated
     final int userId;           // user of process.
     final String processName;   // name of the process
+    final String sdkSandboxClientAppPackage; // if this is an sdk sandbox process, name of the
+                                             // app package for which it is running
 
     /**
      * Overall state of process's uid.
@@ -493,11 +496,12 @@
 
     ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
             int _uid) {
-        this(_service, _info, _processName, _uid, -1, null);
+        this(_service, _info, _processName, _uid, null, -1, null);
     }
 
     ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
-            int _uid, int _definingUid, String _definingProcessName) {
+            int _uid, String _sdkSandboxClientAppPackage, int _definingUid,
+            String _definingProcessName) {
         mService = _service;
         mProcLock = _service.mProcLock;
         info = _info;
@@ -530,6 +534,7 @@
         uid = _uid;
         userId = UserHandle.getUserId(_uid);
         processName = _processName;
+        sdkSandboxClientAppPackage = _sdkSandboxClientAppPackage;
         mPersistent = false;
         mRemoved = false;
         mProfile = new ProcessProfileRecord(this);
@@ -861,6 +866,29 @@
         return mDebugging;
     }
 
+    @Nullable
+    public ApplicationInfo getClientInfoForSdkSandbox() {
+        if (!isSdkSandbox || sdkSandboxClientAppPackage == null) {
+            throw new IllegalStateException(
+                    "getClientInfoForSdkSandbox called for non-sandbox process"
+            );
+        }
+        PackageManagerInternal pm = mService.getPackageManagerInternal();
+        return pm.getApplicationInfo(
+                sdkSandboxClientAppPackage, /* flags */0, Process.SYSTEM_UID, userId);
+    }
+
+    public boolean isDebuggable() {
+        if ((info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+            return true;
+        }
+        if (isSdkSandbox) {
+            ApplicationInfo clientInfo = getClientInfoForSdkSandbox();
+            return clientInfo != null && (clientInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+        }
+        return false;
+    }
+
     @GuardedBy("mService")
     void setDebugging(boolean debugging) {
         mDebugging = debugging;
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index c53d4d6..795311f 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -96,6 +96,8 @@
     final long createRealTime;  // when this service was created
     final boolean isSdkSandbox; // whether this is a sdk sandbox service
     final int sdkSandboxClientAppUid; // the app uid for which this sdk sandbox service is running
+    final String sdkSandboxClientAppPackage; // the app package for which this sdk sandbox service
+                                             // is running
     final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
             = new ArrayMap<Intent.FilterComparison, IntentBindRecord>();
                             // All active bindings to the service.
@@ -573,13 +575,14 @@
             Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
             Runnable restarter) {
         this(ams, name, instanceName, definingPackageName, definingUid, intent, sInfo, callerIsFg,
-                restarter, null, 0);
+                restarter, null, 0, null);
     }
 
     ServiceRecord(ActivityManagerService ams, ComponentName name,
             ComponentName instanceName, String definingPackageName, int definingUid,
             Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
-            Runnable restarter, String sdkSandboxProcessName, int sdkSandboxClientAppUid) {
+            Runnable restarter, String sdkSandboxProcessName, int sdkSandboxClientAppUid,
+            String sdkSandboxClientAppPackage) {
         this.ams = ams;
         this.name = name;
         this.instanceName = instanceName;
@@ -590,8 +593,9 @@
         serviceInfo = sInfo;
         appInfo = sInfo.applicationInfo;
         packageName = sInfo.applicationInfo.packageName;
-        isSdkSandbox = sdkSandboxProcessName != null;
+        this.isSdkSandbox = sdkSandboxProcessName != null;
         this.sdkSandboxClientAppUid = sdkSandboxClientAppUid;
+        this.sdkSandboxClientAppPackage = sdkSandboxClientAppPackage;
         if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0) {
             processName = sInfo.processName + ":" + instanceName.getClassName();
         } else if (sdkSandboxProcessName != null) {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 1095cf0..8795347 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -399,6 +399,9 @@
     @GuardedBy("mLock")
     private @StopUserOnSwitch int mStopUserOnSwitch = STOP_USER_ON_SWITCH_DEFAULT;
 
+    /** @see #getLastUserUnlockingUptime */
+    private volatile long mLastUserUnlockingUptime = 0;
+
     UserController(ActivityManagerService service) {
         this(new Injector(service));
     }
@@ -661,6 +664,8 @@
 
             uss.mUnlockProgress.setProgress(20);
 
+            mLastUserUnlockingUptime = SystemClock.uptimeMillis();
+
             // Dispatch unlocked to system services; when fully dispatched,
             // that calls through to the next "unlocked" phase
             mHandler.obtainMessage(USER_UNLOCK_MSG, userId, 0, uss).sendToTarget();
@@ -2613,7 +2618,7 @@
         if (getStartedUserState(userId) == null) {
             return false;
         }
-        if (!mInjector.getUserManager().isCredentialSharedWithParent(userId)) {
+        if (!mInjector.getUserManager().isCredentialSharableWithParent(userId)) {
             return false;
         }
         if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
@@ -2753,6 +2758,7 @@
             if (mSwitchingToSystemUserMessage != null) {
                 pw.println("  mSwitchingToSystemUserMessage: " + mSwitchingToSystemUserMessage);
             }
+            pw.println("  mLastUserUnlockingUptime:" + mLastUserUnlockingUptime);
         }
     }
 
@@ -3078,6 +3084,14 @@
     }
 
     /**
+     * Uptime when any user was being unlocked most recently. 0 if no users have been unlocked
+     * yet. To avoid lock contention (since it's used by OomAdjuster), it's volatile internally.
+     */
+    public long getLastUserUnlockingUptime() {
+        return mLastUserUnlockingUptime;
+    }
+
+    /**
      * Helper class to store user journey and session id.
      *
      * <p> User journey tracks a chain of user lifecycle events occurring during different user
diff --git a/services/core/java/com/android/server/ambientcontext/RemoteAmbientContextDetectionService.java b/services/core/java/com/android/server/ambientcontext/RemoteAmbientContextDetectionService.java
index f42080d..8aec752 100644
--- a/services/core/java/com/android/server/ambientcontext/RemoteAmbientContextDetectionService.java
+++ b/services/core/java/com/android/server/ambientcontext/RemoteAmbientContextDetectionService.java
@@ -49,6 +49,12 @@
         connect();
     }
 
+    @Override
+    protected long getAutoDisconnectTimeoutMs() {
+        // Disable automatic unbinding.
+        return -1;
+    }
+
     /**
      * Asks the implementation to start detection.
      *
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 3efd8ad..4fa1ba1 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -359,6 +359,7 @@
     public enum FrameRate {
         FPS_DEFAULT(0),
         FPS_30(30),
+        FPS_40(40),
         FPS_45(45),
         FPS_60(60),
         FPS_90(90),
@@ -378,6 +379,8 @@
         switch (raw) {
             case "30":
                 return FrameRate.FPS_30.fps;
+            case "40":
+                return FrameRate.FPS_40.fps;
             case "45":
                 return FrameRate.FPS_45.fps;
             case "60":
diff --git a/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java b/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java
index 0abab6a..a76eb8f 100644
--- a/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java
+++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
 import android.app.ActivityTaskManager;
 import android.content.Context;
 import android.content.Intent;
@@ -29,6 +30,7 @@
 
 import com.android.internal.infra.ServiceConnector;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.ScreenshotHelper;
 import com.android.server.LocalServices;
 import com.android.server.app.GameServiceConfiguration.GameServiceComponentConfiguration;
 import com.android.server.wm.WindowManagerInternal;
@@ -51,11 +53,13 @@
                 mContext,
                 new GameClassifierImpl(mContext.getPackageManager()),
                 ActivityManager.getService(),
+                LocalServices.getService(ActivityManagerInternal.class),
                 ActivityTaskManager.getService(),
                 (WindowManagerService) ServiceManager.getService(Context.WINDOW_SERVICE),
                 LocalServices.getService(WindowManagerInternal.class),
                 new GameServiceConnector(mContext, configuration),
-                new GameSessionServiceConnector(mContext, configuration));
+                new GameSessionServiceConnector(mContext, configuration),
+                new ScreenshotHelper(mContext));
     }
 
     private static final class GameServiceConnector extends ServiceConnector.Impl<IGameService> {
diff --git a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
index e4edf4e..e920523 100644
--- a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
+++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
@@ -21,15 +21,20 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityManagerInternal;
 import android.app.ActivityTaskManager;
 import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
+import android.app.IProcessObserver;
 import android.app.TaskStackListener;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
+import android.graphics.Insets;
 import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.games.CreateGameSessionRequest;
@@ -42,15 +47,19 @@
 import android.service.games.IGameSession;
 import android.service.games.IGameSessionController;
 import android.service.games.IGameSessionService;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.view.SurfaceControl;
 import android.view.SurfaceControlViewHost.SurfacePackage;
+import android.view.WindowManager;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.infra.AndroidFuture;
 import com.android.internal.infra.ServiceConnector;
 import com.android.internal.infra.ServiceConnector.ServiceLifecycleCallbacks;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.ScreenshotHelper;
 import com.android.server.wm.WindowManagerInternal;
 import com.android.server.wm.WindowManagerInternal.TaskSystemBarsListener;
 import com.android.server.wm.WindowManagerService;
@@ -59,6 +68,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 
 final class GameServiceProviderInstanceImpl implements GameServiceProviderInstance {
     private static final String TAG = "GameServiceProviderInstance";
@@ -136,12 +146,42 @@
                 GameServiceProviderInstanceImpl.this.onTaskFocusChanged(taskId, focused);
             });
         }
+    };
 
-        // TODO(b/204503192): Limit the lifespan of the game session in the Game Service provider
-        // to only when the associated task is running. Right now it is possible for a task to
-        // move into the background and for all associated processes to die and for the Game Session
-        // provider's GameSessionService to continue to be running. Ideally we could unbind the
-        // service when this happens.
+    /**
+     * The TaskStackListener declared above gives us good visibility into game task lifecycle.
+     * However, it is possible for the Android system to kill all the processes associated with a
+     * game task (e.g., when the system is under memory pressure or reaches a background process
+     * limit). When this happens, the game task remains (and no TaskStackListener callbacks are
+     * invoked), but we would nonetheless want to destroy a game session associated with the task
+     * if this were to happen.
+     *
+     * This process observer gives us visibility into process lifecycles and lets us track all the
+     * processes associated with each package so that any game sessions associated with the package
+     * are destroyed if the process count for a given package reaches zero (most packages will
+     * have at most one task). If processes for a given package are started up again, the destroyed
+     * game sessions will be re-created.
+     */
+    private final IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
+        @Override
+        public void onForegroundActivitiesChanged(int pid, int uid, boolean fg) {
+            // This callback is used to track how many processes are running for a given package.
+            // Then, when a process dies, we will know if it was the only process running for that
+            // package and the associated game sessions should be destroyed.
+            mBackgroundExecutor.execute(() -> {
+                GameServiceProviderInstanceImpl.this.onForegroundActivitiesChanged(pid);
+            });
+        }
+
+        @Override
+        public void onProcessDied(int pid, int uid) {
+            mBackgroundExecutor.execute(() -> {
+                GameServiceProviderInstanceImpl.this.onProcessDied(pid);
+            });
+        }
+
+        @Override
+        public void onForegroundServicesChanged(int pid, int uid, int serviceTypes) {}
     };
 
     private final IGameServiceController mGameServiceController =
@@ -185,9 +225,11 @@
     private final Context mContext;
     private final GameClassifier mGameClassifier;
     private final IActivityManager mActivityManager;
+    private final ActivityManagerInternal mActivityManagerInternal;
     private final IActivityTaskManager mActivityTaskManager;
     private final WindowManagerService mWindowManagerService;
     private final WindowManagerInternal mWindowManagerInternal;
+    private final ScreenshotHelper mScreenshotHelper;
     private final ServiceConnector<IGameService> mGameServiceConnector;
     private final ServiceConnector<IGameSessionService> mGameSessionServiceConnector;
 
@@ -195,6 +237,12 @@
     private final ConcurrentHashMap<Integer, GameSessionRecord> mGameSessions =
             new ConcurrentHashMap<>();
     @GuardedBy("mLock")
+    private final ConcurrentHashMap<Integer, String> mPidToPackageMap = new ConcurrentHashMap<>();
+    @GuardedBy("mLock")
+    private final ConcurrentHashMap<String, Integer> mPackageNameToProcessCountMap =
+            new ConcurrentHashMap<>();
+
+    @GuardedBy("mLock")
     private volatile boolean mIsRunning;
 
     GameServiceProviderInstanceImpl(
@@ -203,21 +251,25 @@
             @NonNull Context context,
             @NonNull GameClassifier gameClassifier,
             @NonNull IActivityManager activityManager,
+            @NonNull ActivityManagerInternal activityManagerInternal,
             @NonNull IActivityTaskManager activityTaskManager,
             @NonNull WindowManagerService windowManagerService,
             @NonNull WindowManagerInternal windowManagerInternal,
             @NonNull ServiceConnector<IGameService> gameServiceConnector,
-            @NonNull ServiceConnector<IGameSessionService> gameSessionServiceConnector) {
+            @NonNull ServiceConnector<IGameSessionService> gameSessionServiceConnector,
+            @NonNull ScreenshotHelper screenshotHelper) {
         mUserHandle = userHandle;
         mBackgroundExecutor = backgroundExecutor;
         mContext = context;
         mGameClassifier = gameClassifier;
         mActivityManager = activityManager;
+        mActivityManagerInternal = activityManagerInternal;
         mActivityTaskManager = activityTaskManager;
         mWindowManagerService = windowManagerService;
         mWindowManagerInternal = windowManagerInternal;
         mGameServiceConnector = gameServiceConnector;
         mGameSessionServiceConnector = gameSessionServiceConnector;
+        mScreenshotHelper = screenshotHelper;
     }
 
     @Override
@@ -253,6 +305,12 @@
             Slog.w(TAG, "Failed to register task stack listener", e);
         }
 
+        try {
+            mActivityManager.registerProcessObserver(mProcessObserver);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Failed to register process observer", e);
+        }
+
         mWindowManagerInternal.registerTaskSystemBarsListener(mTaskSystemBarsVisibilityListener);
     }
 
@@ -264,6 +322,12 @@
         mIsRunning = false;
 
         try {
+            mActivityManager.unregisterProcessObserver(mProcessObserver);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Failed to unregister process observer", e);
+        }
+
+        try {
             mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
         } catch (RemoteException e) {
             Slog.w(TAG, "Failed to unregister task stack listener", e);
@@ -586,6 +650,126 @@
         }
     }
 
+    private void onForegroundActivitiesChanged(int pid) {
+        synchronized (mLock) {
+            onForegroundActivitiesChangedLocked(pid);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void onForegroundActivitiesChangedLocked(int pid) {
+        if (mPidToPackageMap.containsKey(pid)) {
+            // We are already tracking this pid, nothing to do.
+            return;
+        }
+
+        final String packageName = mActivityManagerInternal.getPackageNameByPid(pid);
+        if (TextUtils.isEmpty(packageName)) {
+            // Game processes should always have a package name.
+            return;
+        }
+
+        if (!gameSessionExistsForPackageNameLocked(packageName)) {
+            // We only need to track processes for tasks with game session records.
+            return;
+        }
+
+        mPidToPackageMap.put(pid, packageName);
+        final int processCountForPackage = mPackageNameToProcessCountMap.getOrDefault(packageName,
+                0) + 1;
+        mPackageNameToProcessCountMap.put(packageName, processCountForPackage);
+
+        if (DEBUG) {
+            Slog.d(TAG, "onForegroundActivitiesChangedLocked: tracking pid " + pid + ", for "
+                    + packageName + ". Process count for package: " + processCountForPackage);
+        }
+
+        // If there are processes for the package, we may need to re-create game sessions
+        // that are associated with the package
+        if (processCountForPackage > 0) {
+            recreateEndedGameSessionsLocked(packageName);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void recreateEndedGameSessionsLocked(String packageName) {
+        for (GameSessionRecord gameSessionRecord : mGameSessions.values()) {
+            if (gameSessionRecord.isGameSessionEndedForProcessDeath() && packageName.equals(
+                    gameSessionRecord.getComponentName().getPackageName())) {
+                if (DEBUG) {
+                    Slog.d(TAG,
+                            "recreateGameSessionsLocked(): re-creating game session for: "
+                                    + packageName + " with taskId: "
+                                    + gameSessionRecord.getTaskId());
+                }
+
+                final int taskId = gameSessionRecord.getTaskId();
+                mGameSessions.put(taskId, GameSessionRecord.awaitingGameSessionRequest(taskId,
+                        gameSessionRecord.getComponentName()));
+                createGameSessionLocked(gameSessionRecord.getTaskId());
+            }
+        }
+    }
+
+    private void onProcessDied(int pid) {
+        synchronized (mLock) {
+            onProcessDiedLocked(pid);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void onProcessDiedLocked(int pid) {
+        final String packageName = mPidToPackageMap.remove(pid);
+        if (packageName == null) {
+            // We weren't tracking this process.
+            return;
+        }
+
+        final Integer oldProcessCountForPackage = mPackageNameToProcessCountMap.get(packageName);
+        if (oldProcessCountForPackage == null) {
+            // This should never happen; we should have a process count for all tracked packages.
+            Slog.w(TAG, "onProcessDiedLocked(): Missing process count for package");
+            return;
+        }
+
+        final int processCountForPackage = oldProcessCountForPackage - 1;
+        mPackageNameToProcessCountMap.put(packageName, processCountForPackage);
+
+        // If there are no more processes for the game, then we will terminate any game sessions
+        // running for the package.
+        if (processCountForPackage <= 0) {
+            endGameSessionsForPackageLocked(packageName);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void endGameSessionsForPackageLocked(String packageName) {
+        for (GameSessionRecord gameSessionRecord : mGameSessions.values()) {
+            if (gameSessionRecord.getGameSession() != null && packageName.equals(
+                    gameSessionRecord.getComponentName().getPackageName())) {
+                if (DEBUG) {
+                    Slog.d(TAG, "endGameSessionsForPackageLocked(): No more processes for "
+                            + packageName + ", ending game session with taskId: "
+                            + gameSessionRecord.getTaskId());
+                }
+                mGameSessions.put(gameSessionRecord.getTaskId(),
+                        gameSessionRecord.withGameSessionEndedOnProcessDeath());
+                destroyGameSessionFromRecordLocked(gameSessionRecord);
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private boolean gameSessionExistsForPackageNameLocked(String packageName) {
+        for (GameSessionRecord gameSessionRecord : mGameSessions.values()) {
+            if (packageName.equals(gameSessionRecord.getComponentName().getPackageName())) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     @Nullable
     private GameSessionViewHostConfiguration createViewHostConfigurationForTask(int taskId) {
         RunningTaskInfo runningTaskInfo = getRunningTaskInfoForTask(taskId);
@@ -651,7 +835,26 @@
                 Slog.w(TAG, "Could not get bitmap for id: " + taskId);
                 callback.complete(GameScreenshotResult.createInternalErrorResult());
             } else {
-                callback.complete(GameScreenshotResult.createSuccessResult(bitmap));
+                final Bundle bundle = ScreenshotHelper.HardwareBitmapBundler.hardwareBitmapToBundle(
+                        bitmap);
+                final RunningTaskInfo runningTaskInfo = getRunningTaskInfoForTask(taskId);
+                if (runningTaskInfo == null) {
+                    Slog.w(TAG, "Could not get running task info for id: " + taskId);
+                    callback.complete(GameScreenshotResult.createInternalErrorResult());
+                }
+                final Rect crop = runningTaskInfo.configuration.windowConfiguration.getBounds();
+                final Consumer<Uri> completionConsumer = (uri) -> {
+                    if (uri == null) {
+                        callback.complete(GameScreenshotResult.createInternalErrorResult());
+                    } else {
+                        callback.complete(GameScreenshotResult.createSuccessResult());
+                    }
+                };
+                mScreenshotHelper.provideScreenshot(bundle, crop, Insets.NONE, taskId,
+                        mUserHandle.getIdentifier(), gameSessionRecord.getComponentName(),
+                        WindowManager.ScreenshotSource.SCREENSHOT_OTHER,
+                        BackgroundThread.getHandler(),
+                        completionConsumer);
             }
         });
     }
diff --git a/services/core/java/com/android/server/app/GameSessionRecord.java b/services/core/java/com/android/server/app/GameSessionRecord.java
index a241812..74e538e 100644
--- a/services/core/java/com/android/server/app/GameSessionRecord.java
+++ b/services/core/java/com/android/server/app/GameSessionRecord.java
@@ -35,6 +35,10 @@
         // A Game Session is created and attached.
         // GameSessionRecord.getGameSession() != null.
         GAME_SESSION_ATTACHED,
+        // A Game Session did exist for a given game task but was destroyed because the last process
+        // for the game died.
+        // GameSessionRecord.getGameSession() == null.
+        GAME_SESSION_ENDED_PROCESS_DEATH,
     }
 
     private final int mTaskId;
@@ -99,6 +103,20 @@
     }
 
     @NonNull
+    public GameSessionRecord withGameSessionEndedOnProcessDeath() {
+        return new GameSessionRecord(
+                mTaskId,
+                State.GAME_SESSION_ENDED_PROCESS_DEATH,
+                mRootComponentName,
+                /* gameSession=*/ null,
+                /* surfacePackage=*/ null);
+    }
+
+    public boolean isGameSessionEndedForProcessDeath() {
+        return mState == State.GAME_SESSION_ENDED_PROCESS_DEATH;
+    }
+
+    @NonNull
     public int getTaskId() {
         return mTaskId;
     }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 82476d8..d01be58 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -127,6 +127,7 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.HwBinder;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
@@ -10471,6 +10472,25 @@
         return mMediaFocusControl.sendFocusLoss(focusLoser);
     }
 
+    private static final String[] HAL_VERSIONS = new String[] {"7.1", "7.0", "6.0", "4.0", "2.0"};
+
+    /** @see AudioManager#getHalVersion */
+    public @Nullable String getHalVersion() {
+        for (String version : HAL_VERSIONS) {
+            try {
+                HwBinder.getService(
+                        String.format("android.hardware.audio@%s::IDevicesFactory", version),
+                        "default");
+                return version;
+            } catch (NoSuchElementException e) {
+                // Ignore, the specified HAL interface is not found.
+            } catch (RemoteException re) {
+                Log.e(TAG, "Remote exception when getting hardware audio service:", re);
+            }
+        }
+        return null;
+    }
+
     /** see AudioManager.hasRegisteredDynamicPolicy */
     public boolean hasRegisteredDynamicPolicy() {
         synchronized (mAudioPolicies) {
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 193cc5f..5af73c9 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -275,6 +275,7 @@
      */
     synchronized void reset(boolean featureEnabled) {
         Log.i(TAG, "Resetting");
+        releaseSpat();
         mState = STATE_UNINITIALIZED;
         mSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
         mCapableSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
@@ -831,10 +832,10 @@
             try {
                 mSpat.registerHeadTrackingCallback(null);
                 mSpat.release();
-                mSpat = null;
             } catch (RemoteException e) {
                 Log.e(TAG, "Can't set release spatializer cleanly", e);
             }
+            mSpat = null;
         }
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index 7765ab3..9ae6750 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -136,8 +136,8 @@
         try {
             if (mSensorPrivacyManager != null
                     && mSensorPrivacyManager
-                    .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA,
-                    getTargetUserId())) {
+                    .isSensorPrivacyEnabled(SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
+                    SensorPrivacyManager.Sensors.CAMERA)) {
                 onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
                         0 /* vendorCode */);
                 mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
index efedcf8..ded1810 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
@@ -96,7 +96,8 @@
     protected void startHalOperation() {
         if (mSensorPrivacyManager != null
                 && mSensorPrivacyManager
-                .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, getTargetUserId())) {
+                .isSensorPrivacyEnabled(SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
+                    SensorPrivacyManager.Sensors.CAMERA)) {
             onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
             mCallback.onClientFinished(this, false /* success */);
             return;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
index 8d76e9f..1935a5b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
@@ -109,7 +109,8 @@
 
         if (mSensorPrivacyManager != null
                 && mSensorPrivacyManager
-                .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, getTargetUserId())) {
+                .isSensorPrivacyEnabled(SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
+                SensorPrivacyManager.Sensors.CAMERA)) {
             onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
             mCallback.onClientFinished(this, false /* success */);
             return;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 653776b..79e3bf5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -140,12 +140,9 @@
 
     @Override
     public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) {
-        // For UDFPS, notify SysUI that the illumination can be turned off.
-        // See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE
-        if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
-            mSensorOverlays.ifUdfps(controller -> controller.onAcquiredGood(getSensorId()));
-        }
-
+        // For UDFPS, notify SysUI with acquiredInfo, so that the illumination can be turned off
+        // for most ACQUIRED messages. See BiometricFingerprintConstants#FingerprintAcquired
+        mSensorOverlays.ifUdfps(controller -> controller.onAcquired(getSensorId(), acquiredInfo));
         super.onAcquired(acquiredInfo, vendorCode);
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index c92d599..bb1fed0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -114,12 +114,16 @@
 
     @Override
     public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) {
+        boolean acquiredGood =
+                acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD;
         // For UDFPS, notify SysUI that the illumination can be turned off.
         // See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE
-        if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD
-                && mSensorProps.isAnyUdfpsType()) {
-            vibrateSuccess();
-            mSensorOverlays.ifUdfps(controller -> controller.onAcquiredGood(getSensorId()));
+        if (mSensorProps.isAnyUdfpsType()) {
+            if (acquiredGood) {
+                vibrateSuccess();
+            }
+            mSensorOverlays.ifUdfps(
+                    controller -> controller.onAcquired(getSensorId(), acquiredInfo));
         }
 
         mSensorOverlays.ifUdfps(controller -> {
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index ecb43f6..7db99f1 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -184,6 +184,9 @@
     // Must be equal to number of CameraStreamProto in CameraActionEvent
     private static final int MAX_STREAM_STATISTICS = 5;
 
+    private static final float MIN_PREVIEW_FPS = 30.0f;
+    private static final float MAX_PREVIEW_FPS = 60.0f;
+
     private final Context mContext;
     private final ServiceThread mHandlerThread;
     private final Handler mHandler;
@@ -821,6 +824,7 @@
                         Slog.v(TAG, "Stream " + i + ": width " + streamProtos[i].width
                                 + ", height " + streamProtos[i].height
                                 + ", format " + streamProtos[i].format
+                                + ", maxPreviewFps " + streamStats.getMaxPreviewFps()
                                 + ", dataSpace " + streamProtos[i].dataSpace
                                 + ", usage " + streamProtos[i].usage
                                 + ", requestCount " + streamProtos[i].requestCount
@@ -1015,6 +1019,11 @@
         return false;
     }
 
+    private float getMinFps(CameraSessionStats cameraState) {
+        float maxFps = cameraState.getMaxPreviewFps();
+        return Math.max(Math.min(maxFps, MAX_PREVIEW_FPS), MIN_PREVIEW_FPS);
+    }
+
     private void updateActivityCount(CameraSessionStats cameraState) {
         String cameraId = cameraState.getCameraId();
         int newCameraState = cameraState.getNewCameraState();
@@ -1068,7 +1077,9 @@
                     if (!alreadyActivePackage) {
                         WindowManagerInternal wmi =
                                 LocalServices.getService(WindowManagerInternal.class);
-                        wmi.addNonHighRefreshRatePackage(clientName);
+                        float minFps = getMinFps(cameraState);
+                        wmi.addRefreshRateRangeForPackage(clientName,
+                                minFps, MAX_PREVIEW_FPS);
                     }
 
                     // Update activity events
@@ -1107,7 +1118,7 @@
                         if (!stillActivePackage) {
                             WindowManagerInternal wmi =
                                     LocalServices.getService(WindowManagerInternal.class);
-                            wmi.removeNonHighRefreshRatePackage(clientName);
+                            wmi.removeRefreshRateRangeForPackage(clientName);
                         }
                     }
 
diff --git a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
index 62b701a..28c7cad 100644
--- a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
+++ b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
@@ -18,6 +18,7 @@
 
 import android.annotation.Nullable;
 import android.content.ClipData;
+import android.os.SystemProperties;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -39,6 +40,8 @@
     private static final String PIPE_NAME = "pipe:clipboard";
     private static final int HOST_PORT = 5000;
     private final Thread mHostMonitorThread;
+    private static final boolean LOG_CLIBOARD_ACCESS =
+            SystemProperties.getBoolean("ro.boot.qemu.log_clipboard_access", false);
     private FileDescriptor mPipe = null;
 
     private static byte[] createOpenHandshake() {
@@ -51,8 +54,8 @@
         return bits;
     }
 
-    private boolean isPipeOpened() {
-        return mPipe != null;
+    private synchronized FileDescriptor getPipeFD() {
+        return mPipe;
     }
 
     private synchronized boolean openPipe() {
@@ -104,14 +107,16 @@
         return msg;
     }
 
-    private void sendMessage(final byte[] msg) throws ErrnoException, InterruptedIOException {
+    private static void sendMessage(
+            final FileDescriptor fd,
+            final byte[] msg) throws ErrnoException, InterruptedIOException {
         final byte[] lengthBits = new byte[4];
         final ByteBuffer bb = ByteBuffer.wrap(lengthBits);
         bb.order(ByteOrder.LITTLE_ENDIAN);
         bb.putInt(msg.length);
 
-        Os.write(mPipe, lengthBits, 0, lengthBits.length);
-        Os.write(mPipe, msg, 0, msg.length);
+        Os.write(fd, lengthBits, 0, lengthBits.length);
+        Os.write(fd, msg, 0, msg.length);
     }
 
     EmulatorClipboardMonitor(final Consumer<ClipData> setAndroidClipboard) {
@@ -132,6 +137,9 @@
                                                        new String[]{"text/plain"},
                                                        new ClipData.Item(str));
 
+                    if (LOG_CLIBOARD_ACCESS) {
+                        Slog.i(TAG, "Setting the guest clipboard to '" + str + "'");
+                    }
                     setAndroidClipboard.accept(clip);
                 } catch (ErrnoException | InterruptedIOException e) {
                     closePipe();
@@ -156,13 +164,22 @@
     }
 
     private void setHostClipboardImpl(final String value) {
-        try {
-            if (isPipeOpened()) {
-                sendMessage(value.getBytes());
-            }
-        } catch (ErrnoException | InterruptedIOException e) {
-            Slog.e(TAG, "Failed to set host clipboard " + e.getMessage());
-        } catch (IllegalArgumentException e) {
+        final FileDescriptor pipeFD = getPipeFD();
+
+        if (pipeFD != null) {
+            Thread t = new Thread(() -> {
+                if (LOG_CLIBOARD_ACCESS) {
+                    Slog.i(TAG, "Setting the host clipboard to '" + value + "'");
+                }
+
+                try {
+                    sendMessage(pipeFD, value.getBytes());
+                } catch (ErrnoException | InterruptedIOException e) {
+                    Slog.e(TAG, "Failed to set host clipboard " + e.getMessage());
+                } catch (IllegalArgumentException e) {
+                }
+            });
+            t.start();
         }
     }
 }
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 682f0df..c0df095 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1320,6 +1320,7 @@
                 .setLegacyTypeName("VPN")
                 .setBypassableVpn(mConfig.allowBypass && !mLockdown)
                 .setVpnRequiresValidation(mConfig.requiresInternetValidation)
+                .setLocalRoutesExcludedForVpn(mConfig.excludeLocalRoutes)
                 .build();
 
         capsBuilder.setOwnerUid(mOwnerUID);
@@ -3386,6 +3387,7 @@
             mConfig.startTime = SystemClock.elapsedRealtime();
             mConfig.proxyInfo = profile.proxy;
             mConfig.requiresInternetValidation = profile.requiresInternetValidation;
+            mConfig.excludeLocalRoutes = profile.excludeLocalRoutes;
 
             switch (profile.type) {
                 case VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS:
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index c0950bf1..d249d57 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -654,14 +654,17 @@
     protected int handleTextViewOn(HdmiCecMessage message) {
         assertRunOnServiceThread();
 
-        // Note that <Text View On> (and <Image View On>) command won't be handled here in
-        // most cases. A dedicated microcontroller should be in charge while Android system
-        // is in sleep mode, and the command need not be passed up to this service.
-        // The only situation where the command reaches this handler is that sleep mode is
-        // implemented in such a way that Android system is not really put to standby mode
-        // but only the display is set to blank. Then the command leads to the effect of
+        // Note that if the device is in sleep mode, the <Text View On> (and <Image View On>)
+        // command won't be handled here in most cases. A dedicated microcontroller should be in
+        // charge while the Android system is in sleep mode, and the command doesn't need to be
+        // passed up to this service.
+        // The only situations where the command reaches this handler are
+        // 1. if sleep mode is implemented in such a way that Android system is not really put to
+        // standby mode but only the display is set to blank. Then the command leads to
         // turning on the display by the invocation of PowerManager.wakeUp().
-        if (mService.isPowerStandbyOrTransient() && getAutoWakeup()) {
+        // 2. if the device is in dream mode, not sleep mode. Then this command leads to
+        // waking up the device from dream mode by the invocation of PowerManager.wakeUp().
+        if (getAutoWakeup()) {
             mService.wakeUp();
         }
         return Constants.HANDLED;
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 9e00f95..34e3ce1 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -48,6 +48,7 @@
 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.Objects;
 
@@ -168,10 +169,10 @@
     private final SparseBooleanArray mDisabledByUserRestriction;
 
     /**
-     * Cache of services per user id.
+     * Cache of service list per user id.
      */
     @GuardedBy("mLock")
-    private final SparseArray<S> mServicesCache = new SparseArray<>();
+    private final SparseArray<List<S>> mServicesCacheList = new SparseArray<>();
 
     /**
      * Value that determines whether the per-user service should be removed from the cache when its
@@ -252,8 +253,7 @@
         mServiceNameResolver = serviceNameResolver;
         if (mServiceNameResolver != null) {
             mServiceNameResolver.setOnTemporaryServiceNameChangedCallback(
-                    (u, s, t) -> onServiceNameChanged(u, s, t));
-
+                    this::onServiceNameChanged);
         }
         if (disallowProperty == null) {
             mDisabledByUserRestriction = null;
@@ -308,7 +308,7 @@
     @Override // from SystemService
     public void onUserStopped(@NonNull TargetUser user) {
         synchronized (mLock) {
-            removeCachedServiceLocked(user.getUserIdentifier());
+            removeCachedServiceListLocked(user.getUserIdentifier());
         }
     }
 
@@ -386,21 +386,58 @@
         synchronized (mLock) {
             final S oldService = peekServiceForUserLocked(userId);
             if (oldService != null) {
-                oldService.removeSelfFromCacheLocked();
+                oldService.removeSelfFromCache();
             }
             mServiceNameResolver.setTemporaryService(userId, componentName, durationMs);
         }
     }
 
     /**
+     * Temporarily sets the service implementation.
+     *
+     * <p>Typically used by Shell command and/or CTS tests.
+     *
+     * @param componentNames list of the names of the new component
+     * @param durationMs     how long the change will be valid (the service will be automatically
+     *                       reset
+     *                       to the default component after this timeout expires).
+     * @throws SecurityException        if caller is not allowed to manage this service's settings.
+     * @throws IllegalArgumentException if value of {@code durationMs} is higher than
+     *                                  {@link #getMaximumTemporaryServiceDurationMs()}.
+     */
+    public final void setTemporaryServices(@UserIdInt int userId, @NonNull String[] componentNames,
+            int durationMs) {
+        Slog.i(mTag, "setTemporaryService(" + userId + ") to " + Arrays.toString(componentNames)
+                + " for " + durationMs + "ms");
+        if (mServiceNameResolver == null) {
+            return;
+        }
+        enforceCallingPermissionForManagement();
+
+        Objects.requireNonNull(componentNames);
+        final int maxDurationMs = getMaximumTemporaryServiceDurationMs();
+        if (durationMs > maxDurationMs) {
+            throw new IllegalArgumentException(
+                    "Max duration is " + maxDurationMs + " (called with " + durationMs + ")");
+        }
+
+        synchronized (mLock) {
+            final S oldService = peekServiceForUserLocked(userId);
+            if (oldService != null) {
+                oldService.removeSelfFromCache();
+            }
+            mServiceNameResolver.setTemporaryServices(userId, componentNames, durationMs);
+        }
+    }
+
+    /**
      * Sets whether the default service should be used.
      *
      * <p>Typically used during CTS tests to make sure only the default service doesn't interfere
      * with the test results.
      *
-     * @throws SecurityException if caller is not allowed to manage this service's settings.
-     *
      * @return whether the enabled state changed.
+     * @throws SecurityException if caller is not allowed to manage this service's settings.
      */
     public final boolean setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) {
         Slog.i(mTag, "setDefaultServiceEnabled() for userId " + userId + ": " + enabled);
@@ -420,7 +457,7 @@
 
             final S oldService = peekServiceForUserLocked(userId);
             if (oldService != null) {
-                oldService.removeSelfFromCacheLocked();
+                oldService.removeSelfFromCache();
             }
 
             // Must update the service on cache so its initialization code is triggered
@@ -501,6 +538,21 @@
     protected abstract S newServiceLocked(@UserIdInt int resolvedUserId, boolean disabled);
 
     /**
+     * Creates a new service list that will be added to the cache.
+     *
+     * @param resolvedUserId the resolved user id for the service.
+     * @param disabled       whether the service is currently disabled (due to {@link UserManager}
+     *                       restrictions).
+     * @return a new instance.
+     */
+    @Nullable
+    @GuardedBy("mLock")
+    protected List<S> newServiceListLocked(@UserIdInt int resolvedUserId, boolean disabled,
+            String[] serviceNames) {
+        throw new UnsupportedOperationException("newServiceListLocked not implemented. ");
+    }
+
+    /**
      * Register the service for extra Settings changes (i.e., other than
      * {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or
      * {@link #getServiceSettingsProperty()}, which are automatically handled).
@@ -516,7 +568,6 @@
      * <p><b>NOTE: </p>it doesn't need to register for
      * {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or
      * {@link #getServiceSettingsProperty()}.
-     *
      */
     @SuppressWarnings("unused")
     protected void registerForExtraSettingsChanges(@NonNull ContentResolver resolver,
@@ -527,7 +578,7 @@
      * Callback for Settings changes that were registered though
      * {@link #registerForExtraSettingsChanges(ContentResolver, ContentObserver)}.
      *
-     * @param userId user associated with the change
+     * @param userId   user associated with the change
      * @param property Settings property changed.
      */
     protected void onSettingsChanged(@UserIdInt int userId, @NonNull String property) {
@@ -539,18 +590,35 @@
     @GuardedBy("mLock")
     @NonNull
     protected S getServiceForUserLocked(@UserIdInt int userId) {
+        List<S> services = getServiceListForUserLocked(userId);
+        return services == null || services.size() == 0 ? null : services.get(0);
+    }
+
+    /**
+     * Gets the service instance list for a user, creating instances if not present in the cache.
+     */
+    @GuardedBy("mLock")
+    protected List<S> getServiceListForUserLocked(@UserIdInt int userId) {
         final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                 Binder.getCallingUid(), userId, false, false, null, null);
-        S service = mServicesCache.get(resolvedUserId);
-        if (service == null) {
+        List<S> services = mServicesCacheList.get(resolvedUserId);
+        if (services == null || services.size() == 0) {
             final boolean disabled = isDisabledLocked(userId);
-            service = newServiceLocked(resolvedUserId, disabled);
-            if (!disabled) {
-                onServiceEnabledLocked(service, resolvedUserId);
+            if (mServiceNameResolver != null && mServiceNameResolver.isConfiguredInMultipleMode()) {
+                services = newServiceListLocked(resolvedUserId, disabled,
+                        mServiceNameResolver.getServiceNameList(userId));
+            } else {
+                services = new ArrayList<>();
+                services.add(newServiceLocked(resolvedUserId, disabled));
             }
-            mServicesCache.put(userId, service);
+            if (!disabled) {
+                for (int i = 0; i < services.size(); i++) {
+                    onServiceEnabledLocked(services.get(i), resolvedUserId);
+                }
+            }
+            mServicesCacheList.put(userId, services);
         }
-        return service;
+        return services;
     }
 
     /**
@@ -560,9 +628,20 @@
     @GuardedBy("mLock")
     @Nullable
     protected S peekServiceForUserLocked(@UserIdInt int userId) {
+        List<S> serviceList = peekServiceListForUserLocked(userId);
+        return serviceList == null || serviceList.size() == 0 ? null : serviceList.get(0);
+    }
+
+    /**
+     * Gets the <b>existing</b> service instance for a user, returning {@code null} if not already
+     * present in the cache.
+     */
+    @GuardedBy("mLock")
+    @Nullable
+    protected List<S> peekServiceListForUserLocked(@UserIdInt int userId) {
         final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                 Binder.getCallingUid(), userId, false, false, null, null);
-        return mServicesCache.get(resolvedUserId);
+        return mServicesCacheList.get(resolvedUserId);
     }
 
     /**
@@ -570,36 +649,59 @@
      */
     @GuardedBy("mLock")
     protected void updateCachedServiceLocked(@UserIdInt int userId) {
-        updateCachedServiceLocked(userId, isDisabledLocked(userId));
+        updateCachedServiceListLocked(userId, isDisabledLocked(userId));
     }
 
     /**
      * Checks whether the service is disabled (through {@link UserManager} restrictions) for the
      * given user.
      */
+    @GuardedBy("mLock")
     protected boolean isDisabledLocked(@UserIdInt int userId) {
-        return mDisabledByUserRestriction == null ? false : mDisabledByUserRestriction.get(userId);
+        return mDisabledByUserRestriction != null && mDisabledByUserRestriction.get(userId);
     }
 
     /**
      * Updates a cached service for a given user.
      *
-     * @param userId user handle.
+     * @param userId   user handle.
      * @param disabled whether the user is disabled.
      * @return service for the user.
      */
     @GuardedBy("mLock")
     protected S updateCachedServiceLocked(@UserIdInt int userId, boolean disabled) {
         final S service = getServiceForUserLocked(userId);
-        if (service != null) {
-            service.updateLocked(disabled);
-            if (!service.isEnabledLocked()) {
-                removeCachedServiceLocked(userId);
-            } else {
-                onServiceEnabledLocked(service, userId);
+        updateCachedServiceListLocked(userId, disabled);
+        return service;
+    }
+
+    /**
+     * Updates a cached service for a given user.
+     *
+     * @param userId   user handle.
+     * @param disabled whether the user is disabled.
+     * @return service for the user.
+     */
+    @GuardedBy("mLock")
+    protected List<S> updateCachedServiceListLocked(@UserIdInt int userId, boolean disabled) {
+        final List<S> services = getServiceListForUserLocked(userId);
+        if (services == null) {
+            return null;
+        }
+        for (int i = 0; i < services.size(); i++) {
+            S service = services.get(i);
+            if (service != null) {
+                synchronized (service.mLock) {
+                    service.updateLocked(disabled);
+                    if (!service.isEnabledLocked()) {
+                        removeCachedServiceListLocked(userId);
+                    } else {
+                        onServiceEnabledLocked(services.get(i), userId);
+                    }
+                }
             }
         }
-        return service;
+        return services;
     }
 
     /**
@@ -619,28 +721,32 @@
      * <p>By default doesn't do anything, but can be overridden by subclasses.
      */
     @SuppressWarnings("unused")
+    @GuardedBy("mLock")
     protected void onServiceEnabledLocked(@NonNull S service, @UserIdInt int userId) {
     }
 
     /**
-     * Removes a cached service for a given user.
+     * Removes a cached service list for a given user.
      *
      * @return the removed service.
      */
     @GuardedBy("mLock")
     @NonNull
-    protected final S removeCachedServiceLocked(@UserIdInt int userId) {
-        final S service = peekServiceForUserLocked(userId);
-        if (service != null) {
-            mServicesCache.delete(userId);
-            onServiceRemoved(service, userId);
+    protected final List<S> removeCachedServiceListLocked(@UserIdInt int userId) {
+        final List<S> services = peekServiceListForUserLocked(userId);
+        if (services != null) {
+            mServicesCacheList.delete(userId);
+            for (int i = 0; i < services.size(); i++) {
+                onServiceRemoved(services.get(i), userId);
+            }
         }
-        return service;
+        return services;
     }
 
     /**
      * Called before the package that provides the service for the given user is being updated.
      */
+    @GuardedBy("mLock")
     protected void onServicePackageUpdatingLocked(@UserIdInt int userId) {
         if (verbose) Slog.v(mTag, "onServicePackageUpdatingLocked(" + userId + ")");
     }
@@ -648,6 +754,7 @@
     /**
      * Called after the package that provides the service for the given user is being updated.
      */
+    @GuardedBy("mLock")
     protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
         if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")");
     }
@@ -655,6 +762,7 @@
     /**
      * Called after the package data that provides the service for the given user is cleared.
      */
+    @GuardedBy("mLock")
     protected void onServicePackageDataClearedLocked(@UserIdInt int userId) {
         if (verbose) Slog.v(mTag, "onServicePackageDataCleared(" + userId + ")");
     }
@@ -662,6 +770,7 @@
     /**
      * Called after the package that provides the service for the given user is restarted.
      */
+    @GuardedBy("mLock")
     protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
         if (verbose) Slog.v(mTag, "onServicePackageRestarted(" + userId + ")");
     }
@@ -679,14 +788,31 @@
      * <p>By default, it calls {@link #updateCachedServiceLocked(int)}; subclasses must either call
      * that same method, or {@code super.onServiceNameChanged()}.
      *
-     * @param userId user handle.
+     * @param userId      user handle.
      * @param serviceName the new service name.
      * @param isTemporary whether the new service is temporary.
      */
     protected void onServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName,
             boolean isTemporary) {
         synchronized (mLock) {
-            updateCachedServiceLocked(userId);
+            updateCachedServiceListLocked(userId, isDisabledLocked(userId));
+        }
+    }
+
+    /**
+     * Called when the service name list has changed (typically when using temporary services).
+     *
+     * <p>By default, it calls {@link #updateCachedServiceLocked(int)}; subclasses must either call
+     * that same method, or {@code super.onServiceNameChanged()}.
+     *
+     * @param userId       user handle.
+     * @param serviceNames the new service name list.
+     * @param isTemporary  whether the new service is temporary.
+     */
+    protected void onServiceNameListChanged(@UserIdInt int userId, @Nullable String[] serviceNames,
+            boolean isTemporary) {
+        synchronized (mLock) {
+            updateCachedServiceListLocked(userId, isDisabledLocked(userId));
         }
     }
 
@@ -695,9 +821,12 @@
      */
     @GuardedBy("mLock")
     protected void visitServicesLocked(@NonNull Visitor<S> visitor) {
-        final int size = mServicesCache.size();
+        final int size = mServicesCacheList.size();
         for (int i = 0; i < size; i++) {
-            visitor.visit(mServicesCache.valueAt(i));
+            List<S> services = mServicesCacheList.valueAt(i);
+            for (int j = 0; j < services.size(); j++) {
+                visitor.visit(services.get(j));
+            }
         }
     }
 
@@ -706,7 +835,7 @@
      */
     @GuardedBy("mLock")
     protected void clearCacheLocked() {
-        mServicesCache.clear();
+        mServicesCacheList.clear();
     }
 
     /**
@@ -757,6 +886,7 @@
     }
 
     // TODO(b/117779333): support proto
+    @GuardedBy("mLock")
     protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
         boolean realDebug = debug;
         boolean realVerbose = verbose;
@@ -765,40 +895,64 @@
         try {
             // Temporarily turn on full logging;
             debug = verbose = true;
-            final int size = mServicesCache.size();
-            pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
-            pw.print(" Verbose: "); pw.println(realVerbose);
-            pw.print("Package policy flags: "); pw.println(mServicePackagePolicyFlags);
+            final int size = mServicesCacheList.size();
+            pw.print(prefix);
+            pw.print("Debug: ");
+            pw.print(realDebug);
+            pw.print(" Verbose: ");
+            pw.println(realVerbose);
+            pw.print("Package policy flags: ");
+            pw.println(mServicePackagePolicyFlags);
             if (mUpdatingPackageNames != null) {
-                pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
+                pw.print("Packages being updated: ");
+                pw.println(mUpdatingPackageNames);
             }
             dumpSupportedUsers(pw, prefix);
             if (mServiceNameResolver != null) {
-                pw.print(prefix); pw.print("Name resolver: ");
-                mServiceNameResolver.dumpShort(pw); pw.println();
+                pw.print(prefix);
+                pw.print("Name resolver: ");
+                mServiceNameResolver.dumpShort(pw);
+                pw.println();
                 final List<UserInfo> users = getSupportedUsers();
                 for (int i = 0; i < users.size(); i++) {
                     final int userId = users.get(i).id;
-                    pw.print(prefix2); pw.print(userId); pw.print(": ");
-                    mServiceNameResolver.dumpShort(pw, userId); pw.println();
+                    pw.print(prefix2);
+                    pw.print(userId);
+                    pw.print(": ");
+                    mServiceNameResolver.dumpShort(pw, userId);
+                    pw.println();
                 }
             }
-            pw.print(prefix); pw.print("Users disabled by restriction: ");
+            pw.print(prefix);
+            pw.print("Users disabled by restriction: ");
             pw.println(mDisabledByUserRestriction);
-            pw.print(prefix); pw.print("Allow instant service: "); pw.println(mAllowInstantService);
+            pw.print(prefix);
+            pw.print("Allow instant service: ");
+            pw.println(mAllowInstantService);
             final String settingsProperty = getServiceSettingsProperty();
             if (settingsProperty != null) {
-                pw.print(prefix); pw.print("Settings property: "); pw.println(settingsProperty);
+                pw.print(prefix);
+                pw.print("Settings property: ");
+                pw.println(settingsProperty);
             }
-            pw.print(prefix); pw.print("Cached services: ");
+            pw.print(prefix);
+            pw.print("Cached services: ");
             if (size == 0) {
                 pw.println("none");
             } else {
                 pw.println(size);
                 for (int i = 0; i < size; i++) {
-                    pw.print(prefix); pw.print("Service at "); pw.print(i); pw.println(": ");
-                    final S service = mServicesCache.valueAt(i);
-                    service.dumpLocked(prefix2, pw);
+                    pw.print(prefix);
+                    pw.print("Service at ");
+                    pw.print(i);
+                    pw.println(": ");
+                    final List<S> services = mServicesCacheList.valueAt(i);
+                    for (int j = 0; j < services.size(); j++) {
+                        S service = services.get(i);
+                        synchronized (service.mLock) {
+                            service.dumpLocked(prefix2, pw);
+                        }
+                    }
                     pw.println();
                 }
             }
@@ -820,7 +974,7 @@
                 final int userId = getChangingUserId();
                 synchronized (mLock) {
                     if (mUpdatingPackageNames == null) {
-                        mUpdatingPackageNames = new SparseArray<String>(mServicesCache.size());
+                        mUpdatingPackageNames = new SparseArray<String>(mServicesCacheList.size());
                     }
                     mUpdatingPackageNames.put(userId, packageName);
                     onServicePackageUpdatingLocked(userId);
@@ -835,7 +989,7 @@
                                     + " because package " + activePackageName
                                     + " is being updated");
                         }
-                        removeCachedServiceLocked(userId);
+                        removeCachedServiceListLocked(userId);
 
                         if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER)
                                 != 0) {
@@ -901,7 +1055,7 @@
                             if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
                                 handleActiveServiceRestartedLocked(activePackageName, userId);
                             } else {
-                                removeCachedServiceLocked(userId);
+                                removeCachedServiceListLocked(userId);
                             }
                         } else {
                             handlePackageUpdateLocked(pkg);
@@ -930,7 +1084,7 @@
 
             private void handleActiveServiceRemoved(@UserIdInt int userId) {
                 synchronized (mLock) {
-                    removeCachedServiceLocked(userId);
+                    removeCachedServiceListLocked(userId);
                 }
                 final String serviceSettingsProperty = getServiceSettingsProperty();
                 if (serviceSettingsProperty != null) {
@@ -939,6 +1093,7 @@
                 }
             }
 
+            @GuardedBy("mLock")
             private void handleActiveServiceRestartedLocked(String activePackageName,
                     @UserIdInt int userId) {
                 if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) {
@@ -952,7 +1107,7 @@
                                 + " because package " + activePackageName
                                 + " is being restarted");
                     }
-                    removeCachedServiceLocked(userId);
+                    removeCachedServiceListLocked(userId);
 
                     if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) {
                         if (debug) {
@@ -966,14 +1121,27 @@
 
             @Override
             public void onPackageModified(String packageName) {
-                if (verbose) Slog.v(mTag, "onPackageModified(): " + packageName);
+                synchronized (mLock) {
+                    if (verbose) Slog.v(mTag, "onPackageModified(): " + packageName);
 
-                if (mServiceNameResolver == null) {
-                    return;
+                    if (mServiceNameResolver == null) {
+                        return;
+                    }
+
+                    final int userId = getChangingUserId();
+                    final String[] serviceNames = mServiceNameResolver.getDefaultServiceNameList(
+                            userId);
+                    if (serviceNames != null) {
+                        for (int i = 0; i < serviceNames.length; i++) {
+                            peekAndUpdateCachedServiceLocked(packageName, userId, serviceNames[i]);
+                        }
+                    }
                 }
+            }
 
-                final int userId = getChangingUserId();
-                final String serviceName = mServiceNameResolver.getDefaultServiceName(userId);
+            @GuardedBy("mLock")
+            private void peekAndUpdateCachedServiceLocked(String packageName, int userId,
+                    String serviceName) {
                 if (serviceName == null) {
                     return;
                 }
@@ -997,6 +1165,7 @@
                 }
             }
 
+            @GuardedBy("mLock")
             private String getActiveServicePackageNameLocked() {
                 final int userId = getChangingUserId();
                 final S service = peekServiceForUserLocked(userId);
@@ -1017,7 +1186,7 @@
         };
 
         // package changes
-        monitor.register(getContext(), null,  UserHandle.ALL, true);
+        monitor.register(getContext(), null, UserHandle.ALL, true);
     }
 
     /**
diff --git a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
index 757a5cc..b8f1db4 100644
--- a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
@@ -43,14 +43,13 @@
  *
  * @param <M> "main" service class.
  * @param <S> "real" service class.
- *
  * @hide
  */
 public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSystemService<S, M>,
         M extends AbstractMasterSystemService<M, S>> {
 
-    protected final @UserIdInt int mUserId;
-    protected final Object mLock;
+    @UserIdInt protected final int mUserId;
+    public final Object mLock;
     protected final String mTag = getClass().getSimpleName();
 
     protected final M mMaster;
@@ -91,14 +90,14 @@
      * <p><b>MUST</b> be overridden by subclasses that bind to an
      * {@link com.android.internal.infra.AbstractRemoteService}.
      *
-     * @throws NameNotFoundException if the service does not exist.
-     * @throws SecurityException if the service does not have the proper permissions to be bound to.
-     * @throws UnsupportedOperationException if subclass binds to a remote service but does not
-     * overrides it.
-     *
      * @return new {@link ServiceInfo},
+     * @throws NameNotFoundException         if the service does not exist.
+     * @throws SecurityException             if the service does not have the proper permissions to
+     *                                       be bound to.
+     * @throws UnsupportedOperationException if subclass binds to a remote service but does not
+     *                                       overrides it.
      */
-    protected @NonNull ServiceInfo newServiceInfoLocked(
+    @NonNull protected ServiceInfo newServiceInfoLocked(
             @SuppressWarnings("unused") @NonNull ComponentName serviceComponent)
             throws NameNotFoundException {
         throw new UnsupportedOperationException("not overridden");
@@ -137,7 +136,6 @@
      * previous state.
      *
      * @param disabled whether the service is disabled (due to {@link UserManager} restrictions).
-     *
      * @return whether the disabled state changed.
      */
     @GuardedBy("mLock")
@@ -154,18 +152,49 @@
         updateIsSetupComplete(mUserId);
         mDisabled = disabled;
 
-        updateServiceInfoLocked();
+        if (mMaster.mServiceNameResolver != null
+                && mMaster.mServiceNameResolver.isConfiguredInMultipleMode()) {
+            updateServiceInfoListLocked();
+        } else {
+            updateServiceInfoLocked();
+        }
         return wasEnabled != isEnabledLocked();
     }
 
     /**
      * Updates the internal reference to the service info, and returns the service's component.
      */
+    @GuardedBy("mLock")
     protected final ComponentName updateServiceInfoLocked() {
-        ComponentName serviceComponent = null;
-        if (mMaster.mServiceNameResolver != null) {
-            ServiceInfo serviceInfo = null;
+        ComponentName[] componentNames = updateServiceInfoListLocked();
+        return componentNames == null || componentNames.length == 0 ? null : componentNames[0];
+    }
+
+    /**
+     * Updates the internal reference to the service info, and returns the service's component.
+     */
+    @GuardedBy("mLock")
+    protected final ComponentName[] updateServiceInfoListLocked() {
+        if (mMaster.mServiceNameResolver == null) {
+            return null;
+        }
+        if (!mMaster.mServiceNameResolver.isConfiguredInMultipleMode()) {
             final String componentName = getComponentNameLocked();
+            return new ComponentName[] { getServiceComponent(componentName) };
+        }
+        final String[] componentNames = mMaster.mServiceNameResolver.getServiceNameList(
+                mUserId);
+        ComponentName[] serviceComponents = new ComponentName[componentNames.length];
+        for (int i = 0; i < componentNames.length; i++) {
+            serviceComponents[i] = getServiceComponent(componentNames[i]);
+        }
+        return serviceComponents;
+    }
+
+    private ComponentName getServiceComponent(String componentName) {
+        synchronized (mLock) {
+            ServiceInfo serviceInfo = null;
+            ComponentName serviceComponent = null;
             if (!TextUtils.isEmpty(componentName)) {
                 try {
                     serviceComponent = ComponentName.unflattenFromString(componentName);
@@ -196,14 +225,14 @@
                 Slog.e(mTag, "Bad ServiceInfo for '" + componentName + "': " + e);
                 mServiceInfo = null;
             }
+            return serviceComponent;
         }
-        return serviceComponent;
     }
 
     /**
      * Gets the user associated with this service.
      */
-    public final @UserIdInt int getUserId() {
+    @UserIdInt public final int getUserId() {
         return mUserId;
     }
 
@@ -229,15 +258,34 @@
 
     /**
      * Gets the current name of the service, which is either the default service or the
-     *  {@link AbstractMasterSystemService#setTemporaryService(int, String, int) temporary one}.
+     * {@link AbstractMasterSystemService#setTemporaryService(int, String, int) temporary one}.
      */
-    protected final @Nullable String getComponentNameLocked() {
+    @Nullable
+    @GuardedBy("mLock")
+    protected final String getComponentNameLocked() {
         return mMaster.mServiceNameResolver.getServiceName(mUserId);
     }
 
     /**
+     * Gets the current name of the service, which is either the default service or the
+     * {@link AbstractMasterSystemService#setTemporaryService(int, String, int) temporary one}.
+     */
+    @Nullable
+    @GuardedBy("mLock")
+    protected final String getComponentNameForMultipleLocked(String serviceName) {
+        String[] services = mMaster.mServiceNameResolver.getServiceNameList(mUserId);
+        for (int i = 0; i < services.length; i++) {
+            if (serviceName.equals(services[i])) {
+                return services[i];
+            }
+        }
+        return null;
+    }
+
+    /**
      * Checks whether the current service for the user was temporarily set.
      */
+    @GuardedBy("mLock")
     public final boolean isTemporaryServiceSetLocked() {
         return mMaster.mServiceNameResolver.isTemporary(mUserId);
     }
@@ -245,6 +293,7 @@
     /**
      * Resets the temporary service implementation to the default component.
      */
+    @GuardedBy("mLock")
     protected final void resetTemporaryServiceLocked() {
         mMaster.mServiceNameResolver.resetTemporaryService(mUserId);
     }
@@ -268,6 +317,7 @@
             return mServiceInfo == null ? null : mServiceInfo.getComponentName();
         }
     }
+
     /**
      * Gets the name of the of the app this service binds to, or {@code null} if the service is
      * disabled.
@@ -303,8 +353,10 @@
     /**
      * Removes the service from the main service's cache.
      */
-    protected final void removeSelfFromCacheLocked() {
-        mMaster.removeCachedServiceLocked(mUserId);
+    protected final void removeSelfFromCache() {
+        synchronized (mMaster.mLock) {
+            mMaster.removeCachedServiceListLocked(mUserId);
+        }
     }
 
     /**
@@ -327,6 +379,7 @@
      * Gets the target SDK level of the service this service binds to,
      * or {@code 0} if the service is disabled.
      */
+    @GuardedBy("mLock")
     public final int getTargedSdkLocked() {
         return mServiceInfo == null ? 0 : mServiceInfo.applicationInfo.targetSdkVersion;
     }
@@ -334,6 +387,7 @@
     /**
      * Gets whether the device already finished setup.
      */
+    @GuardedBy("mLock")
     protected final boolean isSetupCompletedLocked() {
         return mSetupComplete;
     }
@@ -348,19 +402,32 @@
     // TODO(b/117779333): support proto
     @GuardedBy("mLock")
     protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
-        pw.print(prefix); pw.print("User: "); pw.println(mUserId);
+        pw.print(prefix);
+        pw.print("User: ");
+        pw.println(mUserId);
         if (mServiceInfo != null) {
-            pw.print(prefix); pw.print("Service Label: "); pw.println(getServiceLabelLocked());
-            pw.print(prefix); pw.print("Target SDK: "); pw.println(getTargedSdkLocked());
+            pw.print(prefix);
+            pw.print("Service Label: ");
+            pw.println(getServiceLabelLocked());
+            pw.print(prefix);
+            pw.print("Target SDK: ");
+            pw.println(getTargedSdkLocked());
         }
         if (mMaster.mServiceNameResolver != null) {
-            pw.print(prefix); pw.print("Name resolver: ");
-            mMaster.mServiceNameResolver.dumpShort(pw, mUserId); pw.println();
+            pw.print(prefix);
+            pw.print("Name resolver: ");
+            mMaster.mServiceNameResolver.dumpShort(pw, mUserId);
+            pw.println();
         }
-        pw.print(prefix); pw.print("Disabled by UserManager: "); pw.println(mDisabled);
-        pw.print(prefix); pw.print("Setup complete: "); pw.println(mSetupComplete);
+        pw.print(prefix);
+        pw.print("Disabled by UserManager: ");
+        pw.println(mDisabled);
+        pw.print(prefix);
+        pw.print("Setup complete: ");
+        pw.println(mSetupComplete);
         if (mServiceInfo != null) {
-            pw.print(prefix); pw.print("Service UID: ");
+            pw.print(prefix);
+            pw.print("Service UID: ");
             pw.println(mServiceInfo.applicationInfo.uid);
         }
         pw.println();
diff --git a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
index 35d5956..db2cb52 100644
--- a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
+++ b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.infra;
 
+import android.annotation.ArrayRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringRes;
@@ -33,6 +34,7 @@
 import com.android.internal.annotations.GuardedBy;
 
 import java.io.PrintWriter;
+import java.util.Arrays;
 
 /**
  * Gets the service name using a framework resources, temporarily changing the service if necessary
@@ -47,20 +49,20 @@
     /** Handler message to {@link #resetTemporaryService(int)} */
     private static final int MSG_RESET_TEMPORARY_SERVICE = 0;
 
-    private final @NonNull Context mContext;
-    private final @NonNull Object mLock = new Object();
-    private final @StringRes int mResourceId;
-    private @Nullable NameResolverListener mOnSetCallback;
-
+    @NonNull private final Context mContext;
+    @NonNull private final Object mLock = new Object();
+    @StringRes private final int mStringResourceId;
+    @ArrayRes private final int mArrayResourceId;
+    private final boolean mIsMultiple;
     /**
-     * Map of temporary service name set by {@link #setTemporaryService(int, String, int)},
+     * Map of temporary service name list set by {@link #setTemporaryServices(int, String[], int)},
      * keyed by {@code userId}.
      *
-     * <p>Typically used by Shell command and/or CTS tests.
+     * <p>Typically used by Shell command and/or CTS tests to configure temporary services if
+     * mIsMultiple is true.
      */
     @GuardedBy("mLock")
-    private final SparseArray<String> mTemporaryServiceNames = new SparseArray<>();
-
+    private final SparseArray<String[]> mTemporaryServiceNamesList = new SparseArray<>();
     /**
      * Map of default services that have been disabled by
      * {@link #setDefaultServiceEnabled(int, boolean)},keyed by {@code userId}.
@@ -69,7 +71,7 @@
      */
     @GuardedBy("mLock")
     private final SparseBooleanArray mDefaultServicesDisabled = new SparseBooleanArray();
-
+    @Nullable private NameResolverListener mOnSetCallback;
     /**
      * When the temporary service will expire (and reset back to the default).
      */
@@ -85,7 +87,22 @@
     public FrameworkResourcesServiceNameResolver(@NonNull Context context,
             @StringRes int resourceId) {
         mContext = context;
-        mResourceId = resourceId;
+        mStringResourceId = resourceId;
+        mArrayResourceId = -1;
+        mIsMultiple = false;
+    }
+
+    public FrameworkResourcesServiceNameResolver(@NonNull Context context,
+            @ArrayRes int resourceId, boolean isMultiple) {
+        if (!isMultiple) {
+            throw new UnsupportedOperationException("Please use "
+                    + "FrameworkResourcesServiceNameResolver(context, @StringRes int) constructor "
+                    + "if single service mode is requested.");
+        }
+        mContext = context;
+        mStringResourceId = -1;
+        mArrayResourceId = resourceId;
+        mIsMultiple = true;
     }
 
     @Override
@@ -96,22 +113,31 @@
     }
 
     @Override
-    public String getDefaultServiceName(@UserIdInt int userId) {
-        synchronized (mLock) {
-            final String name = mContext.getString(mResourceId);
-            return TextUtils.isEmpty(name) ? null : name;
-        }
+    public String getServiceName(@UserIdInt int userId) {
+        String[] serviceNames = getServiceNameList(userId);
+        return (serviceNames == null || serviceNames.length == 0) ? null : serviceNames[0];
     }
 
     @Override
-    public String getServiceName(@UserIdInt int userId) {
+    public String getDefaultServiceName(@UserIdInt int userId) {
+        String[] serviceNames = getDefaultServiceNameList(userId);
+        return (serviceNames == null || serviceNames.length == 0) ? null : serviceNames[0];
+    }
+
+    /**
+     * Gets the default list of the service names for the given user.
+     *
+     * <p>Typically implemented by services which want to provide multiple backends.
+     */
+    @Override
+    public String[] getServiceNameList(int userId) {
         synchronized (mLock) {
-            final String temporaryName = mTemporaryServiceNames.get(userId);
-            if (temporaryName != null) {
+            String[] temporaryNames = mTemporaryServiceNamesList.get(userId);
+            if (temporaryNames != null) {
                 // Always log it, as it should only be used on CTS or during development
-                Slog.w(TAG, "getServiceName(): using temporary name " + temporaryName
-                        + " for user " + userId);
-                return temporaryName;
+                Slog.w(TAG, "getServiceName(): using temporary name "
+                        + Arrays.toString(temporaryNames) + " for user " + userId);
+                return temporaryNames;
             }
             final boolean disabled = mDefaultServicesDisabled.get(userId);
             if (disabled) {
@@ -120,22 +146,50 @@
                         + "user " + userId);
                 return null;
             }
-            return getDefaultServiceName(userId);
+            return getDefaultServiceNameList(userId);
+
         }
     }
 
+    /**
+     * Gets the default list of the service names for the given user.
+     *
+     * <p>Typically implemented by services which want to provide multiple backends.
+     */
+    @Override
+    public String[] getDefaultServiceNameList(int userId) {
+        synchronized (mLock) {
+            if (mIsMultiple) {
+                return mContext.getResources().getStringArray(mArrayResourceId);
+            } else {
+                final String name = mContext.getString(mStringResourceId);
+                return TextUtils.isEmpty(name) ? new String[0] : new String[] { name };
+            }
+        }
+    }
+
+    @Override
+    public boolean isConfiguredInMultipleMode() {
+        return mIsMultiple;
+    }
+
     @Override
     public boolean isTemporary(@UserIdInt int userId) {
         synchronized (mLock) {
-            return mTemporaryServiceNames.get(userId) != null;
+            return mTemporaryServiceNamesList.get(userId) != null;
         }
     }
 
     @Override
     public void setTemporaryService(@UserIdInt int userId, @NonNull String componentName,
             int durationMs) {
+        setTemporaryServices(userId, new String[]{componentName}, durationMs);
+    }
+
+    @Override
+    public void setTemporaryServices(int userId, @NonNull String[] componentNames, int durationMs) {
         synchronized (mLock) {
-            mTemporaryServiceNames.put(userId, componentName);
+            mTemporaryServiceNamesList.put(userId, componentNames);
 
             if (mTemporaryHandler == null) {
                 mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) {
@@ -155,8 +209,10 @@
             }
             mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs;
             mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs);
-            notifyTemporaryServiceNameChangedLocked(userId, componentName,
-                    /* isTemporary= */ true);
+            for (int i = 0; i < componentNames.length; i++) {
+                notifyTemporaryServiceNameChangedLocked(userId, componentNames[i],
+                        /* isTemporary= */ true);
+            }
         }
     }
 
@@ -164,8 +220,8 @@
     public void resetTemporaryService(@UserIdInt int userId) {
         synchronized (mLock) {
             Slog.i(TAG, "resetting temporary service for user " + userId + " from "
-                    + mTemporaryServiceNames.get(userId));
-            mTemporaryServiceNames.remove(userId);
+                    + Arrays.toString(mTemporaryServiceNamesList.get(userId)));
+            mTemporaryServiceNamesList.remove(userId);
             if (mTemporaryHandler != null) {
                 mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE);
                 mTemporaryHandler = null;
@@ -207,16 +263,21 @@
 
     @Override
     public String toString() {
-        return "FrameworkResourcesServiceNamer[temps=" + mTemporaryServiceNames + "]";
+        synchronized (mLock) {
+            return "FrameworkResourcesServiceNamer[temps=" + mTemporaryServiceNamesList + "]";
+        }
     }
 
     // TODO(b/117779333): support proto
     @Override
     public void dumpShort(@NonNull PrintWriter pw) {
         synchronized (mLock) {
-            pw.print("FrameworkResourcesServiceNamer: resId="); pw.print(mResourceId);
-            pw.print(", numberTemps="); pw.print(mTemporaryServiceNames.size());
-            pw.print(", enabledDefaults="); pw.print(mDefaultServicesDisabled.size());
+            pw.print("FrameworkResourcesServiceNamer: resId=");
+            pw.print(mStringResourceId);
+            pw.print(", numberTemps=");
+            pw.print(mTemporaryServiceNamesList.size());
+            pw.print(", enabledDefaults=");
+            pw.print(mDefaultServicesDisabled.size());
         }
     }
 
@@ -224,13 +285,17 @@
     @Override
     public void dumpShort(@NonNull PrintWriter pw, @UserIdInt int userId) {
         synchronized (mLock) {
-            final String temporaryName = mTemporaryServiceNames.get(userId);
-            if (temporaryName != null) {
-                pw.print("tmpName="); pw.print(temporaryName);
+            final String[] temporaryNames = mTemporaryServiceNamesList.get(userId);
+            if (temporaryNames != null) {
+                pw.print("tmpName=");
+                pw.print(Arrays.toString(temporaryNames));
                 final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime();
-                pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.print("), ");
+                pw.print(" (expires in ");
+                TimeUtils.formatDuration(ttl, pw);
+                pw.print("), ");
             }
-            pw.print("defaultName="); pw.print(getDefaultServiceName(userId));
+            pw.print("defaultName=");
+            pw.print(getDefaultServiceName(userId));
             final boolean disabled = mDefaultServicesDisabled.get(userId);
             pw.println(disabled ? " (disabled)" : " (enabled)");
         }
diff --git a/services/core/java/com/android/server/infra/ServiceNameResolver.java b/services/core/java/com/android/server/infra/ServiceNameResolver.java
index e20c459..7d85fdb4 100644
--- a/services/core/java/com/android/server/infra/ServiceNameResolver.java
+++ b/services/core/java/com/android/server/infra/ServiceNameResolver.java
@@ -34,7 +34,7 @@
     /**
      * Listener for name changes.
      */
-    public interface NameResolverListener {
+    interface NameResolverListener {
 
         /**
          * The name change callback.
@@ -64,6 +64,30 @@
     String getDefaultServiceName(@UserIdInt int userId);
 
     /**
+     * Gets the default list of names of the services for the given user.
+     *
+     * <p>Typically implemented by reading a Settings property or framework resource.
+     */
+    @Nullable
+    default String[] getDefaultServiceNameList(@UserIdInt int userId) {
+        if (isConfiguredInMultipleMode()) {
+            throw new UnsupportedOperationException("getting default service list not supported");
+        } else {
+            return new String[] { getDefaultServiceName(userId) };
+        }
+    }
+
+    /**
+     * Returns whether the resolver is configured to connect to multiple backend services.
+     * The default return type is false.
+     *
+     * <p>Typically implemented by reading a Settings property or framework resource.
+     */
+    default boolean isConfiguredInMultipleMode() {
+        return false;
+    }
+
+    /**
      * Gets the current name of the service for the given user
      *
      * @return either the temporary name (set by
@@ -76,6 +100,18 @@
     }
 
     /**
+     * Gets the current name of the service for the given user
+     *
+     * @return either the temporary name (set by
+     * {@link #setTemporaryService(int, String, int)}, or the
+     * {@link #getDefaultServiceName(int) default name}.
+     */
+    @Nullable
+    default String[] getServiceNameList(@UserIdInt int userId) {
+        return getDefaultServiceNameList(userId);
+    }
+
+    /**
      * Checks whether the current service is temporary for the given user.
      */
     default boolean isTemporary(@SuppressWarnings("unused") @UserIdInt int userId) {
@@ -85,11 +121,11 @@
     /**
      * Temporarily sets the service implementation for the given user.
      *
-     * @param userId user handle
+     * @param userId        user handle
      * @param componentName name of the new component
-     * @param durationMs how long the change will be valid (the service will be automatically reset
-     *            to the default component after this timeout expires).
-     *
+     * @param durationMs    how long the change will be valid (the service will be automatically
+     *                      reset
+     *                      to the default component after this timeout expires).
      * @throws UnsupportedOperationException if not implemented.
      */
     default void setTemporaryService(@UserIdInt int userId, @NonNull String componentName,
@@ -98,10 +134,24 @@
     }
 
     /**
+     * Temporarily sets the service implementation for the given user.
+     *
+     * @param userId         user handle
+     * @param componentNames list of the names of the new component
+     * @param durationMs     how long the change will be valid (the service will be automatically
+     *                       reset
+     *                       to the default component after this timeout expires).
+     * @throws UnsupportedOperationException if not implemented.
+     */
+    default void setTemporaryServices(@UserIdInt int userId, @NonNull String[] componentNames,
+            int durationMs) {
+        throw new UnsupportedOperationException("temporary user not supported");
+    }
+
+    /**
      * Resets the temporary service implementation to the default component for the given user.
      *
      * @param userId user handle
-     *
      * @throws UnsupportedOperationException if not implemented.
      */
     default void resetTemporaryService(@UserIdInt int userId) {
@@ -114,11 +164,11 @@
      * <p>Typically used during CTS tests to make sure only the default service doesn't interfere
      * with the test results.
      *
-     * @param userId user handle
+     * @param userId  user handle
      * @param enabled whether the default service should be used when the temporary service is not
-     * set. If the service enabled state is already that value, the command is ignored and this
-     * method return {@code false}.
-     *
+     *                set. If the service enabled state is already that value, the command is
+     *                ignored and this
+     *                method return {@code false}.
      * @return whether the enabled state changed.
      * @throws UnsupportedOperationException if not implemented.
      */
@@ -133,7 +183,6 @@
      * with the test results.
      *
      * @param userId user handle
-     *
      * @throws UnsupportedOperationException if not implemented.
      */
     default boolean isDefaultServiceEnabled(@UserIdInt int userId) {
diff --git a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
index dbd3f35..d238dae 100644
--- a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
+++ b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
@@ -19,6 +19,7 @@
 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
 
 import android.os.IBinder;
+import android.os.InputConfig;
 import android.view.InputApplicationHandle;
 import android.view.InputChannel;
 import android.view.InputMonitor;
@@ -56,18 +57,13 @@
         mWindowHandle.name = name;
         mWindowHandle.token = mClientChannel.getToken();
         mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
-        mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
         mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-        mWindowHandle.visible = true;
-        mWindowHandle.focusable = false;
-        mWindowHandle.hasWallpaper = false;
-        mWindowHandle.paused = false;
         mWindowHandle.ownerPid = pid;
         mWindowHandle.ownerUid = uid;
-        mWindowHandle.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY;
         mWindowHandle.scaleFactor = 1.0f;
-        mWindowHandle.trustedOverlay = true;
         mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
+        mWindowHandle.inputConfig =
+                InputConfig.NOT_FOCUSABLE | InputConfig.SPY | InputConfig.TRUSTED_OVERLAY;
 
         final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         t.setInputWindowInfo(mInputSurface, mWindowHandle);
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
index 3c45408..1a19385 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
@@ -19,6 +19,7 @@
 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
 
 import android.annotation.NonNull;
+import android.os.InputConfig;
 import android.os.Process;
 import android.view.InputApplicationHandle;
 import android.view.InputChannel;
@@ -56,20 +57,17 @@
         mWindowHandle.name = name;
         mWindowHandle.token = mClientChannel.getToken();
         mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
-        mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
         mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-        mWindowHandle.visible = true;
-        mWindowHandle.focusable = false;
-        mWindowHandle.hasWallpaper = false;
-        mWindowHandle.paused = false;
         mWindowHandle.ownerPid = Process.myPid();
         mWindowHandle.ownerUid = Process.myUid();
-        mWindowHandle.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
-                | WindowManager.LayoutParams.INPUT_FEATURE_INTERCEPTS_STYLUS;
         mWindowHandle.scaleFactor = 1.0f;
-        mWindowHandle.trustedOverlay = true;
         mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
+        mWindowHandle.inputConfig =
+                InputConfig.NOT_FOCUSABLE
+                        | InputConfig.NOT_TOUCHABLE
+                        | InputConfig.SPY
+                        | InputConfig.INTERCEPTS_STYLUS
+                        | InputConfig.TRUSTED_OVERLAY;
 
         final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         t.setInputWindowInfo(mInputSurface, mWindowHandle);
@@ -85,7 +83,7 @@
     void startIntercepting(int imePid, int imeUid) {
         mWindowHandle.ownerPid = imePid;
         mWindowHandle.ownerUid = imeUid;
-        mWindowHandle.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY;
+        mWindowHandle.inputConfig &= ~InputConfig.SPY;
 
         new SurfaceControl.Transaction()
                 .setInputWindowInfo(mInputSurface, mWindowHandle)
diff --git a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
index 6cb3b3b..e6fd409 100644
--- a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
+++ b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
@@ -32,6 +32,7 @@
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
 import com.android.internal.view.IInlineSuggestionsRequestCallback;
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethod;
@@ -108,10 +109,10 @@
     @AnyThread
     void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privOps,
             int configChanges, boolean stylusHwSupported,
-            boolean shouldShowImeSwitcherWhenImeIsShown) {
+            @InputMethodNavButtonFlags int navButtonFlags) {
         try {
             mTarget.initializeInternal(token, privOps, configChanges, stylusHwSupported,
-                    shouldShowImeSwitcherWhenImeIsShown);
+                    navButtonFlags);
         } catch (RemoteException e) {
             logRemoteException(e);
         }
@@ -147,20 +148,19 @@
 
     @AnyThread
     void startInput(IBinder startInputToken, IInputContext inputContext, EditorInfo attribute,
-            boolean restarting, boolean shouldShowImeSwitcherWhenImeIsShown) {
+            boolean restarting, @InputMethodNavButtonFlags int navButtonFlags) {
         try {
             mTarget.startInput(startInputToken, inputContext, attribute, restarting,
-                    shouldShowImeSwitcherWhenImeIsShown);
+                    navButtonFlags);
         } catch (RemoteException e) {
             logRemoteException(e);
         }
     }
 
     @AnyThread
-    void onShouldShowImeSwitcherWhenImeIsShownChanged(boolean shouldShowImeSwitcherWhenImeIsShown) {
+    void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
         try {
-            mTarget.onShouldShowImeSwitcherWhenImeIsShownChanged(
-                    shouldShowImeSwitcherWhenImeIsShown);
+            mTarget.onNavButtonFlagsChanged(navButtonFlags);
         } catch (RemoteException e) {
             logRemoteException(e);
         }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 882e2e3..77dcbd3 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -156,6 +156,7 @@
 import com.android.internal.inputmethod.ImeTracing;
 import com.android.internal.inputmethod.InputBindResult;
 import com.android.internal.inputmethod.InputMethodDebug;
+import com.android.internal.inputmethod.InputMethodNavButtonFlags;
 import com.android.internal.inputmethod.SoftInputShowHideReason;
 import com.android.internal.inputmethod.StartInputFlags;
 import com.android.internal.inputmethod.StartInputReason;
@@ -335,6 +336,10 @@
     @GuardedBy("ImfLock.class")
     private final HandwritingModeController mHwController;
 
+    @GuardedBy("ImfLock.class")
+    @Nullable
+    private OverlayableSystemBooleanResourceWrapper mImeDrawsImeNavBarRes;
+
     static class SessionState {
         final ClientState client;
         final IInputMethodInvoker method;
@@ -1723,11 +1728,52 @@
     }
 
     @GuardedBy("ImfLock.class")
+    private void recreateImeDrawsImeNavBarResIfNecessary(@UserIdInt int targetUserId) {
+        // Currently, com.android.internal.R.bool.config_imeDrawsImeNavBar is overlaid only for the
+        // profile parent user.
+        // TODO(b/221443458): See if we can make OverlayManager be aware of profile groups.
+        final int profileParentUserId = mUserManagerInternal.getProfileParentId(targetUserId);
+        if (mImeDrawsImeNavBarRes != null
+                && mImeDrawsImeNavBarRes.getUserId() != profileParentUserId) {
+            mImeDrawsImeNavBarRes.close();
+            mImeDrawsImeNavBarRes = null;
+        }
+        if (mImeDrawsImeNavBarRes == null) {
+            final Context userContext;
+            if (mContext.getUserId() == profileParentUserId) {
+                userContext = mContext;
+            } else {
+                userContext = mContext.createContextAsUser(UserHandle.of(profileParentUserId),
+                        0 /* flags */);
+            }
+            mImeDrawsImeNavBarRes = OverlayableSystemBooleanResourceWrapper.create(userContext,
+                    com.android.internal.R.bool.config_imeDrawsImeNavBar, mHandler, resource -> {
+                        synchronized (ImfLock.class) {
+                            if (resource == mImeDrawsImeNavBarRes) {
+                                sendOnNavButtonFlagsChangedLocked();
+                            }
+                        }
+                    });
+        }
+    }
+
+    @NonNull
+    private static PackageManager getPackageManagerForUser(@NonNull Context context,
+            @UserIdInt int userId) {
+        return context.getUserId() == userId
+                ? context.getPackageManager()
+                : context.createContextAsUser(UserHandle.of(userId), 0 /* flags */)
+                        .getPackageManager();
+    }
+
+    @GuardedBy("ImfLock.class")
     private void switchUserOnHandlerLocked(@UserIdInt int newUserId,
             IInputMethodClient clientToBeReset) {
         if (DEBUG) Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId
                 + " currentUserId=" + mSettings.getCurrentUserId());
 
+        recreateImeDrawsImeNavBarResIfNecessary(newUserId);
+
         // ContentObserver should be registered again when the user is changed
         mSettingsObserver.registerContentObserverLocked(newUserId);
 
@@ -1764,9 +1810,9 @@
         updateFromSettingsLocked(true);
 
         if (initialUserSwitch) {
-            InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager,
-                    mSettings.getEnabledInputMethodListLocked(), newUserId,
-                    mContext.getBasePackageName());
+            InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
+                    getPackageManagerForUser(mContext, newUserId),
+                    mSettings.getEnabledInputMethodListLocked());
         }
 
         if (DEBUG) Slog.d(TAG, "Switching user stage 3/3. newUserId=" + newUserId
@@ -1832,6 +1878,8 @@
                     });
                 }
 
+                recreateImeDrawsImeNavBarResIfNecessary(currentUserId);
+
                 mMyPackageMonitor.register(mContext, null, UserHandle.ALL, true);
                 mSettingsObserver.registerContentObserverLocked(currentUserId);
 
@@ -1853,9 +1901,9 @@
                 final boolean imeSelectedOnBoot = !TextUtils.isEmpty(defaultImiId);
                 buildInputMethodListLocked(!imeSelectedOnBoot /* resetDefaultEnabledIme */);
                 updateFromSettingsLocked(true);
-                InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager,
-                        mSettings.getEnabledInputMethodListLocked(), currentUserId,
-                        mContext.getBasePackageName());
+                InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
+                        getPackageManagerForUser(mContext, currentUserId),
+                        mSettings.getEnabledInputMethodListLocked());
             }
         }
     }
@@ -2412,12 +2460,12 @@
                     true /* direct */);
         }
 
-        final boolean shouldShowImeSwitcherWhenImeIsShown =
-                shouldShowImeSwitcherWhenImeIsShownLocked();
+        @InputMethodNavButtonFlags
+        final int navButtonFlags = getInputMethodNavButtonFlagsLocked();
         final SessionState session = mCurClient.curSession;
         setEnabledSessionLocked(session);
         session.method.startInput(startInputToken, mCurInputContext, mCurAttribute, restarting,
-                shouldShowImeSwitcherWhenImeIsShown);
+                navButtonFlags);
         if (mShowRequested) {
             if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
             showCurrentInputLocked(mCurFocusedWindow, getAppShowFlagsLocked(), null,
@@ -2681,7 +2729,7 @@
                     + mCurTokenDisplayId);
         }
         inputMethod.initializeInternal(token, new InputMethodPrivilegedOperationsImpl(this, token),
-                configChanges, supportStylusHw, shouldShowImeSwitcherWhenImeIsShownLocked());
+                configChanges, supportStylusHw, getInputMethodNavButtonFlagsLocked());
     }
 
     @AnyThread
@@ -2938,9 +2986,15 @@
     }
 
     @GuardedBy("ImfLock.class")
-    boolean shouldShowImeSwitcherWhenImeIsShownLocked() {
-        return shouldShowImeSwitcherLocked(
+    @InputMethodNavButtonFlags
+    private int getInputMethodNavButtonFlagsLocked() {
+        final boolean canImeDrawsImeNavBar =
+                mImeDrawsImeNavBarRes != null && mImeDrawsImeNavBarRes.get();
+        final boolean shouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherLocked(
                 InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE);
+        return (canImeDrawsImeNavBar ? InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR : 0)
+                | (shouldShowImeSwitcherWhenImeIsShown
+                        ? InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN : 0);
     }
 
     @GuardedBy("ImfLock.class")
@@ -3203,7 +3257,7 @@
         // the same enabled IMEs list.
         mSwitchingController.resetCircularListLocked(mContext);
 
-        sendShouldShowImeSwitcherWhenImeIsShownLocked();
+        sendOnNavButtonFlagsChangedLocked();
     }
 
     @GuardedBy("ImfLock.class")
@@ -4680,7 +4734,7 @@
             case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
                 mMenuController.handleHardKeyboardStatusChange(msg.arg1 == 1);
                 synchronized (ImfLock.class) {
-                    sendShouldShowImeSwitcherWhenImeIsShownLocked();
+                    sendOnNavButtonFlagsChangedLocked();
                 }
                 return true;
             case MSG_SYSTEM_UNLOCK_USER: {
@@ -4950,7 +5004,7 @@
         // the same enabled IMEs list.
         mSwitchingController.resetCircularListLocked(mContext);
 
-        sendShouldShowImeSwitcherWhenImeIsShownLocked();
+        sendOnNavButtonFlagsChangedLocked();
 
         // Notify InputMethodListListeners of the new installed InputMethods.
         final List<InputMethodInfo> inputMethodList = new ArrayList<>(mMethodList);
@@ -4959,14 +5013,13 @@
     }
 
     @GuardedBy("ImfLock.class")
-    void sendShouldShowImeSwitcherWhenImeIsShownLocked() {
+    void sendOnNavButtonFlagsChangedLocked() {
         final IInputMethodInvoker curMethod = mBindingController.getCurMethod();
         if (curMethod == null) {
             // No need to send the data if the IME is not yet bound.
             return;
         }
-        curMethod.onShouldShowImeSwitcherWhenImeIsShownChanged(
-                shouldShowImeSwitcherWhenImeIsShownLocked());
+        curMethod.onNavButtonFlagsChanged(getInputMethodNavButtonFlagsLocked());
     }
 
     @GuardedBy("ImfLock.class")
@@ -6078,10 +6131,9 @@
                         setInputMethodEnabledLocked(imi.getId(), true);
                     }
                     updateInputMethodsFromSettingsLocked(true /* enabledMayChange */);
-                    InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager,
-                            mSettings.getEnabledInputMethodListLocked(),
-                            mSettings.getCurrentUserId(),
-                            mContext.getBasePackageName());
+                    InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
+                            getPackageManagerForUser(mContext, mSettings.getCurrentUserId()),
+                            mSettings.getEnabledInputMethodListLocked());
                     nextIme = mSettings.getSelectedInputMethod();
                     nextEnabledImes = mSettings.getEnabledInputMethodListLocked();
                 } else {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
index 98bde11..c255fe1 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
@@ -203,7 +203,7 @@
             attrs.setTitle("Select input method");
             w.setAttributes(attrs);
             mService.updateSystemUiLocked();
-            mService.sendShouldShowImeSwitcherWhenImeIsShownLocked();
+            mService.sendOnNavButtonFlagsChangedLocked();
             mSwitchingDialog.show();
         }
     }
@@ -239,7 +239,7 @@
             mSwitchingDialogTitleView = null;
 
             mService.updateSystemUiLocked();
-            mService.sendShouldShowImeSwitcherWhenImeIsShownLocked();
+            mService.sendOnNavButtonFlagsChangedLocked();
             mDialogBuilder = null;
             mIms = null;
         }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
index e619fff..4633df2 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
@@ -18,17 +18,16 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserHandleAware;
 import android.annotation.UserIdInt;
 import android.app.AppOpsManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.os.Build;
 import android.os.LocaleList;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -663,8 +662,9 @@
         return !subtype.isAuxiliary();
     }
 
-    static void setNonSelectedSystemImesDisabledUntilUsed(IPackageManager packageManager,
-            List<InputMethodInfo> enabledImis, @UserIdInt int userId, String callingPackage) {
+    @UserHandleAware
+    static void setNonSelectedSystemImesDisabledUntilUsed(PackageManager packageManagerForUser,
+            List<InputMethodInfo> enabledImis) {
         if (DEBUG) {
             Slog.d(TAG, "setNonSelectedSystemImesDisabledUntilUsed");
         }
@@ -675,7 +675,8 @@
         }
         // Only the current spell checker should be treated as an enabled one.
         final SpellCheckerInfo currentSpellChecker =
-                TextServicesManagerInternal.get().getCurrentSpellCheckerForUser(userId);
+                TextServicesManagerInternal.get().getCurrentSpellCheckerForUser(
+                        packageManagerForUser.getUserId());
         for (final String packageName : systemImesDisabledUntilUsed) {
             if (DEBUG) {
                 Slog.d(TAG, "check " + packageName);
@@ -702,11 +703,12 @@
             }
             ApplicationInfo ai = null;
             try {
-                ai = packageManager.getApplicationInfo(packageName,
-                        PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, userId);
-            } catch (RemoteException e) {
+                ai = packageManagerForUser.getApplicationInfo(packageName,
+                        PackageManager.ApplicationInfoFlags.of(
+                                PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS));
+            } catch (PackageManager.NameNotFoundException e) {
                 Slog.w(TAG, "getApplicationInfo failed. packageName=" + packageName
-                        + " userId=" + userId, e);
+                        + " userId=" + packageManagerForUser.getUserId(), e);
                 continue;
             }
             if (ai == null) {
@@ -717,18 +719,18 @@
             if (!isSystemPackage) {
                 continue;
             }
-            setDisabledUntilUsed(packageManager, packageName, userId, callingPackage);
+            setDisabledUntilUsed(packageManagerForUser, packageName);
         }
     }
 
-    private static void setDisabledUntilUsed(IPackageManager packageManager, String packageName,
-            int userId, String callingPackage) {
+    private static void setDisabledUntilUsed(PackageManager packageManagerForUser,
+            String packageName) {
         final int state;
         try {
-            state = packageManager.getApplicationEnabledSetting(packageName, userId);
-        } catch (RemoteException e) {
+            state = packageManagerForUser.getApplicationEnabledSetting(packageName);
+        } catch (IllegalArgumentException e) {
             Slog.w(TAG, "getApplicationEnabledSetting failed. packageName=" + packageName
-                    + " userId=" + userId, e);
+                    + " userId=" + packageManagerForUser.getUserId(), e);
             return;
         }
         if (state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
@@ -737,12 +739,12 @@
                 Slog.d(TAG, "Update state(" + packageName + "): DISABLED_UNTIL_USED");
             }
             try {
-                packageManager.setApplicationEnabledSetting(packageName,
+                packageManagerForUser.setApplicationEnabledSetting(packageName,
                         PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
-                        0 /* newState */, userId, callingPackage);
-            } catch (RemoteException e) {
+                        0 /* newState */);
+            } catch (IllegalArgumentException e) {
                 Slog.w(TAG, "setApplicationEnabledSetting failed. packageName=" + packageName
-                        + " userId=" + userId + " callingPackage=" + callingPackage, e);
+                        + " userId=" + packageManagerForUser.getUserId(), e);
                 return;
             }
         } else {
diff --git a/services/core/java/com/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper.java b/services/core/java/com/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper.java
new file mode 100644
index 0000000..33e7a76
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper.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.server.inputmethod;
+
+import static android.content.Intent.ACTION_OVERLAY_CHANGED;
+
+import android.annotation.AnyThread;
+import android.annotation.BoolRes;
+import android.annotation.NonNull;
+import android.annotation.UserHandleAware;
+import android.annotation.UserIdInt;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.PatternMatcher;
+import android.util.Slog;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+
+/**
+ * A wrapper object for any boolean resource defined in {@code "android"} package, in a way that is
+ * aware of per-user Runtime Resource Overlay (RRO).
+ */
+final class OverlayableSystemBooleanResourceWrapper implements AutoCloseable {
+    private static final String TAG = "OverlayableSystemBooleanResourceWrapper";
+
+    private static final String SYSTEM_PACKAGE_NAME = "android";
+
+    @UserIdInt
+    private final int mUserId;
+    @NonNull
+    private final AtomicBoolean mValueRef;
+    @NonNull
+    private final AtomicReference<Runnable> mCleanerRef;
+
+    /**
+     * Creates {@link OverlayableSystemBooleanResourceWrapper} for the given boolean resource ID
+     * with a value change callback for the user associated with the {@link Context}.
+     *
+     * @param userContext The {@link Context} to be used to access the resource. This needs to be
+     *                    associated with the right user because the Runtime Resource Overlay (RRO)
+     *                    is per-user configuration.
+     * @param boolResId The resource ID to be queried.
+     * @param handler {@link Handler} to be used to dispatch {@code callback}.
+     * @param callback The callback to be notified when the specified value might be updated.
+     *                 The callback needs to take care of spurious wakeup. The value returned from
+     *                 {@link #get()} may look to be exactly the same as the previously read value
+     *                 e.g. when the value is changed from {@code false} to {@code true} to
+     *                 {@code false} in a very short period of time, because {@link #get()} always
+     *                 does volatile-read.
+     * @return New {@link OverlayableSystemBooleanResourceWrapper}.
+     */
+    @NonNull
+    @UserHandleAware
+    static OverlayableSystemBooleanResourceWrapper create(@NonNull Context userContext,
+            @BoolRes int boolResId, @NonNull Handler handler,
+            @NonNull Consumer<OverlayableSystemBooleanResourceWrapper> callback) {
+
+        // Note that we cannot fully trust this initial value due to the dead time between obtaining
+        // the value here and setting up a broadcast receiver for change callback below.
+        // We will refresh the value again later after setting up the change callback anyway.
+        final AtomicBoolean valueRef = new AtomicBoolean(evaluate(userContext, boolResId));
+
+        final AtomicReference<Runnable> cleanerRef = new AtomicReference<>();
+
+        final OverlayableSystemBooleanResourceWrapper object =
+                new OverlayableSystemBooleanResourceWrapper(userContext.getUserId(), valueRef,
+                        cleanerRef);
+
+        final IntentFilter intentFilter = new IntentFilter(ACTION_OVERLAY_CHANGED);
+        intentFilter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
+        intentFilter.addDataSchemeSpecificPart(SYSTEM_PACKAGE_NAME, PatternMatcher.PATTERN_LITERAL);
+
+        final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                final boolean newValue = evaluate(userContext, boolResId);
+                if (newValue != valueRef.getAndSet(newValue)) {
+                    callback.accept(object);
+                }
+            }
+        };
+        userContext.registerReceiver(broadcastReceiver, intentFilter,
+                null /* broadcastPermission */, handler,
+                Context.RECEIVER_NOT_EXPORTED);
+        cleanerRef.set(() -> userContext.unregisterReceiver(broadcastReceiver));
+
+        // Make sure that the initial observable value is obtained after the change callback is set.
+        valueRef.set(evaluate(userContext, boolResId));
+        return object;
+    }
+
+    private OverlayableSystemBooleanResourceWrapper(@UserIdInt int userId,
+            @NonNull AtomicBoolean valueRef, @NonNull AtomicReference<Runnable> cleanerRef) {
+        mUserId = userId;
+        mValueRef = valueRef;
+        mCleanerRef = cleanerRef;
+    }
+
+    /**
+     * @return The boolean resource value.
+     */
+    @AnyThread
+    boolean get() {
+        return mValueRef.get();
+    }
+
+    /**
+     * @return The user ID associated with this resource reader.
+     */
+    @AnyThread
+    @UserIdInt
+    int getUserId() {
+        return mUserId;
+    }
+
+    @AnyThread
+    private static boolean evaluate(@NonNull Context context, @BoolRes int boolResId) {
+        try {
+            return context.getPackageManager()
+                    .getResourcesForApplication(SYSTEM_PACKAGE_NAME)
+                    .getBoolean(boolResId);
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.e(TAG, "getResourcesForApplication(\"" + SYSTEM_PACKAGE_NAME + "\") failed", e);
+            return false;
+        }
+    }
+
+    /**
+     * Cleans up the callback.
+     */
+    @AnyThread
+    @Override
+    public void close() {
+        final Runnable cleaner = mCleanerRef.getAndSet(null);
+        if (cleaner != null) {
+            cleaner.run();
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index cd2ba39..8407a11 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -1184,6 +1184,7 @@
                 mAlarmManager.cancel(mBatchingAlarm);
                 mBatchingAlarm = null;
             }
+            mGnssNative.flushBatch();
             mGnssNative.stopBatch();
             mBatchingStarted = false;
         }
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 0f4648a..436cc69 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -252,8 +252,6 @@
 
     private final RebootEscrowManager mRebootEscrowManager;
 
-    private boolean mFirstCallToVold;
-
     // Current password metric for all users on the device. Updated when user unlocks
     // the device or changes password. Removed when user is stopped.
     @GuardedBy("this")
@@ -373,7 +371,7 @@
             LockscreenCredential profileUserPassword) {
         if (DEBUG) Slog.v(TAG, "Check child profile lock for user: " + profileUserId);
         // Only for profiles that shares credential with parent
-        if (!isCredentialSharedWithParent(profileUserId)) {
+        if (!isCredentialSharableWithParent(profileUserId)) {
             return;
         }
         // Do not tie profile when work challenge is enabled
@@ -597,8 +595,6 @@
         mStrongAuth = injector.getStrongAuth();
         mActivityManager = injector.getActivityManager();
 
-        mFirstCallToVold = true;
-
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_ADDED);
         filter.addAction(Intent.ACTION_USER_STARTING);
@@ -789,7 +785,7 @@
     private void ensureProfileKeystoreUnlocked(int userId) {
         final KeyStore ks = KeyStore.getInstance();
         if (ks.state(userId) == KeyStore.State.LOCKED
-                && isCredentialSharedWithParent(userId)
+                && isCredentialSharableWithParent(userId)
                 && hasUnifiedChallenge(userId)) {
             Slog.i(TAG, "Profile got unlocked, will unlock its keystore");
             // If boot took too long and the password in vold got expired, parent keystore will
@@ -810,7 +806,7 @@
                 // Hide notification first, as tie managed profile lock takes time
                 hideEncryptionNotification(new UserHandle(userId));
 
-                if (isCredentialSharedWithParent(userId)) {
+                if (isCredentialSharableWithParent(userId)) {
                     tieProfileLockIfNecessary(userId, LockscreenCredential.createNone());
                 }
 
@@ -1077,7 +1073,7 @@
         final int userCount = users.size();
         for (int i = 0; i < userCount; i++) {
             UserInfo user = users.get(i);
-            if (isCredentialSharedWithParent(user.id)
+            if (isCredentialSharableWithParent(user.id)
                     && !getSeparateProfileChallengeEnabledInternal(user.id)) {
                 success &= SyntheticPasswordCrypto.migrateLockSettingsKey(
                         PROFILE_KEY_NAME_ENCRYPT + user.id);
@@ -1471,7 +1467,7 @@
             Thread.currentThread().interrupt();
         }
 
-        if (isCredentialSharedWithParent(userId)) {
+        if (isCredentialSharableWithParent(userId)) {
             if (!hasUnifiedChallenge(userId)) {
                 mBiometricDeferredQueue.processPendingLockoutResets();
             }
@@ -1480,7 +1476,7 @@
 
         for (UserInfo profile : mUserManager.getProfiles(userId)) {
             if (profile.id == userId) continue;
-            if (!isCredentialSharedWithParent(profile.id)) continue;
+            if (!isCredentialSharableWithParent(profile.id)) continue;
 
             if (hasUnifiedChallenge(profile.id)) {
                 if (mUserManager.isUserRunning(profile.id)) {
@@ -1517,7 +1513,7 @@
     }
 
     private Map<Integer, LockscreenCredential> getDecryptedPasswordsForAllTiedProfiles(int userId) {
-        if (isCredentialSharedWithParent(userId)) {
+        if (isCredentialSharableWithParent(userId)) {
             return null;
         }
         Map<Integer, LockscreenCredential> result = new ArrayMap<>();
@@ -1525,7 +1521,7 @@
         final int size = profiles.size();
         for (int i = 0; i < size; i++) {
             final UserInfo profile = profiles.get(i);
-            if (!isCredentialSharedWithParent(profile.id)) {
+            if (!isCredentialSharableWithParent(profile.id)) {
                 continue;
             }
             final int profileUserId = profile.id;
@@ -1560,7 +1556,7 @@
      */
     private void synchronizeUnifiedWorkChallengeForProfiles(int userId,
             Map<Integer, LockscreenCredential> profilePasswordMap) {
-        if (isCredentialSharedWithParent(userId)) {
+        if (isCredentialSharableWithParent(userId)) {
             return;
         }
         final boolean isSecure = isUserSecure(userId);
@@ -1569,7 +1565,7 @@
         for (int i = 0; i < size; i++) {
             final UserInfo profile = profiles.get(i);
             final int profileUserId = profile.id;
-            if (isCredentialSharedWithParent(profileUserId)) {
+            if (isCredentialSharableWithParent(profileUserId)) {
                 if (getSeparateProfileChallengeEnabledInternal(profileUserId)) {
                     continue;
                 }
@@ -1596,12 +1592,12 @@
     }
 
     private boolean isProfileWithUnifiedLock(int userId) {
-        return isCredentialSharedWithParent(userId)
+        return isCredentialSharableWithParent(userId)
                 && !getSeparateProfileChallengeEnabledInternal(userId);
     }
 
     private boolean isProfileWithSeparatedLock(int userId) {
-        return isCredentialSharedWithParent(userId)
+        return isCredentialSharableWithParent(userId)
                 && getSeparateProfileChallengeEnabledInternal(userId);
     }
 
@@ -1719,7 +1715,7 @@
                 setSeparateProfileChallengeEnabledLocked(userId, true, /* unused */ null);
                 notifyPasswordChanged(credential, userId);
             }
-            if (isCredentialSharedWithParent(userId)) {
+            if (isCredentialSharableWithParent(userId)) {
                 // Make sure the profile doesn't get locked straight after setting work challenge.
                 setDeviceUnlockedForUser(userId);
             }
@@ -1734,7 +1730,7 @@
 
     /**
      * @param savedCredential if the user is a profile with
-     * {@link UserManager#isCredentialSharedWithParent()} with unified challenge and
+     * {@link UserManager#isCredentialSharableWithParent()} with unified challenge and
      *   savedCredential is empty, LSS will try to re-derive the profile password internally.
      *     TODO (b/80170828): Fix this so profile password is always passed in.
      * @param isLockTiedToParent is {@code true} if {@code userId} is a profile and its new
@@ -1800,7 +1796,10 @@
     }
 
     private void onPostPasswordChanged(LockscreenCredential newCredential, int userHandle) {
-        updateEncryptionPasswordIfNeeded(newCredential, userHandle);
+        if (userHandle == UserHandle.USER_SYSTEM && isDeviceEncryptionEnabled() &&
+            shouldEncryptWithCredentials() && newCredential.isNone()) {
+            setCredentialRequiredToDecrypt(false);
+        }
         if (newCredential.isPattern()) {
             setBoolean(LockPatternUtils.PATTERN_EVER_CHOSEN_KEY, true, userHandle);
         }
@@ -1809,26 +1808,6 @@
     }
 
     /**
-     * Update device encryption password if calling user is USER_SYSTEM and device supports
-     * encryption.
-     */
-    private void updateEncryptionPasswordIfNeeded(LockscreenCredential credential, int userHandle) {
-        // Update the device encryption password.
-        if (userHandle != UserHandle.USER_SYSTEM || !isDeviceEncryptionEnabled()) {
-            return;
-        }
-        if (!shouldEncryptWithCredentials()) {
-            updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null);
-            return;
-        }
-        if (credential.isNone()) {
-            // Set the encryption password to default.
-            setCredentialRequiredToDecrypt(false);
-        }
-        updateEncryptionPassword(credential.getStorageCryptType(), credential.getCredential());
-    }
-
-    /**
      * Store the hash of the *current* password in the password history list, if device policy
      * enforces password history requirement.
      */
@@ -1927,8 +1906,8 @@
         }
     }
 
-    protected boolean isCredentialSharedWithParent(int userId) {
-        return getUserManagerFromCache(userId).isCredentialSharedWithParent();
+    protected boolean isCredentialSharableWithParent(int userId) {
+        return getUserManagerFromCache(userId).isCredentialSharableWithParent();
     }
 
     private VerifyCredentialResponse convertResponse(GateKeeperResponse gateKeeperResponse) {
@@ -1942,34 +1921,6 @@
         }
     }
 
-    /** Update the encryption password if it is enabled **/
-    @Override
-    public void updateEncryptionPassword(final int type, final byte[] password) {
-        if (!hasSecureLockScreen() && password != null && password.length != 0) {
-            throw new UnsupportedOperationException(
-                    "This operation requires the lock screen feature.");
-        }
-        if (!isDeviceEncryptionEnabled()) {
-            return;
-        }
-        final IBinder service = ServiceManager.getService("mount");
-        if (service == null) {
-            Slog.e(TAG, "Could not find the mount service to update the encryption password");
-            return;
-        }
-
-        // TODO(b/120484642): This is a location where we still use a String for vold
-        String passwordString = password != null ? new String(password) : null;
-        mHandler.post(() -> {
-            IStorageManager storageManager = mInjector.getStorageManager();
-            try {
-                storageManager.changeEncryptionPassword(type, passwordString);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Error changing encryption password", e);
-            }
-        });
-    }
-
     /** Register the given WeakEscrowTokenRemovedListener. */
     @Override
     public boolean registerWeakEscrowTokenRemovedListener(
@@ -2206,7 +2157,7 @@
         final List<UserInfo> profiles = mUserManager.getProfiles(userId);
         for (UserInfo pi : profiles) {
             // Unlock profile which shares credential with parent with unified lock
-            if (isCredentialSharedWithParent(pi.id)
+            if (isCredentialSharableWithParent(pi.id)
                     && !getSeparateProfileChallengeEnabledInternal(pi.id)
                     && mStorage.hasChildProfileLock(pi.id)) {
                 try {
@@ -2519,77 +2470,6 @@
         });
     }
 
-    private LockscreenCredential createPattern(String patternString) {
-        final byte[] patternBytes = patternString.getBytes();
-        LockscreenCredential pattern = LockscreenCredential.createPattern(
-                LockPatternUtils.byteArrayToPattern(patternBytes));
-        Arrays.fill(patternBytes, (byte) 0);
-        return pattern;
-    }
-
-    @Override
-    public boolean checkVoldPassword(int userId) {
-        if (!mFirstCallToVold) {
-            return false;
-        }
-        mFirstCallToVold = false;
-
-        checkPasswordReadPermission();
-
-        // There's no guarantee that this will safely connect, but if it fails
-        // we will simply show the lock screen when we shouldn't, so relatively
-        // benign. There is an outside chance something nasty would happen if
-        // this service restarted before vold stales out the password in this
-        // case. The nastiness is limited to not showing the lock screen when
-        // we should, within the first minute of decrypting the phone if this
-        // service can't connect to vold, it restarts, and then the new instance
-        // does successfully connect.
-        final IStorageManager service = mInjector.getStorageManager();
-        // TODO(b/120484642): Update vold to return a password as a byte array
-        String password;
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            password = service.getPassword();
-            service.clearPassword();
-        } catch (RemoteException e) {
-            Slog.w(TAG, "vold getPassword() failed", e);
-            return false;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-        if (TextUtils.isEmpty(password)) {
-            return false;
-        }
-
-        try {
-            final LockscreenCredential credential;
-            switch (getCredentialTypeInternal(userId)) {
-                case CREDENTIAL_TYPE_PATTERN:
-                    credential = createPattern(password);
-                    break;
-                case CREDENTIAL_TYPE_PIN:
-                    credential = LockscreenCredential.createPin(password);
-                    break;
-                case CREDENTIAL_TYPE_PASSWORD:
-                    credential = LockscreenCredential.createPassword(password);
-                    break;
-                default:
-                    credential = null;
-                    Slog.e(TAG, "Unknown credential type");
-            }
-
-            if (credential != null
-                    && checkCredential(credential, userId, null /* progressCallback */)
-                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                return true;
-            }
-        } catch (Exception e) {
-            Slog.e(TAG, "checkVoldPassword failed: ", e);
-        }
-
-        return false;
-    }
-
     private void removeUser(int userId, boolean unknownUser) {
         Slog.i(TAG, "RemoveUser: " + userId);
         removeBiometricsForUser(userId);
@@ -2600,7 +2480,7 @@
         mManagedProfilePasswordCache.removePassword(userId);
 
         gateKeeperClearSecureUserId(userId);
-        if (unknownUser || isCredentialSharedWithParent(userId)) {
+        if (unknownUser || isCredentialSharableWithParent(userId)) {
             removeKeystoreProfileKey(userId);
         }
         // Clean up storage last, this is to ensure that cleanupDataForReusedUserIdIfNecessary()
@@ -3320,7 +3200,7 @@
      * Returns a fixed pseudorandom byte string derived from the user's synthetic password.
      * This is used to salt the password history hash to protect the hash against offline
      * bruteforcing, since rederiving this value requires a successful authentication.
-     * If user is a profile with {@link UserManager#isCredentialSharedWithParent()} true and with
+     * If user is a profile with {@link UserManager#isCredentialSharableWithParent()} true and with
      * unified challenge, currentCredential is ignored.
      */
     @Override
diff --git a/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java b/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java
deleted file mode 100644
index 6b442a6..0000000
--- a/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.logcat;
-
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentSender;
-import android.os.Bundle;
-import android.os.ServiceManager;
-import android.os.logcat.ILogcatManagerService;
-import android.util.Slog;
-import android.view.View;
-import android.widget.TextView;
-
-import com.android.internal.R;
-import com.android.internal.app.AlertActivity;
-import com.android.internal.app.AlertController;
-
-
-/**
- * This dialog is shown to the user before an activity in a harmful app is launched.
- *
- * See {@code PackageManager.setLogcatAppInfo} for more info.
- */
-public class LogAccessConfirmationActivity extends AlertActivity implements
-        DialogInterface.OnClickListener {
-    private static final String TAG = LogAccessConfirmationActivity.class.getSimpleName();
-
-    private String mPackageName;
-    private IntentSender mTarget;
-    private final ILogcatManagerService mLogcatManagerService =
-            ILogcatManagerService.Stub.asInterface(ServiceManager.getService("logcat"));
-
-    private int mUid;
-    private int mGid;
-    private int mPid;
-    private int mFd;
-
-    private static final String EXTRA_UID = "uid";
-    private static final String EXTRA_GID = "gid";
-    private static final String EXTRA_PID = "pid";
-    private static final String EXTRA_FD = "fd";
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        final Intent intent = getIntent();
-        mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
-        mUid = intent.getIntExtra("uid", 0);
-        mGid = intent.getIntExtra("gid", 0);
-        mPid = intent.getIntExtra("pid", 0);
-        mFd = intent.getIntExtra("fd", 0);
-
-        final AlertController.AlertParams p = mAlertParams;
-        p.mTitle = getString(R.string.log_access_confirmation_title);
-        p.mView = createView();
-
-        p.mPositiveButtonText = getString(R.string.log_access_confirmation_allow);
-        p.mPositiveButtonListener = this;
-        p.mNegativeButtonText = getString(R.string.log_access_confirmation_deny);
-        p.mNegativeButtonListener = this;
-
-        mAlert.installContent(mAlertParams);
-    }
-
-    private View createView() {
-        final View view = getLayoutInflater().inflate(R.layout.harmful_app_warning_dialog,
-                null /*root*/);
-        ((TextView) view.findViewById(R.id.app_name_text))
-                .setText(mPackageName);
-        ((TextView) view.findViewById(R.id.message))
-                .setText(getIntent().getExtras().getString("body"));
-        return view;
-    }
-
-    @Override
-    public void onClick(DialogInterface dialog, int which) {
-        switch (which) {
-            case DialogInterface.BUTTON_POSITIVE:
-                try {
-                    mLogcatManagerService.approve(mUid, mGid, mPid, mFd);
-                } catch (Throwable t) {
-                    Slog.e(TAG, "Could not start the LogcatManagerService.", t);
-                }
-                finish();
-                break;
-            case DialogInterface.BUTTON_NEGATIVE:
-                try {
-                    mLogcatManagerService.decline(mUid, mGid, mPid, mFd);
-                } catch (Throwable t) {
-                    Slog.e(TAG, "Could not start the LogcatManagerService.", t);
-                }
-                finish();
-                break;
-        }
-    }
-
-    /**
-     * Create the Intent for a LogAccessConfirmationActivity.
-     */
-    public static Intent createIntent(Context context, String targetPackageName,
-            IntentSender target, int uid, int gid, int pid, int fd) {
-        final Intent intent = new Intent();
-        intent.setClass(context, LogAccessConfirmationActivity.class);
-        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPackageName);
-        intent.putExtra(EXTRA_UID, uid);
-        intent.putExtra(EXTRA_GID, gid);
-        intent.putExtra(EXTRA_PID, pid);
-        intent.putExtra(EXTRA_FD, fd);
-
-        return intent;
-    }
-
-}
diff --git a/services/core/java/com/android/server/logcat/LogAccessDialogActivity.java b/services/core/java/com/android/server/logcat/LogAccessDialogActivity.java
new file mode 100644
index 0000000..8be90e0c
--- /dev/null
+++ b/services/core/java/com/android/server/logcat/LogAccessDialogActivity.java
@@ -0,0 +1,170 @@
+/*
+ * 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.logcat;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.logcat.ILogcatManagerService;
+import android.util.Slog;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.internal.R;
+
+/**
+ * Dialog responsible for obtaining user consent per-use log access
+ */
+public class LogAccessDialogActivity extends Activity implements
+        View.OnClickListener {
+    private static final String TAG = LogAccessDialogActivity.class.getSimpleName();
+    private Context mContext;
+
+    private final ILogcatManagerService mLogcatManagerService =
+            ILogcatManagerService.Stub.asInterface(ServiceManager.getService("logcat"));
+
+    private String mPackageName;
+
+    private int mUid;
+    private int mGid;
+    private int mPid;
+    private int mFd;
+    private String mAlertTitle;
+    private AlertDialog.Builder mAlertDialog;
+    private AlertDialog mAlert;
+
+    private static final int DIALOG_TIME_OUT = Build.IS_DEBUGGABLE ? 60000 : 300000;
+    private static final int MSG_DISMISS_DIALOG = 0;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mContext = this;
+
+        Intent intent = getIntent();
+        mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+        mUid = intent.getIntExtra("com.android.server.logcat.uid", 0);
+        mGid = intent.getIntExtra("com.android.server.logcat.gid", 0);
+        mPid = intent.getIntExtra("com.android.server.logcat.pid", 0);
+        mFd = intent.getIntExtra("com.android.server.logcat.fd", 0);
+        mAlertTitle = getTitleString(mContext, mPackageName, mUid);
+
+        if (mAlertTitle != null) {
+
+            mAlertDialog = new AlertDialog.Builder(this);
+            mAlertDialog.setView(createView());
+
+            mAlert = mAlertDialog.create();
+            mAlert.show();
+            mHandler.sendEmptyMessageDelayed(MSG_DISMISS_DIALOG, DIALOG_TIME_OUT);
+
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (mAlert != null && mAlert.isShowing()) {
+            mAlert.dismiss();
+        }
+        mAlert = null;
+    }
+
+    private Handler mHandler = new Handler() {
+        public void handleMessage(android.os.Message msg) {
+            switch (msg.what) {
+                case MSG_DISMISS_DIALOG:
+                    if (mAlert != null) {
+                        mAlert.dismiss();
+                        mAlert = null;
+                        try {
+                            mLogcatManagerService.decline(mUid, mGid, mPid, mFd);
+                        } catch (RemoteException e) {
+                            Slog.e(TAG, "Fails to call remote functions", e);
+                        }
+                    }
+                    break;
+
+                default:
+                    break;
+            }
+        }
+    };
+
+    private String getTitleString(Context context, String callingPackage, int uid) {
+        PackageManager pm = context.getPackageManager();
+        try {
+            return context.getString(
+                    com.android.internal.R.string.log_access_confirmation_title,
+                    pm.getApplicationInfoAsUser(callingPackage,
+                            PackageManager.MATCH_DIRECT_BOOT_AUTO,
+                            UserHandle.getUserId(uid)).loadLabel(pm));
+        } catch (NameNotFoundException e) {
+            Slog.e(TAG, "App name is unknown.", e);
+            return null;
+        }
+    }
+
+    private View createView() {
+        final View view = getLayoutInflater().inflate(
+                R.layout.log_access_user_consent_dialog_permission, null /*root*/);
+
+        ((TextView) view.findViewById(R.id.log_access_dialog_title))
+                .setText(mAlertTitle);
+
+        Button button_allow = (Button) view.findViewById(R.id.log_access_dialog_allow_button);
+        button_allow.setOnClickListener(this);
+
+        Button button_deny = (Button) view.findViewById(R.id.log_access_dialog_deny_button);
+        button_deny.setOnClickListener(this);
+
+        return view;
+    }
+
+    @Override
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.log_access_dialog_allow_button:
+                try {
+                    mLogcatManagerService.approve(mUid, mGid, mPid, mFd);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Fails to call remote functions", e);
+                }
+                finish();
+                break;
+            case R.id.log_access_dialog_deny_button:
+                try {
+                    mLogcatManagerService.decline(mUid, mGid, mPid, mFd);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Fails to call remote functions", e);
+                }
+                finish();
+                break;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/logcat/LogcatManagerService.java b/services/core/java/com/android/server/logcat/LogcatManagerService.java
index 490e00e..7b63fa2 100644
--- a/services/core/java/com/android/server/logcat/LogcatManagerService.java
+++ b/services/core/java/com/android/server/logcat/LogcatManagerService.java
@@ -18,15 +18,12 @@
 
 import android.annotation.NonNull;
 import android.app.ActivityManager;
-import android.app.ActivityManager.RunningAppProcessInfo;
 import android.app.ActivityManagerInternal;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Binder;
 import android.os.ILogd;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -34,16 +31,14 @@
 import android.os.logcat.ILogcatManagerService;
 import android.util.Slog;
 
-import com.android.internal.R;
-import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.ArrayUtils;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
-import java.util.Arrays;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
+
 /**
  * Service responsible for managing the access to Logcat.
  */
@@ -54,43 +49,16 @@
     private final BinderService mBinderService;
     private final ExecutorService mThreadExecutor;
     private ILogd mLogdService;
-    private NotificationManager mNotificationManager;
     private @NonNull ActivityManager mActivityManager;
     private ActivityManagerInternal mActivityManagerInternal;
     private static final int MAX_UID_IMPORTANCE_COUNT_LISTENER = 2;
-    private static int sUidImportanceListenerCount = 0;
-    private static final int AID_SHELL_UID = 2000;
-
-    // TODO This allowlist is just a temporary workaround for the tests:
-    //      FrameworksServicesTests
-    //      PlatformRuleTests
-    // After adapting the test suites, the allowlist will be removed in
-    // the upcoming bug fix patches.
-    private static final String[] ALLOWABLE_TESTING_PACKAGES = {
-            "android.platform.test.rule.tests",
-            "com.android.frameworks.servicestests"
-    };
-
-    // TODO Same as the above ALLOWABLE_TESTING_PACKAGES.
-    private boolean isAllowableTestingPackage(int uid) {
-        PackageManager pm = mContext.getPackageManager();
-
-        String[] packageNames = pm.getPackagesForUid(uid);
-
-        if (ArrayUtils.isEmpty(packageNames)) {
-            return false;
-        }
-
-        for (String name : packageNames) {
-            Slog.e(TAG, "isAllowableTestingPackage: " + name);
-
-            if (Arrays.asList(ALLOWABLE_TESTING_PACKAGES).contains(name)) {
-                return true;
-            }
-        }
-
-        return false;
-    };
+    private static final String TARGET_PACKAGE_NAME = "android";
+    private static final String TARGET_ACTIVITY_NAME =
+            "com.android.server.logcat.LogAccessDialogActivity";
+    private static final String EXTRA_UID = "com.android.server.logcat.uid";
+    private static final String EXTRA_GID = "com.android.server.logcat.gid";
+    private static final String EXTRA_PID = "com.android.server.logcat.pid";
+    private static final String EXTRA_FD = "com.android.server.logcat.fd";
 
     private final class BinderService extends ILogcatManagerService.Stub {
         @Override
@@ -110,7 +78,7 @@
             try {
                 getLogdService().approve(uid, gid, pid, fd);
             } catch (RemoteException e) {
-                e.printStackTrace();
+                Slog.e(TAG, "Fails to call remote functions", e);
             }
         }
 
@@ -119,7 +87,7 @@
             try {
                 getLogdService().decline(uid, gid, pid, fd);
             } catch (RemoteException e) {
-                e.printStackTrace();
+                Slog.e(TAG, "Fails to call remote functions", e);
             }
         }
     }
@@ -133,46 +101,16 @@
         }
     }
 
-    private String getBodyString(Context context, String callingPackage, int uid) {
-        PackageManager pm = context.getPackageManager();
-        try {
-            return context.getString(
-                com.android.internal.R.string.log_access_confirmation_body,
-                pm.getApplicationInfoAsUser(callingPackage, PackageManager.MATCH_DIRECT_BOOT_AUTO,
-                    UserHandle.getUserId(uid)).loadLabel(pm));
-        } catch (NameNotFoundException e) {
-            // App name is unknown.
-            return null;
-        }
-    }
-
-    private void sendNotification(int notificationId, String clientInfo, int uid, int gid, int pid,
-            int fd) {
-
+    private void showDialog(int uid, int gid, int pid, int fd) {
         final ActivityManagerInternal activityManagerInternal =
                 LocalServices.getService(ActivityManagerInternal.class);
 
         PackageManager pm = mContext.getPackageManager();
         String packageName = activityManagerInternal.getPackageNameByPid(pid);
         if (packageName != null) {
-            String notificationBody = getBodyString(mContext, packageName, uid);
-
-            final Intent mIntent = LogAccessConfirmationActivity.createIntent(mContext,
-                    packageName, null, uid, gid, pid, fd);
-
-            if (notificationBody == null) {
-                // Decline the logd access if the nofitication body is unknown
-                Slog.e(TAG, "Unknown notification body, declining the logd access");
-                declineLogdAccess(uid, gid, pid, fd);
-                return;
-            }
-
-            // TODO Next version will replace notification with dialogue
-            // per UX guidance.
-            generateNotificationWithBodyContent(notificationId, clientInfo, notificationBody,
-                    mIntent);
+            Intent mIntent = createIntent(packageName, uid, gid, pid, fd);
+            mContext.startActivityAsUser(mIntent, UserHandle.SYSTEM);
             return;
-
         }
 
         String[] packageNames = pm.getPackagesForUid(uid);
@@ -186,115 +124,28 @@
 
         String firstPackageName = packageNames[0];
 
-        if (firstPackageName == null || firstPackageName.length() == 0) {
+        if (firstPackageName.isEmpty() || firstPackageName == null) {
             // Decline the logd access if the package name from uid is unknown
             Slog.e(TAG, "Unknown calling package name, declining the logd access");
             declineLogdAccess(uid, gid, pid, fd);
             return;
         }
 
-        String notificationBody = getBodyString(mContext, firstPackageName, uid);
-
-        final Intent mIntent = LogAccessConfirmationActivity.createIntent(mContext,
-                firstPackageName, null, uid, gid, pid, fd);
-
-        if (notificationBody == null) {
-            Slog.e(TAG, "Unknown notification body, declining the logd access");
-            declineLogdAccess(uid, gid, pid, fd);
-            return;
-        }
-
-        // TODO Next version will replace notification with dialogue
-        // per UX guidance.
-        generateNotificationWithBodyContent(notificationId, clientInfo,
-                notificationBody, mIntent);
+        final Intent mIntent = createIntent(firstPackageName, uid, gid, pid, fd);
+        mContext.startActivityAsUser(mIntent, UserHandle.SYSTEM);
     }
 
     private void declineLogdAccess(int uid, int gid, int pid, int fd) {
         try {
             getLogdService().decline(uid, gid, pid, fd);
-        } catch (RemoteException ex) {
-            Slog.e(TAG, "Fails to call remote functions ", ex);
-        }
-    }
-
-    private void generateNotificationWithBodyContent(int notificationId, String clientInfo,
-            String notificationBody, Intent intent) {
-        final Notification.Builder notificationBuilder = new Notification.Builder(
-                mContext,
-                SystemNotificationChannels.ACCESSIBILITY_SECURITY_POLICY);
-        intent.setFlags(
-                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        intent.setIdentifier(String.valueOf(notificationId) + clientInfo);
-        intent.putExtra("body", notificationBody);
-
-        notificationBuilder
-            .setSmallIcon(R.drawable.ic_info)
-            .setContentTitle(
-                mContext.getString(R.string.log_access_confirmation_title))
-            .setContentText(notificationBody)
-            .setContentIntent(
-                PendingIntent.getActivity(mContext, 0, intent,
-                    PendingIntent.FLAG_IMMUTABLE))
-            .setTicker(mContext.getString(R.string.log_access_confirmation_title))
-            .setOnlyAlertOnce(true)
-            .setAutoCancel(true);
-        mNotificationManager.notify(notificationId, notificationBuilder.build());
-    }
-
-    /**
-     * A class which watches an uid for background access and notifies the logdMonitor when
-     * the package status becomes foreground (importance change)
-     */
-    private class UidImportanceListener implements ActivityManager.OnUidImportanceListener {
-        private final int mExpectedUid;
-        private final int mExpectedGid;
-        private final int mExpectedPid;
-        private final int mExpectedFd;
-        private int mExpectedImportance;
-        private int mCurrentImportance = RunningAppProcessInfo.IMPORTANCE_GONE;
-
-        UidImportanceListener(int uid, int gid, int pid, int fd, int importance) {
-            mExpectedUid = uid;
-            mExpectedGid = gid;
-            mExpectedPid = pid;
-            mExpectedFd = fd;
-            mExpectedImportance = importance;
-        }
-
-        @Override
-        public void onUidImportance(int uid, int importance) {
-            if (uid == mExpectedUid) {
-                mCurrentImportance = importance;
-
-                /**
-                 * 1) If the process status changes to foreground, send a notification
-                 * for user consent.
-                 * 2) If the process status remains background, we decline logd access request.
-                 **/
-                if (importance <= RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE) {
-                    String clientInfo = getClientInfo(uid, mExpectedGid, mExpectedPid, mExpectedFd);
-                    sendNotification(0, clientInfo, uid, mExpectedGid, mExpectedPid,
-                            mExpectedFd);
-                    mActivityManager.removeOnUidImportanceListener(this);
-
-                    synchronized (LogcatManagerService.this) {
-                        sUidImportanceListenerCount--;
-                    }
-                } else {
-                    try {
-                        getLogdService().decline(uid, mExpectedGid, mExpectedPid, mExpectedFd);
-                    } catch (RemoteException ex) {
-                        Slog.e(TAG, "Fails to call remote functions ", ex);
-                    }
-                }
-            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Fails to call remote functions", e);
         }
     }
 
     private static String getClientInfo(int uid, int gid, int pid, int fd) {
         return "UID=" + Integer.toString(uid) + " GID=" + Integer.toString(gid) + " PID="
-            + Integer.toString(pid) + " FD=" + Integer.toString(fd);
+                + Integer.toString(pid) + " FD=" + Integer.toString(fd);
     }
 
     private class LogdMonitor implements Runnable {
@@ -338,18 +189,22 @@
                     try {
                         getLogdService().approve(mUid, mGid, mPid, mFd);
                     } catch (RemoteException e) {
-                        e.printStackTrace();
+                        Slog.e(TAG, "Fails to call remote functions", e);
                     }
                     return;
                 }
 
-                // TODO Temporarily approve all the requests to unblock testing failures.
-                try {
-                    getLogdService().approve(mUid, mGid, mPid, mFd);
-                } catch (RemoteException e) {
-                    e.printStackTrace();
+                final int procState = mActivityManager.getUidImportance(Binder.getCallingUid());
+                // If the process is foreground, send a notification for user consent
+                if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
+                    showDialog(mUid, mGid, mPid, mFd);
+                } else {
+                    /**
+                     * If the process is background, decline the logd access.
+                     **/
+                    declineLogdAccess(mUid, mGid, mPid, mFd);
+                    return;
                 }
-                return;
             }
         }
     }
@@ -360,7 +215,6 @@
         mBinderService = new BinderService();
         mThreadExecutor = Executors.newCachedThreadPool();
         mActivityManager = context.getSystemService(ActivityManager.class);
-        mNotificationManager = mContext.getSystemService(NotificationManager.class);
     }
 
     @Override
@@ -375,4 +229,23 @@
     private void addLogdService() {
         mLogdService = ILogd.Stub.asInterface(ServiceManager.getService("logd"));
     }
+
+    /**
+     * Create the Intent for LogAccessDialogActivity.
+     */
+    public Intent createIntent(String targetPackageName, int uid, int gid, int pid, int fd) {
+        final Intent intent = new Intent();
+
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPackageName);
+        intent.putExtra(EXTRA_UID, uid);
+        intent.putExtra(EXTRA_GID, gid);
+        intent.putExtra(EXTRA_PID, pid);
+        intent.putExtra(EXTRA_FD, fd);
+
+        intent.setComponent(new ComponentName(TARGET_PACKAGE_NAME, TARGET_ACTIVITY_NAME));
+
+        return intent;
+    }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c4731aa7..1885b55 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -630,6 +630,7 @@
     private int mWarnRemoteViewsSizeBytes;
     private int mStripRemoteViewsSizeBytes;
     final boolean mEnableAppSettingMigration;
+    private boolean mForceUserSetOnUpgrade;
 
     private MetricsLogger mMetricsLogger;
     private TriPredicate<String, Integer, String> mAllowedManagedServicePackages;
@@ -1623,18 +1624,6 @@
         }
     };
 
-    @VisibleForTesting
-    final IAppOpsCallback mAppOpsCallback = new IAppOpsCallback.Stub() {
-        @Override public void opChanged(int op, int uid, String packageName) {
-            if (mEnableAppSettingMigration) {
-                int opValue = mAppOps.checkOpNoThrow(
-                        AppOpsManager.OP_POST_NOTIFICATION, uid, packageName);
-                boolean blocked = op != MODE_ALLOWED;
-                sendAppBlockStateChangedBroadcast(packageName, uid, blocked);
-            }
-        }
-    };
-
     private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -2133,12 +2122,6 @@
         mUsageStatsManagerInternal = usageStatsManagerInternal;
         mAppOps = appOps;
         mAppOpsService = iAppOps;
-        try {
-            mAppOpsService.startWatchingMode(
-                    AppOpsManager.OP_POST_NOTIFICATION, null, mAppOpsCallback);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Could not register OP_POST_NOTIFICATION listener");
-        }
         mAppUsageStats = appUsageStats;
         mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
         mCompanionManager = companionManager;
@@ -2312,6 +2295,7 @@
 
         mMsgPkgsAllowedAsConvos = Set.of(getStringArrayResource(
                 com.android.internal.R.array.config_notificationMsgPkgsAllowedAsConvos));
+
         mStatsManager = statsManager;
 
         mToastRateLimiter = toastRateLimiter;
@@ -2404,6 +2388,9 @@
 
         WorkerHandler handler = new WorkerHandler(Looper.myLooper());
 
+        mForceUserSetOnUpgrade = getContext().getResources().getBoolean(
+                R.bool.config_notificationForceUserSetOnUpgrade);
+
         init(handler, new RankingHandlerWorker(mRankingThread.getLooper()),
                 AppGlobals.getPackageManager(), getContext().getPackageManager(),
                 getLocalService(LightsManager.class),
@@ -2432,7 +2419,8 @@
                 LocalServices.getService(ActivityManagerInternal.class),
                 createToastRateLimiter(), new PermissionHelper(LocalServices.getService(
                         PermissionManagerServiceInternal.class), AppGlobals.getPackageManager(),
-                        AppGlobals.getPermissionManager(), mEnableAppSettingMigration),
+                        AppGlobals.getPermissionManager(), mEnableAppSettingMigration,
+                        mForceUserSetOnUpgrade),
                 LocalServices.getService(UsageStatsManagerInternal.class));
 
         publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
@@ -3409,6 +3397,7 @@
                 }
                 mPermissionHelper.setNotificationPermission(
                         pkg, UserHandle.getUserId(uid), enabled, true);
+                sendAppBlockStateChangedBroadcast(pkg, uid, !enabled);
             } else {
                 synchronized (mNotificationLock) {
                     boolean wasEnabled = mPreferencesHelper.getImportance(pkg, uid)
@@ -3746,6 +3735,10 @@
                     if (!hadChannel && hasChannel && !hasRequestedNotificationPermission
                             && startingTaskId != ActivityTaskManager.INVALID_TASK_ID) {
                         hasRequestedNotificationPermission = true;
+                        if (mPermissionPolicyInternal == null) {
+                            mPermissionPolicyInternal =
+                                    LocalServices.getService(PermissionPolicyInternal.class);
+                        }
                         mHandler.post(new ShowNotificationPermissionPromptRunnable(pkg,
                                 UserHandle.getUserId(uid), startingTaskId,
                                 mPermissionPolicyInternal));
@@ -3764,19 +3757,7 @@
             try {
                 int uid = mPackageManager.getPackageUid(pkg, 0,
                         UserHandle.getUserId(Binder.getCallingUid()));
-                List<ActivityManager.AppTask> tasks = mAtm.getAppTasks(pkg, uid);
-                for (int i = 0; i < tasks.size(); i++) {
-                    ActivityManager.RecentTaskInfo task = tasks.get(i).getTaskInfo();
-                    if (mPermissionPolicyInternal == null) {
-                        mPermissionPolicyInternal =
-                                LocalServices.getService(PermissionPolicyInternal.class);
-                    }
-                    if (mPermissionPolicyInternal != null
-                            && mPermissionPolicyInternal.canShowPermissionPromptForTask(task)) {
-                        taskId = task.taskId;
-                        break;
-                    }
-                }
+                taskId = mAtm.getTaskToShowPermissionDialogOn(pkg, uid);
             } catch (RemoteException e) {
                 // Do nothing
             }
@@ -4068,13 +4049,12 @@
 
         @Override
         public ParceledListSlice<NotificationChannel> getNotificationChannelsBypassingDnd(
-                String pkg, int userId) {
+                String pkg, int uid) {
             checkCallerIsSystem();
-            if (!areNotificationsEnabledForPackage(pkg,
-                    mPackageManagerInternal.getPackageUid(pkg, 0, userId))) {
+            if (!areNotificationsEnabledForPackage(pkg, uid)) {
                 return ParceledListSlice.emptyList();
             }
-            return mPreferencesHelper.getNotificationChannelsBypassingDnd(pkg, userId);
+            return mPreferencesHelper.getNotificationChannelsBypassingDnd(pkg, uid);
         }
 
         @Override
@@ -6095,6 +6075,7 @@
                     pw.println("  mMaxPackageEnqueueRate=" + mMaxPackageEnqueueRate);
                     pw.println("  hideSilentStatusBar="
                             + mPreferencesHelper.shouldHideSilentStatusIcons());
+                    pw.println("  mForceUserSetOnUpgrade=" + mForceUserSetOnUpgrade);
                 }
                 pw.println("  mArchive=" + mArchive.toString());
                 mArchive.dumpImpl(pw, filter);
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index 6b9e374..b4230c1 100644
--- a/services/core/java/com/android/server/notification/PermissionHelper.java
+++ b/services/core/java/com/android/server/notification/PermissionHelper.java
@@ -35,6 +35,7 @@
 import android.util.Pair;
 import android.util.Slog;
 
+import com.android.internal.util.ArrayUtils;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.util.Collections;
@@ -56,13 +57,16 @@
     private final IPermissionManager mPermManager;
     // TODO (b/194833441): Remove when the migration is enabled
     private final boolean mMigrationEnabled;
+    private final boolean mForceUserSetOnUpgrade;
 
     public PermissionHelper(PermissionManagerServiceInternal pmi, IPackageManager packageManager,
-            IPermissionManager permManager, boolean migrationEnabled) {
+            IPermissionManager permManager, boolean migrationEnabled,
+            boolean forceUserSetOnUpgrade) {
         mPmi = pmi;
         mPackageManager = packageManager;
         mPermManager = permManager;
         mMigrationEnabled = migrationEnabled;
+        mForceUserSetOnUpgrade = forceUserSetOnUpgrade;
     }
 
     public boolean isMigrationEnabled() {
@@ -178,13 +182,16 @@
             boolean userSet, boolean reviewRequired) {
         assertFlag();
         final long callingId = Binder.clearCallingIdentity();
-        // Do not change fixed permissions, and do not change non-user set permissions that are
-        // granted by default, or granted by role.
-        if (isPermissionFixed(packageName, userId)
-                || (isPermissionGrantedByDefaultOrRole(packageName, userId) && !userSet)) {
-            return;
-        }
         try {
+            // Do not change the permission if the package doesn't request it, do not change fixed
+            // permissions, and do not change non-user set permissions that are granted by default,
+            // or granted by role.
+            if (!packageRequestsNotificationPermission(packageName, userId)
+                    || isPermissionFixed(packageName, userId)
+                    || (isPermissionGrantedByDefaultOrRole(packageName, userId) && !userSet)) {
+                return;
+            }
+
             boolean currentlyGranted = mPmi.checkPermission(packageName, NOTIFICATION_PERMISSION,
                     userId) != PackageManager.PERMISSION_DENIED;
             if (grant && !reviewRequired && !currentlyGranted) {
@@ -219,8 +226,9 @@
             return;
         }
         if (!isPermissionFixed(pkgPerm.packageName, pkgPerm.userId)) {
+            boolean userSet = mForceUserSetOnUpgrade ? true : pkgPerm.userModifiedSettings;
             setNotificationPermission(pkgPerm.packageName, pkgPerm.userId, pkgPerm.granted,
-                    pkgPerm.userSet, !pkgPerm.userSet);
+                    userSet, !userSet);
         }
     }
 
@@ -278,6 +286,19 @@
         }
     }
 
+    private boolean packageRequestsNotificationPermission(String packageName,
+            @UserIdInt int userId) {
+        assertFlag();
+        try {
+            String[] permissions = mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS,
+                    userId).requestedPermissions;
+            return ArrayUtils.contains(permissions, NOTIFICATION_PERMISSION);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Could not reach system server", e);
+        }
+        return false;
+    }
+
     private void assertFlag() {
         if (!mMigrationEnabled) {
             throw new IllegalStateException("Method called without checking flag value");
@@ -288,13 +309,13 @@
         public final String packageName;
         public final @UserIdInt int userId;
         public final boolean granted;
-        public final boolean userSet;
+        public final boolean userModifiedSettings;
 
         public PackagePermission(String pkg, int userId, boolean granted, boolean userSet) {
             this.packageName = pkg;
             this.userId = userId;
             this.granted = granted;
-            this.userSet = userSet;
+            this.userModifiedSettings = userSet;
         }
 
         @Override
@@ -302,13 +323,14 @@
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
             PackagePermission that = (PackagePermission) o;
-            return userId == that.userId && granted == that.granted && userSet == that.userSet
+            return userId == that.userId && granted == that.granted && userModifiedSettings
+                    == that.userModifiedSettings
                     && Objects.equals(packageName, that.packageName);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(packageName, userId, granted, userSet);
+            return Objects.hash(packageName, userId, granted, userModifiedSettings);
         }
 
         @Override
@@ -317,7 +339,7 @@
                     "packageName='" + packageName + '\'' +
                     ", userId=" + userId +
                     ", granted=" + granted +
-                    ", userSet=" + userSet +
+                    ", userSet=" + userModifiedSettings +
                     '}';
         }
     }
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 1185890..1f7d65e 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -1669,14 +1669,14 @@
     }
 
     /**
-     * Gets all notification channels associated with the given pkg and userId that can bypass dnd
+     * Gets all notification channels associated with the given pkg and uid that can bypass dnd
      */
     public ParceledListSlice<NotificationChannel> getNotificationChannelsBypassingDnd(String pkg,
-            int userId) {
+            int uid) {
         List<NotificationChannel> channels = new ArrayList<>();
         synchronized (mPackagePreferences) {
             final PackagePreferences r = mPackagePreferences.get(
-                    packagePreferencesKey(pkg, userId));
+                    packagePreferencesKey(pkg, uid));
             if (r != null) {
                 for (NotificationChannel channel : r.channels.values()) {
                     if (channelIsLiveLocked(r, channel) && channel.canBypassDnd()) {
diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java
index 2a6dd84..b0d40ef 100644
--- a/services/core/java/com/android/server/notification/ZenModeFiltering.java
+++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java
@@ -112,7 +112,7 @@
         }
         if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
             if (consolidatedPolicy.allowRepeatCallers()
-                    && REPEAT_CALLERS.isRepeat(context, extras)) {
+                    && REPEAT_CALLERS.isRepeat(context, extras, null)) {
                 ZenLog.traceMatchesCallFilter(true, "repeat caller");
                 return true;
             }
@@ -229,7 +229,8 @@
                 }
                 if (isCall(record)) {
                     if (policy.allowRepeatCallers()
-                            && REPEAT_CALLERS.isRepeat(mContext, extras(record))) {
+                            && REPEAT_CALLERS.isRepeat(
+                                    mContext, extras(record), record.getPhoneNumbers())) {
                         ZenLog.traceNotIntercepted(record, "repeatCaller");
                         return false;
                     }
@@ -350,6 +351,9 @@
         private final ArrayMap<String, Long> mOtherCalls = new ArrayMap<>();
         private int mThresholdMinutes;
 
+        // Record all people URIs in the extras bundle as well as the provided phoneNumbers set
+        // as callers. The phoneNumbers set is used to pass in any additional phone numbers
+        // associated with the people URIs as separately retrieved from contacts.
         private synchronized void recordCall(Context context, Bundle extras,
                 ArraySet<String> phoneNumbers) {
             setThresholdMinutes(context);
@@ -362,7 +366,13 @@
             recordCallers(extraPeople, phoneNumbers, now);
         }
 
-        private synchronized boolean isRepeat(Context context, Bundle extras) {
+        // Determine whether any people in the provided extras bundle or phone number set is
+        // a repeat caller. The extras bundle contains the people associated with a specific
+        // notification, and will suffice for most callers; the phoneNumbers array may be used
+        // to additionally check any specific phone numbers previously retrieved from contacts
+        // associated with the people in the extras bundle.
+        private synchronized boolean isRepeat(Context context, Bundle extras,
+                ArraySet<String> phoneNumbers) {
             setThresholdMinutes(context);
             if (mThresholdMinutes <= 0 || extras == null) return false;
             final String[] extraPeople = ValidateNotificationPeople.getExtraPeople(extras);
@@ -370,7 +380,7 @@
             final long now = System.currentTimeMillis();
             cleanUp(mTelCalls, now);
             cleanUp(mOtherCalls, now);
-            return checkCallers(context, extraPeople);
+            return checkCallers(context, extraPeople, phoneNumbers);
         }
 
         private synchronized void cleanUp(ArrayMap<String, Long> calls, long now) {
@@ -433,7 +443,31 @@
             }
         }
 
-        private synchronized boolean checkCallers(Context context, String[] people) {
+        // helper function to check mTelCalls array for a number, and also check its decoded
+        // version
+        private synchronized boolean checkForNumber(String number, String defaultCountryCode) {
+            if (mTelCalls.containsKey(number)) {
+                // check directly via map first
+                return true;
+            } else {
+                // see if a number that matches via areSameNumber exists
+                String numberToCheck = Uri.decode(number);
+                if (numberToCheck != null) {
+                    for (String prev : mTelCalls.keySet()) {
+                        if (PhoneNumberUtils.areSamePhoneNumber(
+                                numberToCheck, prev, defaultCountryCode)) {
+                            return true;
+                        }
+                    }
+                }
+            }
+            return false;
+        }
+
+        // Check whether anyone in the provided array of people URIs or phone number set matches a
+        // previously recorded phone call.
+        private synchronized boolean checkCallers(Context context, String[] people,
+                ArraySet<String> phoneNumbers) {
             // get the default country code for checking telephone numbers
             final String defaultCountryCode =
                     context.getSystemService(TelephonyManager.class).getNetworkCountryIso();
@@ -443,20 +477,8 @@
                 final Uri uri = Uri.parse(person);
                 if ("tel".equals(uri.getScheme())) {
                     String number = uri.getSchemeSpecificPart();
-                    if (mTelCalls.containsKey(number)) {
-                        // check directly via map first
+                    if (checkForNumber(number, defaultCountryCode)) {
                         return true;
-                    } else {
-                        // see if a number that matches via areSameNumber exists
-                        String numberToCheck = Uri.decode(number);
-                        if (numberToCheck != null) {
-                            for (String prev : mTelCalls.keySet()) {
-                                if (PhoneNumberUtils.areSamePhoneNumber(
-                                        numberToCheck, prev, defaultCountryCode)) {
-                                    return true;
-                                }
-                            }
-                        }
                     }
                 } else {
                     if (mOtherCalls.containsKey(person)) {
@@ -464,6 +486,17 @@
                     }
                 }
             }
+
+            // also check any passed-in phone numbers
+            if (phoneNumbers != null) {
+                for (String num : phoneNumbers) {
+                    if (checkForNumber(num, defaultCountryCode)) {
+                        return true;
+                    }
+                }
+            }
+
+            // no matches
             return false;
         }
     }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 93f1b47..9e0c975 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -104,6 +104,7 @@
 
     // The amount of time rules instances can exist without their owning app being installed.
     private static final int RULE_INSTANCE_GRACE_PERIOD = 1000 * 60 * 60 * 72;
+    static final int RULE_LIMIT_PER_PACKAGE = 100;
 
     // pkg|userId => uid
     protected final ArrayMap<String, Integer> mRulesUidCache = new ArrayMap<>();
@@ -329,10 +330,10 @@
             int newRuleInstanceCount = getCurrentInstanceCount(automaticZenRule.getOwner())
                     + getCurrentInstanceCount(automaticZenRule.getConfigurationActivity())
                     + 1;
-            if (ruleInstanceLimit > 0 && ruleInstanceLimit < newRuleInstanceCount) {
+            if (newRuleInstanceCount > RULE_LIMIT_PER_PACKAGE
+                    || (ruleInstanceLimit > 0 && ruleInstanceLimit < newRuleInstanceCount)) {
                 throw new IllegalArgumentException("Rule instance limit exceeded");
             }
-
         }
 
         ZenModeConfig newConfig;
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 6a2b2d5..76d3d23 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -29,7 +29,6 @@
 import android.apex.IApexService;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
-import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
 import android.content.pm.SigningDetails;
 import android.content.pm.parsing.result.ParseResult;
@@ -834,7 +833,7 @@
                 throw new RuntimeException(re);
             } catch (Exception e) {
                 throw new PackageManagerException(
-                        PackageInstaller.SessionInfo.SESSION_VERIFICATION_FAILED,
+                        PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
                         "apexd verification failed : " + e.getMessage());
             }
         }
@@ -861,7 +860,7 @@
                 throw new RuntimeException(re);
             } catch (Exception e) {
                 throw new PackageManagerException(
-                        PackageInstaller.SessionInfo.SESSION_VERIFICATION_FAILED,
+                        PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
                         "Failed to mark apexd session as ready : " + e.getMessage());
             }
         }
diff --git a/services/core/java/com/android/server/pm/ApkChecksums.java b/services/core/java/com/android/server/pm/ApkChecksums.java
index aa467e7..2824585 100644
--- a/services/core/java/com/android/server/pm/ApkChecksums.java
+++ b/services/core/java/com/android/server/pm/ApkChecksums.java
@@ -34,6 +34,7 @@
 import android.content.pm.ApkChecksum;
 import android.content.pm.Checksum;
 import android.content.pm.IOnChecksumsReadyListener;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
 import android.content.pm.SigningDetails.SignatureSchemeVersion;
@@ -62,6 +63,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.security.VerityUtils;
+import com.android.server.LocalServices;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 
 import java.io.ByteArrayOutputStream;
diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java
index 0b0d1458..5013570 100644
--- a/services/core/java/com/android/server/pm/AppDataHelper.java
+++ b/services/core/java/com/android/server/pm/AppDataHelper.java
@@ -36,7 +36,6 @@
 import android.os.storage.VolumeInfo;
 import android.security.AndroidKeyStoreMaintenance;
 import android.system.keystore2.Domain;
-import android.system.keystore2.KeyDescriptor;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
@@ -218,8 +217,9 @@
 
         final String seInfo = pkgSeInfo + seInfoUser;
         final int targetSdkVersion = pkg.getTargetSdkVersion();
+        final boolean usesSdk = !pkg.getUsesSdkLibraries().isEmpty();
         final CreateAppDataArgs args = Installer.buildCreateAppDataArgs(volumeUuid, packageName,
-                userId, flags, appId, seInfo, targetSdkVersion);
+                userId, flags, appId, seInfo, targetSdkVersion, usesSdk);
         args.previousAppId = previousAppId;
 
         return batch.createAppData(args).whenComplete((ceDataInode, e) -> {
@@ -554,26 +554,6 @@
         return prepareAppDataFuture;
     }
 
-    public void migrateKeyStoreData(int previousAppId, int appId) {
-        // If previous UID is system UID, declaring inheritKeyStoreKeys is not supported.
-        // Silently ignore the request to migrate keys.
-        if (previousAppId == Process.SYSTEM_UID) return;
-
-        for (int userId : mPm.resolveUserIds(UserHandle.USER_ALL)) {
-            int srcUid = UserHandle.getUid(userId, previousAppId);
-            int destUid = UserHandle.getUid(userId, appId);
-            final KeyDescriptor[] keys = AndroidKeyStoreMaintenance.listEntries(Domain.APP, srcUid);
-            if (keys == null) continue;
-            for (final KeyDescriptor key : keys) {
-                KeyDescriptor dest = new KeyDescriptor();
-                dest.domain = Domain.APP;
-                dest.nspace = destUid;
-                dest.alias = key.alias;
-                AndroidKeyStoreMaintenance.migrateKeyNamespace(key, dest);
-            }
-        }
-    }
-
     void clearAppDataLIF(AndroidPackage pkg, int userId, int flags) {
         if (pkg == null) {
             return;
diff --git a/services/core/java/com/android/server/pm/AppIdSettingMap.java b/services/core/java/com/android/server/pm/AppIdSettingMap.java
new file mode 100644
index 0000000..b41a0b8
--- /dev/null
+++ b/services/core/java/com/android/server/pm/AppIdSettingMap.java
@@ -0,0 +1,147 @@
+/*
+ * 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.pm;
+
+import android.os.Process;
+import android.util.Log;
+
+import com.android.server.utils.WatchedArrayList;
+import com.android.server.utils.WatchedSparseArray;
+import com.android.server.utils.Watcher;
+
+/**
+ * A wrapper over {@link WatchedArrayList} that tracks the current (app ID -> SettingBase) mapping
+ * for non-system apps. Also tracks system app settings in an {@link WatchedSparseArray}.
+ */
+final class AppIdSettingMap {
+    /**
+     * We use an ArrayList instead of an SparseArray for non system apps because the number of apps
+     * might be big, and only ArrayList gives us a constant lookup time. For a given app ID, the
+     * index to the corresponding SettingBase object is (appId - FIRST_APPLICATION_ID). If an app ID
+     * doesn't exist (i.e., app is not installed), we fill the corresponding entry with null.
+     */
+    private WatchedArrayList<SettingBase> mNonSystemSettings = new WatchedArrayList<>();
+    private WatchedSparseArray<SettingBase> mSystemSettings = new WatchedSparseArray<>();
+    private int mFirstAvailableAppId = Process.FIRST_APPLICATION_UID;
+
+    /** Returns true if the requested AppID was valid and not already registered. */
+    public boolean registerExistingAppId(int appId, SettingBase setting, Object name) {
+        if (appId >= Process.FIRST_APPLICATION_UID) {
+            int size = mNonSystemSettings.size();
+            final int index = appId - Process.FIRST_APPLICATION_UID;
+            // fill the array until our index becomes valid
+            while (index >= size) {
+                mNonSystemSettings.add(null);
+                size++;
+            }
+            if (mNonSystemSettings.get(index) != null) {
+                PackageManagerService.reportSettingsProblem(Log.WARN,
+                        "Adding duplicate app id: " + appId
+                                + " name=" + name);
+                return false;
+            }
+            mNonSystemSettings.set(index, setting);
+        } else {
+            if (mSystemSettings.get(appId) != null) {
+                PackageManagerService.reportSettingsProblem(Log.WARN,
+                        "Adding duplicate shared id: " + appId
+                                + " name=" + name);
+                return false;
+            }
+            mSystemSettings.put(appId, setting);
+        }
+        return true;
+    }
+
+    public SettingBase getSetting(int appId) {
+        if (appId >= Process.FIRST_APPLICATION_UID) {
+            final int size = mNonSystemSettings.size();
+            final int index = appId - Process.FIRST_APPLICATION_UID;
+            return index < size ? mNonSystemSettings.get(index) : null;
+        } else {
+            return mSystemSettings.get(appId);
+        }
+    }
+
+    public void removeSetting(int appId) {
+        if (appId >= Process.FIRST_APPLICATION_UID) {
+            final int size = mNonSystemSettings.size();
+            final int index = appId - Process.FIRST_APPLICATION_UID;
+            if (index < size) {
+                mNonSystemSettings.set(index, null);
+            }
+        } else {
+            mSystemSettings.remove(appId);
+        }
+        setFirstAvailableAppId(appId + 1);
+    }
+
+    // This should be called (at least) whenever an application is removed
+    private void setFirstAvailableAppId(int uid) {
+        if (uid > mFirstAvailableAppId) {
+            mFirstAvailableAppId = uid;
+        }
+    }
+
+    public void replaceSetting(int appId, SettingBase setting) {
+        if (appId >= Process.FIRST_APPLICATION_UID) {
+            final int size = mNonSystemSettings.size();
+            final int index = appId - Process.FIRST_APPLICATION_UID;
+            if (index < size) {
+                mNonSystemSettings.set(index, setting);
+            } else {
+                PackageManagerService.reportSettingsProblem(Log.WARN,
+                        "Error in package manager settings: calling replaceAppIdLpw to"
+                                + " replace SettingBase at appId=" + appId
+                                + " but nothing is replaced.");
+            }
+        } else {
+            mSystemSettings.put(appId, setting);
+        }
+    }
+
+    /** Returns a new AppID or -1 if we could not find an available AppID to assign */
+    public int acquireAndRegisterNewAppId(SettingBase obj) {
+        final int size = mNonSystemSettings.size();
+        for (int i = mFirstAvailableAppId - Process.FIRST_APPLICATION_UID; i < size; i++) {
+            if (mNonSystemSettings.get(i) == null) {
+                mNonSystemSettings.set(i, obj);
+                return Process.FIRST_APPLICATION_UID + i;
+            }
+        }
+
+        // None left?
+        if (size > (Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID)) {
+            return -1;
+        }
+
+        mNonSystemSettings.add(obj);
+        return Process.FIRST_APPLICATION_UID + size;
+    }
+
+    public AppIdSettingMap snapshot() {
+        AppIdSettingMap l = new AppIdSettingMap();
+        mNonSystemSettings.snapshot(l.mNonSystemSettings, mNonSystemSettings);
+        mSystemSettings.snapshot(l.mSystemSettings, mSystemSettings);
+        return l;
+    }
+
+    public void registerObserver(Watcher observer) {
+        mNonSystemSettings.registerObserver(observer);
+        mSystemSettings.registerObserver(observer);
+    }
+}
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index d117967..7b2dc28 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -52,6 +52,7 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.function.QuadFunction;
 import com.android.server.FgThread;
+import com.android.server.LocalServices;
 import com.android.server.compat.CompatChange;
 import com.android.server.om.OverlayReferenceMapper;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
@@ -486,12 +487,12 @@
     }
 
     /** Builder method for an AppsFilter */
-    public static AppsFilter create(
-            PackageManagerInternal pms, PackageManagerServiceInjector injector) {
+    public static AppsFilter create(@NonNull PackageManagerServiceInjector injector,
+            @NonNull PackageManagerInternal pmInt) {
         final boolean forceSystemAppsQueryable =
                 injector.getContext().getResources()
                         .getBoolean(R.bool.config_forceSystemPackagesQueryable);
-        final FeatureConfigImpl featureConfig = new FeatureConfigImpl(pms, injector);
+        final FeatureConfigImpl featureConfig = new FeatureConfigImpl(pmInt, injector);
         final String[] forcedQueryablePackageNames;
         if (forceSystemAppsQueryable) {
             // all system apps already queryable, no need to read and parse individual exceptions
@@ -512,7 +513,7 @@
         };
         AppsFilter appsFilter = new AppsFilter(stateProvider, featureConfig,
                 forcedQueryablePackageNames, forceSystemAppsQueryable, null,
-                injector.getBackgroundExecutor(), pms);
+                injector.getBackgroundExecutor(), pmInt);
         featureConfig.setAppsFilter(appsFilter);
         return appsFilter;
     }
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 31df0a5..9ff4aab 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -19,6 +19,7 @@
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.job.JobInfo;
 import android.app.job.JobParameters;
@@ -269,7 +270,7 @@
             PackageManagerService pm = mInjector.getPackageManagerService();
             ArraySet<String> packagesToOptimize;
             if (packageNames == null) {
-                packagesToOptimize = mDexOptHelper.getOptimizablePackages();
+                packagesToOptimize = mDexOptHelper.getOptimizablePackages(pm.snapshotComputer());
             } else {
                 packagesToOptimize = new ArraySet<>(packageNames);
             }
@@ -334,7 +335,7 @@
             return false;
         }
 
-        ArraySet<String> pkgs = mDexOptHelper.getOptimizablePackages();
+        ArraySet<String> pkgs = mDexOptHelper.getOptimizablePackages(pm.snapshotComputer());
         if (pkgs.isEmpty()) {
             Slog.i(TAG, "No packages to optimize");
             markPostBootUpdateCompleted(params);
@@ -556,8 +557,8 @@
     }
 
     /** Gets the size of a package. */
-    private long getPackageSize(PackageManagerService pm, String pkg) {
-        PackageInfo info = pm.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
+    private long getPackageSize(@NonNull Computer snapshot, String pkg) {
+        PackageInfo info = snapshot.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
         long size = 0;
         if (info != null && info.applicationInfo != null) {
             File path = Paths.get(info.applicationInfo.sourceDir).toFile();
@@ -605,8 +606,9 @@
                 Slog.d(TAG, "Should Downgrade " + shouldDowngrade);
             }
             if (shouldDowngrade) {
+                final Computer snapshot = pm.snapshotComputer();
                 Set<String> unusedPackages =
-                        pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis);
+                        snapshot.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis);
                 if (DEBUG) {
                     Slog.d(TAG, "Unsused Packages " + String.join(",", unusedPackages));
                 }
@@ -618,7 +620,7 @@
                             // Should be aborted by the scheduler.
                             return abortCode;
                         }
-                        @DexOptResult int downgradeResult = downgradePackage(pm, pkg,
+                        @DexOptResult int downgradeResult = downgradePackage(snapshot, pm, pkg,
                                 /* isForPrimaryDex= */ true, isPostBootUpdate);
                         if (downgradeResult == PackageDexOptimizer.DEX_OPT_PERFORMED) {
                             updatedPackages.add(pkg);
@@ -629,7 +631,7 @@
                             return status;
                         }
                         if (supportSecondaryDex) {
-                            downgradeResult = downgradePackage(pm, pkg,
+                            downgradeResult = downgradePackage(snapshot, pm, pkg,
                                     /* isForPrimaryDex= */false, isPostBootUpdate);
                             status = convertPackageDexOptimizerStatusToInternal(downgradeResult);
                             if (status != STATUS_OK) {
@@ -696,8 +698,8 @@
      * @return PackageDexOptimizer.DEX_*
      */
     @DexOptResult
-    private int downgradePackage(PackageManagerService pm, String pkg, boolean isForPrimaryDex,
-            boolean isPostBootUpdate) {
+    private int downgradePackage(@NonNull Computer snapshot, PackageManagerService pm, String pkg,
+            boolean isForPrimaryDex, boolean isPostBootUpdate) {
         if (DEBUG) {
             Slog.d(TAG, "Downgrading " + pkg);
         }
@@ -709,15 +711,15 @@
         if (!isPostBootUpdate) {
             dexoptFlags |= DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB;
         }
-        long package_size_before = getPackageSize(pm, pkg);
+        long package_size_before = getPackageSize(snapshot, pkg);
         int result = PackageDexOptimizer.DEX_OPT_SKIPPED;
         if (isForPrimaryDex || PLATFORM_PACKAGE_NAME.equals(pkg)) {
             // This applies for system apps or if packages location is not a directory, i.e.
             // monolithic install.
-            if (!pm.canHaveOatDir(pkg)) {
+            if (!pm.canHaveOatDir(snapshot, pkg)) {
                 // For apps that don't have the oat directory, instead of downgrading,
                 // remove their compiler artifacts from dalvik cache.
-                pm.deleteOatArtifactsOfPackage(pkg);
+                pm.deleteOatArtifactsOfPackage(snapshot, pkg);
             } else {
                 result = performDexOptPrimary(pkg, reason, dexoptFlags);
             }
@@ -726,8 +728,9 @@
         }
 
         if (result == PackageDexOptimizer.DEX_OPT_PERFORMED) {
+            final Computer newSnapshot = pm.snapshotComputer();
             FrameworkStatsLog.write(FrameworkStatsLog.APP_DOWNGRADED, pkg, package_size_before,
-                    getPackageSize(pm, pkg), /*aggressive=*/ false);
+                    getPackageSize(newSnapshot, pkg), /*aggressive=*/ false);
         }
         return result;
     }
diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java
index df7387d..f1394d4 100644
--- a/services/core/java/com/android/server/pm/BroadcastHelper.java
+++ b/services/core/java/com/android/server/pm/BroadcastHelper.java
@@ -119,14 +119,10 @@
                 intent.setPackage(targetPkg);
             }
             // Modify the UID when posting to other users
-            final String[] uidExtraNames =
-                    { Intent.EXTRA_UID, Intent.EXTRA_PREVIOUS_UID, Intent.EXTRA_NEW_UID };
-            for (String name : uidExtraNames) {
-                int uid = intent.getIntExtra(name, -1);
-                if (uid >= 0 && UserHandle.getUserId(uid) != userId) {
-                    uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
-                    intent.putExtra(name, uid);
-                }
+            int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+            if (uid >= 0 && UserHandle.getUserId(uid) != userId) {
+                uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
+                intent.putExtra(Intent.EXTRA_UID, uid);
             }
             if (broadcastAllowList != null && PLATFORM_PACKAGE_NAME.equals(targetPkg)) {
                 intent.putExtra(Intent.EXTRA_VISIBILITY_ALLOW_LIST,
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index 2a4882a..8e85301 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -58,10 +58,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
 import java.util.List;
 import java.util.Set;
 
@@ -92,92 +88,69 @@
  * and other managers (like PermissionManager) mean deadlock is possible.  On the
  * other hand, not overriding in {@link ComputerLocked} may leave a function walking
  * unstable data.
- *
- * To coax developers to consider such issues carefully, all methods in
- * {@link Computer} must be annotated with <code>@LiveImplementation(override =
- * MANDATORY)</code> or <code>LiveImplementation(locked = NOT_ALLOWED)</code>.  A unit
- * test verifies the annotation and that the annotation corresponds to the code in
- * {@link ComputerEngine} and {@link ComputerLocked}.
  */
 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
 public interface Computer extends PackageDataSnapshot {
 
     /**
-     * Every method must be annotated.
-     */
-    @Target({ ElementType.METHOD })
-    @Retention(RetentionPolicy.RUNTIME)
-    @interface LiveImplementation {
-        // A Computer method must be annotated with one of the following values:
-        //   MANDATORY - the method must be overridden in ComputerEngineLive.  The
-        //     format of the override is a call to the super method, wrapped in a
-        //     synchronization block.
-        //   NOT_ALLOWED - the method may not appear in the live computer.  It must
-        //     be final in the ComputerEngine.
-        int MANDATORY = 1;
-        int NOT_ALLOWED = 2;
-        int override() default MANDATORY;
-        String rationale() default "";
-    }
-
-    /**
      * Administrative statistics: record that the snapshot has been used.  Every call
      * to use() increments the usage counter.
      */
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     default void use() {
     }
     /**
      * Fetch the snapshot usage counter.
      * @return The number of times this snapshot was used.
      */
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     default int getUsed() {
         return 0;
     }
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
             @PackageManager.ResolveInfoFlagsBits long flags,
             @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags,
             int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
             long flags, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, String resolvedType,
             long flags, int userId, int callingUid, boolean includeInstantApps);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(Intent intent,
             String resolvedType, long flags, int filterCallingUid, int userId,
             boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
             String instantAppPkgName);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     ActivityInfo getActivityInfo(ComponentName component, long flags, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
+
+    /**
+     * Important: The provided filterCallingUid is used exclusively to filter out activities
+     * that can be seen based on user state. It's typically the original caller uid prior
+     * to clearing. Because it can only be provided by trusted code, its value can be
+     * trusted and will be used as-is; unlike userId which will be validated by this method.
+     */
     ActivityInfo getActivityInfoInternal(ComponentName component, long flags,
             int filterCallingUid, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     AndroidPackage getPackage(String packageName);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     AndroidPackage getPackage(int uid);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     ApplicationInfo generateApplicationInfoFromSettings(String packageName, long flags,
             int filterCallingUid, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     ApplicationInfo getApplicationInfo(String packageName, long flags, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
+
+    /**
+     * Important: The provided filterCallingUid is used exclusively to filter out applications
+     * that can be seen based on user state. It's typically the original caller uid prior
+     * to clearing. Because it can only be provided by trusted code, its value can be
+     * trusted and will be used as-is; unlike userId which will be validated by this method.
+     */
     ApplicationInfo getApplicationInfoInternal(String packageName, long flags,
             int filterCallingUid, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
+
+    /**
+     * Report the 'Home' activity which is currently set as "always use this one". If non is set
+     * then reports the most likely home activity or null if there are more than one.
+     */
     ComponentName getDefaultHomeActivity(int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType,
             long flags, int sourceUserId, int parentUserId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     Intent getHomeIntent();
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
             String resolvedType, int userId);
 
@@ -192,15 +165,11 @@
      * @param intent
      * @return A filtered list of resolved activities.
      */
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
             String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
             boolean resolveForStart, int userId, Intent intent);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     PackageInfo generatePackageInfo(PackageStateInternal ps, long flags, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     PackageInfo getPackageInfo(String packageName, long flags, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     PackageInfo getPackageInfoInternal(String packageName, long versionCode, long flags,
             int filterCallingUid, int userId);
 
@@ -209,192 +178,179 @@
      * known {@link PackageState} instances without a {@link PackageState#getAndroidPackage()}
      * will not be represented.
      */
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     String[] getAllAvailablePackageNames();
 
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     PackageStateInternal getPackageStateInternal(String packageName);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     PackageStateInternal getPackageStateInternal(String packageName, int callingUid);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
-    @Nullable PackageState getPackageStateCopied(@NonNull String packageName);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     ParceledListSlice<PackageInfo> getInstalledPackages(long flags, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
             int sourceUserId, int targetUserId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     ServiceInfo getServiceInfo(ComponentName component, long flags, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     SharedLibraryInfo getSharedLibraryInfo(String name, long version);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     String getInstantAppPackageName(int callingUid);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     String resolveExternalPackageName(AndroidPackage pkg);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     String resolveInternalPackageName(String packageName, long versionCode);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     String[] getPackagesForUid(int uid);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     UserInfo getProfileParent(int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean canViewInstantApps(int callingUid, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean filterSharedLibPackage(@Nullable PackageStateInternal ps, int uid, int userId,
             long flags);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean isCallerSameApp(String packageName, int uid);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean isComponentVisibleToInstantApp(@Nullable ComponentName component);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean isComponentVisibleToInstantApp(@Nullable ComponentName component,
             @PackageManager.ComponentType int type);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId,
+
+    /**
+     * From Android R, camera intents have to match system apps. The only exception to this is if
+     * the DPC has set the camera persistent preferred activity. This case was introduced
+     * because it is important that the DPC has the ability to set both system and non-system
+     * camera persistent preferred activities.
+     *
+     * @return {@code true} if the intent is a camera intent and the persistent preferred
+     * activity was not set by the DPC.
+     */
+    boolean isImplicitImageCaptureIntentAndNotSetByDpc(Intent intent, int userId,
             String resolvedType, long flags);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean isInstantApp(String packageName, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean shouldFilterApplication(@Nullable PackageStateInternal ps, int callingUid,
             @Nullable ComponentName component, @PackageManager.ComponentType int componentType,
             int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean shouldFilterApplication(@Nullable PackageStateInternal ps, int callingUid,
             int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean shouldFilterApplication(@NonNull SharedUserSetting sus, int callingUid,
             int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     int checkUidPermission(String permName, int uid);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     int getPackageUidInternal(String packageName, long flags, int userId, int callingUid);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     long updateFlagsForApplication(long flags, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     long updateFlagsForComponent(long flags, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     long updateFlagsForPackage(long flags, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
+
+    /**
+     * Update given flags when being used to request {@link ResolveInfo}.
+     * <p>Instant apps are resolved specially, depending upon context. Minimally,
+     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
+     * flag set. However, this flag is only honoured in three circumstances:
+     * <ul>
+     * <li>when called from a system process</li>
+     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
+     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
+     * action and a {@code android.intent.category.BROWSABLE} category</li>
+     * </ul>
+     */
     long updateFlagsForResolve(long flags, int userId, int callingUid, boolean wantInstantApps,
             boolean isImplicitImageCaptureIntentAndNotSetByDpc);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     long updateFlagsForResolve(long flags, int userId, int callingUid, boolean wantInstantApps,
             boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
+
+    /**
+     * Checks if the request is from the system or an app that has the appropriate cross-user
+     * permissions defined as follows:
+     * <ul>
+     * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
+     * <li>INTERACT_ACROSS_USERS if the given {@code userId} is in a different profile group
+     * to the caller.</li>
+     * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@code userId} is in the same profile
+     * group as the caller.</li>
+     * </ul>
+     *
+     * @param checkShell whether to prevent shell from access if there's a debugging restriction
+     * @param message the message to log on security exception
+     */
     void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
             boolean requireFullPermission, boolean checkShell, String message);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
+
+    /**
+     * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
+     * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
+     *
+     * @param checkShell whether to prevent shell from access if there's a debugging restriction
+     * @param message the message to log on security exception
+     */
     void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
             boolean requireFullPermission, boolean checkShell, String message);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
             boolean requireFullPermission, boolean checkShell,
             boolean requirePermissionWhenSameUser, String message);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     SigningDetails getSigningDetails(@NonNull String packageName);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     SigningDetails getSigningDetails(int uid);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     boolean filterAppAccess(String packageName, int callingUid, int userId);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     boolean filterAppAccess(int uid, int callingUid);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityInternal(
             Intent intent, String resolvedType, long flags, List<ResolveInfo> query, boolean always,
             boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered);
-    @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, long flags,
+    ResolveInfo findPersistentPreferredActivity(Intent intent, String resolvedType, long flags,
             List<ResolveInfo> query, boolean debug, int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     PreferredIntentResolver getPreferredActivities(@UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     ArrayMap<String, ? extends PackageStateInternal> getPackageStates();
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     String getRenamedPackage(@NonNull String packageName);
 
     /**
      * @return set of packages to notify
      */
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     ArraySet<String> getNotifyPackagesForReplacedReceived(@NonNull String[] packages);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @PackageManagerService.PackageStartability
     int getPackageStartability(boolean safeMode, @NonNull String packageName, int callingUid,
             @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean isPackageAvailable(String packageName, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     String[] currentToCanonicalPackageNames(@NonNull String[] names);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     String[] canonicalToCurrentPackageNames(@NonNull String[] names);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     int[] getPackageGids(@NonNull String packageName,
             @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     int getTargetSdkVersion(@NonNull String packageName);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean activitySupportsIntent(@NonNull ComponentName resolveComponentName,
             @NonNull ComponentName component, @NonNull Intent intent, String resolvedType);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     ActivityInfo getReceiverInfo(@NonNull ComponentName component,
             @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     ParceledListSlice<SharedLibraryInfo> getSharedLibraries(@NonNull String packageName,
             @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean canRequestPackageInstalls(@NonNull String packageName, int callingUid,
             int userId, boolean throwIfPermNotDeclared);
 
-    @Computer.LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
+    /**
+     * Returns true if the system or user is explicitly preventing an otherwise valid installer to
+     * complete an install. This includes checks like unknown sources and user restrictions.
+     */
     boolean isInstallDisabledForPackage(@NonNull String packageName, int uid,
             @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     List<VersionedPackage> getPackagesUsingSharedLibrary(@NonNull SharedLibraryInfo libInfo,
             @PackageManager.PackageInfoFlagsBits long flags, int callingUid, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
             @NonNull String packageName, @PackageManager.PackageInfoFlagsBits long flags,
             @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     ProviderInfo getProviderInfo(@NonNull ComponentName component,
             @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     String[] getSystemSharedLibraryNames();
 
@@ -402,136 +358,103 @@
      * @return the state if the given package has a state and isn't filtered by visibility.
      * Provides no guarantee that the package is in any usable state.
      */
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     PackageStateInternal getPackageStateFiltered(@NonNull String packageName, int callingUid,
             @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     int checkSignatures(@NonNull String pkg1, @NonNull String pkg2);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     int checkUidSignatures(int uid1, int uid2);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate,
             @PackageManager.CertificateInputType int type);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean hasUidSigningCertificate(int uid, @NonNull byte[] certificate,
             @PackageManager.CertificateInputType int type);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     List<String> getAllPackages();
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     String getNameForUid(int uid);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     String[] getNamesForUids(@NonNull int[] uids);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     int getUidForSharedUser(@NonNull String sharedUserName);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     int getFlagsForUid(int uid);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     int getPrivateFlagsForUid(int uid);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean isUidPrivileged(int uid);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     String[] getAppOpPermissionPackages(@NonNull String permissionName);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(@NonNull String[] permissions,
             @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     List<ApplicationInfo> getInstalledApplications(
             @PackageManager.ApplicationInfoFlagsBits long flags, @UserIdInt int userId,
             int callingUid);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     ProviderInfo resolveContentProvider(@NonNull String name,
             @PackageManager.ResolveInfoFlagsBits long flags, @UserIdInt int userId, int callingUid);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     ProviderInfo getGrantImplicitAccessProviderInfo(int recipientUid,
             @NonNull String visibleAuthority);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     void querySyncProviders(boolean safeMode, @NonNull List<String> outNames,
             @NonNull List<ProviderInfo> outInfo);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable String processName, int uid,
             @PackageManager.ComponentInfoFlagsBits long flags, @Nullable String metaDataKey);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     ParceledListSlice<InstrumentationInfo> queryInstrumentation(
             @NonNull String targetPackage, int flags);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     List<PackageStateInternal> findSharedNonSystemLibraries(
             @NonNull PackageStateInternal pkgSetting);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean getApplicationHiddenSettingAsUser(@NonNull String packageName, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean isPackageSuspendedForUser(@NonNull String packageName, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean isSuspendingAnyPackages(@NonNull String suspendingPackage, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     ParceledListSlice<IntentFilter> getAllIntentFilters(@NonNull String packageName);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean getBlockUninstallForUser(@NonNull String packageName, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     SparseArray<int[]> getBroadcastAllowList(@NonNull String packageName, @UserIdInt int[] userIds,
             boolean isInstantApp);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     String getInstallerPackageName(@NonNull String packageName);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     InstallSourceInfo getInstallSourceInfo(@NonNull String packageName);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @PackageManager.EnabledState
     int getApplicationEnabledSetting(@NonNull String packageName, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @PackageManager.EnabledState
     int getComponentEnabledSetting(@NonNull ComponentName component, int callingUid,
             @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @PackageManager.EnabledState
     int getComponentEnabledSettingInternal(@NonNull ComponentName component, int callingUid,
             @UserIdInt int userId);
@@ -542,25 +465,19 @@
      * are all effectively enabled for the given component. Or if the component cannot be found,
      * returns false.
      */
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean isComponentEffectivelyEnabled(@NonNull ComponentInfo componentInfo,
             @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     KeySet getSigningKeySet(@NonNull String packageName);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean isPackageSignedByKeySet(@NonNull String packageName, @NonNull KeySet ks);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean isPackageSignedByKeySetExactly(@NonNull String packageName, @NonNull KeySet ks);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     int[] getVisibilityAllowList(@NonNull String packageName, @UserIdInt int userId);
 
@@ -570,49 +487,37 @@
      * package visibility filtering is enabled on it. If the UID is part of a shared user ID,
      * return {@code true} if any one application belongs to the shared user ID meets the criteria.
      */
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean canQueryPackage(int callingUid, @Nullable String targetPackageName);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     int getPackageUid(@NonNull String packageName, @PackageManager.PackageInfoFlagsBits long flags,
             @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean canAccessComponent(int callingUid, @NonNull ComponentName component,
             @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean isCallerInstallerOfRecord(@NonNull AndroidPackage pkg, int callingUid);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @PackageManager.InstallReason
     int getInstallReason(@NonNull String packageName, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean canPackageQuery(@NonNull String sourcePackageName, @NonNull String targetPackageName,
             @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean canForwardTo(@NonNull Intent intent, @Nullable String resolvedType,
             @UserIdInt int sourceUserId, @UserIdInt int targetUserId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     List<ApplicationInfo> getPersistentApplications(boolean safeMode, int flags);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     SparseArray<String> getAppsWithSharedUserIds();
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     String[] getSharedUserPackagesForPackage(@NonNull String packageName, @UserIdInt int userId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     Set<String> getUnusedPackages(long downgradeTimeThresholdMillis);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     CharSequence getHarmfulAppWarning(@NonNull String packageName, @UserIdInt int userId);
 
@@ -623,55 +528,49 @@
      *
      * @return The filtered packages
      */
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     String[] filterOnlySystemPackages(@Nullable String... pkgNames);
 
     // The methods in this block should be removed once SettingBase is interface snapshotted
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     List<AndroidPackage> getPackagesForAppId(int appId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     int getUidTargetSdkVersion(int uid);
 
     /**
      * @see PackageManagerInternal#getProcessesForUid(int)
      */
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     ArrayMap<String, ProcessInfo> getProcessesForUid(int uid);
     // End block
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean getBlockUninstall(@UserIdInt int userId, @NonNull String packageName);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>> getSharedLibraries();
 
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     Pair<PackageStateInternal, SharedUserApi> getPackageOrSharedUser(int appId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     SharedUserApi getSharedUser(int sharedUserAppIde);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     ArraySet<PackageStateInternal> getSharedUserPackages(int sharedUserAppId);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     ComponentResolverApi getComponentResolver();
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     PackageStateInternal getDisabledSystemPackage(@NonNull String packageName);
 
-    @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     ResolveInfo getInstantAppInstallerInfo();
+
+    @NonNull
+    WatchedArrayMap<String, Integer> getFrozenPackages();
+
+    @Nullable
+    ComponentName getInstantAppInstallerComponent();
 }
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 0c9855b..06e827a 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -466,7 +466,7 @@
 
         flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
                 comp != null || pkgName != null /*onlyExposedExplicitly*/,
-                isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
+                isImplicitImageCaptureIntentAndNotSetByDpc(intent, userId, resolvedType,
                         flags));
         List<ResolveInfo> list = Collections.emptyList();
         boolean skipPostResolution = false;
@@ -1722,15 +1722,6 @@
         return mSettings.getPackage(packageName);
     }
 
-    @Nullable
-    public PackageState getPackageStateCopied(@NonNull String packageName) {
-        int callingUid = Binder.getCallingUid();
-        packageName = resolveInternalPackageNameInternalLocked(
-                packageName, PackageManager.VERSION_CODE_HIGHEST, callingUid);
-        PackageStateInternal pkgSetting = mSettings.getPackage(packageName);
-        return pkgSetting == null ? null : PackageStateImpl.copy(pkgSetting);
-    }
-
     public final ParceledListSlice<PackageInfo> getInstalledPackages(long flags, int userId) {
         final int callingUid = Binder.getCallingUid();
         if (getInstantAppPackageName(callingUid) != null) {
@@ -2468,7 +2459,7 @@
      * @return {@code true} if the intent is a camera intent and the persistent preferred
      * activity was not set by the DPC.
      */
-    public final boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent,
+    public final boolean isImplicitImageCaptureIntentAndNotSetByDpc(Intent intent,
             int userId, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags) {
         return intent.isImplicitImageCaptureIntent() && !isPersistentPreferredActivitySetByDpm(
                 intent, userId, resolvedType, flags);
@@ -3228,12 +3219,12 @@
 
         flags = updateFlagsForResolve(
                 flags, userId, callingUid, false /*includeInstantApps*/,
-                isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
+                isImplicitImageCaptureIntentAndNotSetByDpc(intent, userId,
                         resolvedType, flags));
         intent = PackageManagerServiceUtils.updateIntentForResolve(intent);
 
         // Try to find a matching persistent preferred activity.
-        result.mPreferredResolveInfo = findPersistentPreferredActivityLP(intent,
+        result.mPreferredResolveInfo = findPersistentPreferredActivity(intent,
                 resolvedType, flags, query, debug, userId);
 
         // If a persistent preferred activity matched, use it.
@@ -3444,7 +3435,7 @@
                 userId, queryMayBeFiltered, callingUid, isDeviceProvisioned);
     }
 
-    public final ResolveInfo findPersistentPreferredActivityLP(Intent intent,
+    public final ResolveInfo findPersistentPreferredActivity(Intent intent,
             String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
             List<ResolveInfo> query, boolean debug, int userId) {
         final int n = query.size();
@@ -5418,7 +5409,7 @@
             }
             long flags = updateFlagsForResolve(0, parent.id, callingUid,
                     false /*includeInstantApps*/,
-                    isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, parent.id,
+                    isImplicitImageCaptureIntentAndNotSetByDpc(intent, parent.id,
                             resolvedType, 0));
             flags |= PackageManager.MATCH_DEFAULT_ONLY;
             CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
@@ -5694,4 +5685,17 @@
     public ResolveInfo getInstantAppInstallerInfo() {
         return mInstantAppInstallerInfo;
     }
+
+    @NonNull
+    @Override
+    public WatchedArrayMap<String, Integer> getFrozenPackages() {
+        return mFrozenPackages;
+    }
+
+    @Nullable
+    @Override
+    public ComponentName getInstantAppInstallerComponent() {
+        return mLocalInstantAppInstallerActivity == null
+                ? null : mLocalInstantAppInstallerActivity.getComponentName();
+    }
 }
diff --git a/services/core/java/com/android/server/pm/ComputerLocked.java b/services/core/java/com/android/server/pm/ComputerLocked.java
index 5d89c7d..af196d5 100644
--- a/services/core/java/com/android/server/pm/ComputerLocked.java
+++ b/services/core/java/com/android/server/pm/ComputerLocked.java
@@ -16,62 +16,21 @@
 
 package com.android.server.pm;
 
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UserIdInt;
 import android.content.ComponentName;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.ComponentInfo;
-import android.content.pm.InstallSourceInfo;
-import android.content.pm.InstrumentationInfo;
-import android.content.pm.KeySet;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ParceledListSlice;
-import android.content.pm.ProcessInfo;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.SigningDetails;
-import android.content.pm.VersionedPackage;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Pair;
-import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.pm.parsing.pkg.AndroidPackage;
-import com.android.server.pm.pkg.PackageState;
-import com.android.server.pm.pkg.PackageStateInternal;
-import com.android.server.pm.pkg.SharedUserApi;
-import com.android.server.pm.resolution.ComponentResolverApi;
-import com.android.server.utils.WatchedArrayMap;
-import com.android.server.utils.WatchedLongSparseArray;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
 
 /**
  * This subclass is the external interface to the live computer.  Some internal helper
- * methods are overridden to fetch live data instead of snapshot data.  For each
- * Computer interface that is overridden in this class, the override takes the PM lock
- * and then delegates to the live computer engine.  This is required because there are
- * no locks taken in the engine itself.
+ * methods are overridden to fetch live data instead of snapshot data.
  */
 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
 public final class ComputerLocked extends ComputerEngine {
-    private final Object mLock;
 
     ComputerLocked(PackageManagerService.Snapshot args) {
         super(args);
-        mLock = mService.mLock;
     }
 
     protected ComponentName resolveComponentName() {
@@ -83,814 +42,4 @@
     protected ApplicationInfo androidApplication() {
         return mService.getCoreAndroidApplication();
     }
-
-    public @NonNull List<ResolveInfo> queryIntentServicesInternalBody(Intent intent,
-            String resolvedType, int flags, int userId, int callingUid,
-            String instantAppPkgName) {
-        synchronized (mLock) {
-            return super.queryIntentServicesInternalBody(intent, resolvedType, flags, userId,
-                    callingUid, instantAppPkgName);
-        }
-    }
-    public @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
-            Intent intent, String resolvedType, long flags, int filterCallingUid, int userId,
-            boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
-            String instantAppPkgName) {
-        synchronized (mLock) {
-            return super.queryIntentActivitiesInternalBody(intent, resolvedType, flags,
-                    filterCallingUid, userId, resolveForStart, allowDynamicSplits, pkgName,
-                    instantAppPkgName);
-        }
-    }
-    public ActivityInfo getActivityInfoInternalBody(ComponentName component, int flags,
-            int filterCallingUid, int userId) {
-        synchronized (mLock) {
-            return super.getActivityInfoInternalBody(component, flags, filterCallingUid,
-                    userId);
-        }
-    }
-    public AndroidPackage getPackage(String packageName) {
-        synchronized (mLock) {
-            return super.getPackage(packageName);
-        }
-    }
-    public AndroidPackage getPackage(int uid) {
-        synchronized (mLock) {
-            return super.getPackage(uid);
-        }
-    }
-    public ApplicationInfo getApplicationInfoInternalBody(String packageName, int flags,
-            int filterCallingUid, int userId) {
-        synchronized (mLock) {
-            return super.getApplicationInfoInternalBody(packageName, flags, filterCallingUid,
-                    userId);
-        }
-    }
-    public ArrayList<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPrBody(
-            Intent intent, int matchFlags, List<ResolveInfo> candidates,
-            CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug) {
-        synchronized (mLock) {
-            return super.filterCandidatesWithDomainPreferredActivitiesLPrBody(intent,
-                    matchFlags, candidates, xpDomainInfo, userId, debug);
-        }
-    }
-    public PackageInfo getPackageInfoInternalBody(String packageName, long versionCode,
-            int flags, int filterCallingUid, int userId) {
-        synchronized (mLock) {
-            return super.getPackageInfoInternalBody(packageName, versionCode, flags,
-                    filterCallingUid, userId);
-        }
-    }
-
-    @Override
-    public String[] getAllAvailablePackageNames() {
-        synchronized (mLock) {
-            return super.getAllAvailablePackageNames();
-        }
-    }
-
-    public PackageStateInternal getPackageStateInternal(String packageName, int callingUid) {
-        synchronized (mLock) {
-            return super.getPackageStateInternal(packageName, callingUid);
-        }
-    }
-
-    @Nullable
-    public PackageState getPackageStateCopied(@NonNull String packageName) {
-        synchronized (mLock) {
-            return super.getPackageStateCopied(packageName);
-        }
-    }
-
-    public ParceledListSlice<PackageInfo> getInstalledPackagesBody(int flags, int userId,
-            int callingUid) {
-        synchronized (mLock) {
-            return super.getInstalledPackagesBody(flags, userId, callingUid);
-        }
-    }
-    public ServiceInfo getServiceInfoBody(ComponentName component, int flags, int userId,
-            int callingUid) {
-        synchronized (mLock) {
-            return super.getServiceInfoBody(component, flags, userId, callingUid);
-        }
-    }
-    public String getInstantAppPackageName(int callingUid) {
-        synchronized (mLock) {
-            return super.getInstantAppPackageName(callingUid);
-        }
-    }
-    public String[] getPackagesForUidInternalBody(int callingUid, int userId, int appId,
-            boolean isCallerInstantApp) {
-        synchronized (mLock) {
-            return super.getPackagesForUidInternalBody(callingUid, userId, appId,
-                    isCallerInstantApp);
-        }
-    }
-    public boolean isInstantAppInternalBody(String packageName, @UserIdInt int userId,
-            int callingUid) {
-        synchronized (mLock) {
-            return super.isInstantAppInternalBody(packageName, userId, callingUid);
-        }
-    }
-    public boolean isInstantAppResolutionAllowedBody(Intent intent,
-            List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck,
-            int flags) {
-        synchronized (mLock) {
-            return super.isInstantAppResolutionAllowedBody(intent, resolvedActivities, userId,
-                    skipPackageCheck, flags);
-        }
-    }
-    public int getPackageUidInternal(String packageName, int flags, int userId,
-            int callingUid) {
-        synchronized (mLock) {
-            return super.getPackageUidInternal(packageName, flags, userId, callingUid);
-        }
-    }
-    public SigningDetails getSigningDetails(@NonNull String packageName) {
-        synchronized (mLock) {
-            return super.getSigningDetails(packageName);
-        }
-    }
-    public SigningDetails getSigningDetails(int uid) {
-        synchronized (mLock) {
-            return super.getSigningDetails(uid);
-        }
-    }
-    public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
-        synchronized (mLock) {
-            return super.filterAppAccess(pkg, callingUid, userId);
-        }
-    }
-    public boolean filterAppAccess(String packageName, int callingUid, int userId) {
-        synchronized (mLock) {
-            return super.filterAppAccess(packageName, callingUid, userId);
-        }
-    }
-    public boolean filterAppAccess(int uid, int callingUid) {
-        synchronized (mLock) {
-            return super.filterAppAccess(uid, callingUid);
-        }
-    }
-    public void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
-        synchronized (mLock) {
-            super.dump(type, fd, pw, dumpState);
-        }
-    }
-    public PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityBody(
-            Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean always,
-            boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered,
-            int callingUid, boolean isDeviceProvisioned) {
-        synchronized (mLock) {
-            return super.findPreferredActivityBody(intent, resolvedType, flags, query, always,
-                    removeMatches, debug, userId, queryMayBeFiltered, callingUid,
-                    isDeviceProvisioned);
-        }
-    }
-
-    @Override
-    public PreferredIntentResolver getPreferredActivities(int userId) {
-        synchronized (mLock) {
-            return super.getPreferredActivities(userId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ArrayMap<String, ? extends PackageStateInternal> getPackageStates() {
-        synchronized (mLock) {
-            return super.getPackageStates();
-        }
-    }
-
-    @Nullable
-    @Override
-    public String getRenamedPackage(@NonNull String packageName) {
-        synchronized (mLock) {
-            return super.getRenamedPackage(packageName);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ArraySet<String> getNotifyPackagesForReplacedReceived(@NonNull String[] packages) {
-        synchronized (mLock) {
-            return super.getNotifyPackagesForReplacedReceived(packages);
-        }
-    }
-
-    @Override
-    public int getPackageStartability(boolean safeMode, @NonNull String packageName, int callingUid,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getPackageStartability(safeMode, packageName, callingUid, userId);
-        }
-    }
-
-    @Override
-    public boolean isPackageAvailable(String packageName, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.isPackageAvailable(packageName, userId);
-        }
-    }
-
-    @Override
-    public String[] currentToCanonicalPackageNames(String[] names) {
-        synchronized (mLock) {
-            return super.currentToCanonicalPackageNames(names);
-        }
-    }
-
-    @Override
-    public String[] canonicalToCurrentPackageNames(String[] names) {
-        synchronized (mLock) {
-            return super.canonicalToCurrentPackageNames(names);
-        }
-    }
-
-    @Override
-    public int[] getPackageGids(@NonNull String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getPackageGids(packageName, flags, userId);
-        }
-    }
-
-    @Override
-    public int getTargetSdkVersion(@NonNull String packageName) {
-        synchronized (mLock) {
-            return super.getTargetSdkVersion(packageName);
-        }
-    }
-
-    @Override
-    public boolean activitySupportsIntent(@NonNull ComponentName resolveComponentName,
-            @NonNull ComponentName component, @NonNull Intent intent, String resolvedType) {
-        synchronized (mLock) {
-            return super.activitySupportsIntent(resolveComponentName, component, intent,
-                    resolvedType);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ActivityInfo getReceiverInfo(@NonNull ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getReceiverInfo(component, flags, userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(@NonNull String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getSharedLibraries(packageName, flags, userId);
-        }
-    }
-
-    @Override
-    public boolean canRequestPackageInstalls(@NonNull String packageName, int callingUid,
-            @UserIdInt int userId, boolean throwIfPermNotDeclared) {
-        synchronized (mLock) {
-            return super.canRequestPackageInstalls(packageName, callingUid, userId,
-                    throwIfPermNotDeclared);
-        }
-    }
-
-    @Override
-    public List<VersionedPackage> getPackagesUsingSharedLibrary(@NonNull SharedLibraryInfo libInfo,
-            @PackageManager.PackageInfoFlagsBits long flags, int callingUid,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getPackagesUsingSharedLibrary(libInfo, flags, callingUid, userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
-            @NonNull String packageName, @PackageManager.PackageInfoFlagsBits long flags,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getDeclaredSharedLibraries(packageName, flags, userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ProviderInfo getProviderInfo(@NonNull ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getProviderInfo(component, flags, userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public String[] getSystemSharedLibraryNames() {
-        synchronized (mLock) {
-            return super.getSystemSharedLibraryNames();
-        }
-    }
-
-    @Override
-    public int checkSignatures(@NonNull String pkg1,
-            @NonNull String pkg2) {
-        synchronized (mLock) {
-            return super.checkSignatures(pkg1, pkg2);
-        }
-    }
-
-    @Override
-    public int checkUidSignatures(int uid1, int uid2) {
-        synchronized (mLock) {
-            return super.checkUidSignatures(uid1, uid2);
-        }
-    }
-
-    @Override
-    public boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate,
-            int type) {
-        synchronized (mLock) {
-            return super.hasSigningCertificate(packageName, certificate, type);
-        }
-    }
-
-    @Override
-    public boolean hasUidSigningCertificate(int uid, @NonNull byte[] certificate, int type) {
-        synchronized (mLock) {
-            return super.hasUidSigningCertificate(uid, certificate, type);
-        }
-    }
-
-    @Override
-    public List<String> getAllPackages() {
-        synchronized (mLock) {
-            return super.getAllPackages();
-        }
-    }
-
-    @Nullable
-    @Override
-    public String getNameForUid(int uid) {
-        synchronized (mLock) {
-            return super.getNameForUid(uid);
-        }
-    }
-
-    @Nullable
-    @Override
-    public String[] getNamesForUids(int[] uids) {
-        synchronized (mLock) {
-            return super.getNamesForUids(uids);
-        }
-    }
-
-    @Override
-    public int getUidForSharedUser(@NonNull String sharedUserName) {
-        synchronized (mLock) {
-            return super.getUidForSharedUser(sharedUserName);
-        }
-    }
-
-    @Override
-    public int getFlagsForUid(int uid) {
-        synchronized (mLock) {
-            return super.getFlagsForUid(uid);
-        }
-    }
-
-    @Override
-    public int getPrivateFlagsForUid(int uid) {
-        synchronized (mLock) {
-            return super.getPrivateFlagsForUid(uid);
-        }
-    }
-
-    @Override
-    public boolean isUidPrivileged(int uid) {
-        synchronized (mLock) {
-            return super.isUidPrivileged(uid);
-        }
-    }
-
-    @NonNull
-    @Override
-    public String[] getAppOpPermissionPackages(@NonNull String permissionName) {
-        synchronized (mLock) {
-            return super.getAppOpPermissionPackages(permissionName);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
-            @NonNull String[] permissions, @PackageManager.PackageInfoFlagsBits long flags,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getPackagesHoldingPermissions(permissions, flags, userId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public List<ApplicationInfo> getInstalledApplications(
-            @PackageManager.ApplicationInfoFlagsBits long flags, @UserIdInt int userId,
-            int callingUid) {
-        synchronized (mLock) {
-            return super.getInstalledApplications(flags, userId, callingUid);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ProviderInfo resolveContentProvider(@NonNull String name,
-            @PackageManager.ResolveInfoFlagsBits long flags, @UserIdInt int userId,
-            int callingUid) {
-        synchronized (mLock) {
-            return super.resolveContentProvider(name, flags, userId, callingUid);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ProviderInfo getGrantImplicitAccessProviderInfo(int recipientUid,
-            @NonNull String visibleAuthority) {
-        synchronized (mLock) {
-            return super.getGrantImplicitAccessProviderInfo(recipientUid, visibleAuthority);
-        }
-    }
-
-    @Override
-    public void querySyncProviders(boolean safeMode, @NonNull List<String> outNames,
-            @NonNull List<ProviderInfo> outInfo) {
-        synchronized (mLock) {
-            super.querySyncProviders(safeMode, outNames, outInfo);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable String processName,
-            int uid, @PackageManager.ComponentInfoFlagsBits long flags,
-            @Nullable String metaDataKey) {
-        synchronized (mLock) {
-            return super.queryContentProviders(processName, uid, flags, metaDataKey);
-        }
-    }
-
-    @Nullable
-    @Override
-    public InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags) {
-        synchronized (mLock) {
-            return super.getInstrumentationInfo(component, flags);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ParceledListSlice<InstrumentationInfo> queryInstrumentation(
-            @NonNull String targetPackage, int flags) {
-        synchronized (mLock) {
-            return super.queryInstrumentation(targetPackage, flags);
-        }
-    }
-
-    @NonNull
-    @Override
-    public List<PackageStateInternal> findSharedNonSystemLibraries(
-            @NonNull PackageStateInternal pkgSetting) {
-        synchronized (mLock) {
-            return super.findSharedNonSystemLibraries(pkgSetting);
-        }
-    }
-
-    @Override
-    public boolean getApplicationHiddenSettingAsUser(@NonNull String packageName,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getApplicationHiddenSettingAsUser(packageName, userId);
-        }
-    }
-
-    @Override
-    public boolean isPackageSuspendedForUser(@NonNull String packageName, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.isPackageSuspendedForUser(packageName, userId);
-        }
-    }
-
-    @Override
-    public boolean isSuspendingAnyPackages(@NonNull String suspendingPackage,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.isSuspendingAnyPackages(suspendingPackage, userId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ParceledListSlice<IntentFilter> getAllIntentFilters(@NonNull String packageName) {
-        synchronized (mLock) {
-            return super.getAllIntentFilters(packageName);
-        }
-    }
-
-    @Override
-    public boolean getBlockUninstallForUser(@NonNull String packageName, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getBlockUninstallForUser(packageName, userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public SparseArray<int[]> getBroadcastAllowList(@NonNull String packageName,
-            @UserIdInt int[] userIds, boolean isInstantApp) {
-        synchronized (mLock) {
-            return super.getBroadcastAllowList(packageName, userIds, isInstantApp);
-        }
-    }
-
-    @Nullable
-    @Override
-    public String getInstallerPackageName(@NonNull String packageName) {
-        synchronized (mLock) {
-            return super.getInstallerPackageName(packageName);
-        }
-    }
-
-    @Nullable
-    @Override
-    public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName) {
-        synchronized (mLock) {
-            return super.getInstallSourceInfo(packageName);
-        }
-    }
-
-    @Override
-    public int getApplicationEnabledSetting(@NonNull String packageName, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getApplicationEnabledSetting(packageName, userId);
-        }
-    }
-
-    @Override
-    public int getComponentEnabledSetting(@NonNull ComponentName component, int callingUid,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getComponentEnabledSetting(component, callingUid, userId);
-        }
-    }
-
-    @Override
-    public int getComponentEnabledSettingInternal(@NonNull ComponentName component, int callingUid,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getComponentEnabledSettingInternal(component, callingUid, userId);
-        }
-    }
-
-    @Override
-    public boolean isComponentEffectivelyEnabled(@NonNull ComponentInfo componentInfo,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.isComponentEffectivelyEnabled(componentInfo, userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias) {
-        synchronized (mLock) {
-            return super.getKeySetByAlias(packageName, alias);
-        }
-    }
-
-    @Nullable
-    @Override
-    public KeySet getSigningKeySet(@NonNull String packageName) {
-        synchronized (mLock) {
-            return super.getSigningKeySet(packageName);
-        }
-    }
-
-    @Override
-    public boolean isPackageSignedByKeySet(@NonNull String packageName, @NonNull KeySet ks) {
-        synchronized (mLock) {
-            return super.isPackageSignedByKeySet(packageName, ks);
-        }
-    }
-
-    @Override
-    public boolean isPackageSignedByKeySetExactly(@NonNull String packageName, @NonNull KeySet ks) {
-        synchronized (mLock) {
-            return super.isPackageSignedByKeySetExactly(packageName, ks);
-        }
-    }
-
-    @Nullable
-    @Override
-    public int[] getVisibilityAllowList(@NonNull String packageName, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getVisibilityAllowList(packageName, userId);
-        }
-    }
-
-    @Override
-    public boolean canQueryPackage(int callingUid, @Nullable String targetPackageName) {
-        synchronized (mLock) {
-            return super.canQueryPackage(callingUid, targetPackageName);
-        }
-    }
-
-    @Override
-    public int getPackageUid(@NonNull String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getPackageUid(packageName, flags, userId);
-        }
-    }
-
-    @Override
-    public boolean canAccessComponent(int callingUid, @NonNull ComponentName component,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.canAccessComponent(callingUid, component, userId);
-        }
-    }
-
-    @Override
-    public boolean isCallerInstallerOfRecord(@NonNull AndroidPackage pkg, int callingUid) {
-        synchronized (mLock) {
-            return super.isCallerInstallerOfRecord(pkg, callingUid);
-        }
-    }
-
-    @Override
-    public int getInstallReason(@NonNull String packageName, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getInstallReason(packageName, userId);
-        }
-    }
-
-    @Override
-    public boolean canPackageQuery(@NonNull String sourcePackageName,
-            @NonNull String targetPackageName, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.canPackageQuery(sourcePackageName, targetPackageName, userId);
-        }
-    }
-
-    @Override
-    public boolean canForwardTo(@NonNull Intent intent, @Nullable String resolvedType,
-            @UserIdInt int sourceUserId, @UserIdInt int targetUserId) {
-        synchronized (mLock) {
-            return super.canForwardTo(intent, resolvedType, sourceUserId, targetUserId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public List<ApplicationInfo> getPersistentApplications(boolean safeMode, int flags) {
-        synchronized (mLock) {
-            return super.getPersistentApplications(safeMode, flags);
-        }
-    }
-
-    @NonNull
-    @Override
-    public SparseArray<String> getAppsWithSharedUserIds() {
-        synchronized (mLock) {
-            return super.getAppsWithSharedUserIds();
-        }
-    }
-
-    @NonNull
-    @Override
-    public String[] getSharedUserPackagesForPackage(@NonNull String packageName,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getSharedUserPackagesForPackage(packageName, userId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
-        synchronized (mLock) {
-            return super.getUnusedPackages(downgradeTimeThresholdMillis);
-        }
-    }
-
-    @Nullable
-    @Override
-    public CharSequence getHarmfulAppWarning(@NonNull String packageName, @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getHarmfulAppWarning(packageName, userId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public String[] filterOnlySystemPackages(@Nullable String... pkgNames) {
-        synchronized (mLock) {
-            return super.filterOnlySystemPackages(pkgNames);
-        }
-    }
-
-    @NonNull
-    @Override
-    public List<AndroidPackage> getPackagesForAppId(int appId) {
-        synchronized (mLock) {
-            return super.getPackagesForAppId(appId);
-        }
-    }
-
-    @Override
-    public int getUidTargetSdkVersion(int uid) {
-        synchronized (mLock) {
-            return super.getUidTargetSdkVersion(uid);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ArrayMap<String, ProcessInfo> getProcessesForUid(int uid) {
-        synchronized (mLock) {
-            return super.getProcessesForUid(uid);
-        }
-    }
-
-    @Override
-    public PackageStateInternal getPackageStateFiltered(@NonNull String packageName, int callingUid,
-            @UserIdInt int userId) {
-        synchronized (mLock) {
-            return super.getPackageStateFiltered(packageName, callingUid, userId);
-        }
-    }
-
-    @Override
-    public boolean getBlockUninstall(@UserIdInt int userId, @NonNull String packageName) {
-        synchronized (mLock) {
-            return super.getBlockUninstall(userId, packageName);
-        }
-    }
-
-    @NonNull
-    @Override
-    public WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>> getSharedLibraries() {
-        synchronized (mLock) {
-            return super.getSharedLibraries();
-        }
-    }
-
-    @Nullable
-    @Override
-    public Pair<PackageStateInternal, SharedUserApi> getPackageOrSharedUser(int appId) {
-        synchronized (mLock) {
-            return super.getPackageOrSharedUser(appId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public SharedUserApi getSharedUser(int sharedUserAppId) {
-        synchronized (mLock) {
-            return super.getSharedUser(sharedUserAppId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ArraySet<PackageStateInternal> getSharedUserPackages(int sharedUserAppId) {
-        synchronized (mLock) {
-            return super.getSharedUserPackages(sharedUserAppId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ComponentResolverApi getComponentResolver() {
-        synchronized (mLock) {
-            return super.getComponentResolver();
-        }
-    }
-
-    @Nullable
-    @Override
-    public PackageStateInternal getDisabledSystemPackage(@NonNull String packageName) {
-        synchronized (mLock) {
-            return super.getDisabledSystemPackage(packageName);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ResolveInfo getInstantAppInstallerInfo() {
-        synchronized (mLock) {
-            return super.getInstantAppInstallerInfo();
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/pm/ComputerTracker.java b/services/core/java/com/android/server/pm/ComputerTracker.java
deleted file mode 100644
index 216ad71..0000000
--- a/services/core/java/com/android/server/pm/ComputerTracker.java
+++ /dev/null
@@ -1,1327 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UserIdInt;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ComponentInfo;
-import android.content.pm.InstallSourceInfo;
-import android.content.pm.InstrumentationInfo;
-import android.content.pm.KeySet;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
-import android.content.pm.ParceledListSlice;
-import android.content.pm.ProcessInfo;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.SigningDetails;
-import android.content.pm.UserInfo;
-import android.content.pm.VersionedPackage;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.server.pm.parsing.pkg.AndroidPackage;
-import com.android.server.pm.pkg.PackageState;
-import com.android.server.pm.pkg.PackageStateInternal;
-import com.android.server.pm.pkg.SharedUserApi;
-import com.android.server.pm.resolution.ComponentResolverApi;
-import com.android.server.utils.WatchedArrayMap;
-import com.android.server.utils.WatchedLongSparseArray;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * This subclass delegates to methods in a Computer after reference-counting the computer.
- */
-public final class ComputerTracker implements Computer {
-
-    // The number of times a thread reused a computer in its stack instead of fetching
-    // a snapshot computer.
-    private final AtomicInteger mReusedSnapshot = new AtomicInteger(0);
-
-    private final PackageManagerService mService;
-    ComputerTracker(PackageManagerService s) {
-        mService = s;
-    }
-
-    private ThreadComputer snapshot() {
-        ThreadComputer current = PackageManagerService.sThreadComputer.get();
-        if (current.mRefCount > 0) {
-            current.acquire();
-            mReusedSnapshot.incrementAndGet();
-        } else {
-            current.acquire(mService.snapshotComputer());
-        }
-        return current;
-    }
-
-    public @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
-            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags,
-            int filterCallingUid, int userId, boolean resolveForStart,
-            boolean allowDynamicSplits) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.queryIntentActivitiesInternal(intent, resolvedType, flags,
-                    privateResolveFlags, filterCallingUid, userId, resolveForStart,
-                    allowDynamicSplits);
-        } finally {
-            current.release();
-        }
-    }
-    public @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.queryIntentActivitiesInternal(intent, resolvedType, flags,
-                    userId);
-        } finally {
-            current.release();
-        }
-    }
-    public @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId,
-            int callingUid, boolean includeInstantApps) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.queryIntentServicesInternal(intent, resolvedType, flags,
-                    userId, callingUid, includeInstantApps);
-        } finally {
-            current.release();
-        }
-    }
-    public @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
-            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
-            int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits,
-            String pkgName, String instantAppPkgName) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.queryIntentActivitiesInternalBody(intent, resolvedType,
-                    flags, filterCallingUid, userId, resolveForStart, allowDynamicSplits,
-                    pkgName, instantAppPkgName);
-        } finally {
-            current.release();
-        }
-    }
-    public ActivityInfo getActivityInfo(ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getActivityInfo(component, flags, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public ActivityInfo getActivityInfoInternal(ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags,
-            int filterCallingUid, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getActivityInfoInternal(component, flags, filterCallingUid,
-                    userId);
-        } finally {
-            current.release();
-        }
-    }
-    public AndroidPackage getPackage(String packageName) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getPackage(packageName);
-        } finally {
-            current.release();
-        }
-    }
-    public AndroidPackage getPackage(int uid) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getPackage(uid);
-        } finally {
-            current.release();
-        }
-    }
-    public ApplicationInfo generateApplicationInfoFromSettings(String packageName,
-            long flags, int filterCallingUid, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.generateApplicationInfoFromSettings(packageName, flags,
-                    filterCallingUid, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public ApplicationInfo getApplicationInfo(String packageName,
-            @PackageManager.ApplicationInfoFlagsBits long flags, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getApplicationInfo(packageName, flags, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public ApplicationInfo getApplicationInfoInternal(String packageName,
-            @PackageManager.ApplicationInfoFlagsBits long flags, int filterCallingUid, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getApplicationInfoInternal(packageName, flags,
-                    filterCallingUid, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public ComponentName getDefaultHomeActivity(int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getDefaultHomeActivity(userId);
-        } finally {
-            current.release();
-        }
-    }
-    public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
-            int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getHomeActivitiesAsUser(allHomeCandidates, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int sourceUserId,
-            int parentUserId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getCrossProfileDomainPreferredLpr(intent, resolvedType,
-                    flags, sourceUserId, parentUserId);
-        } finally {
-            current.release();
-        }
-    }
-    public Intent getHomeIntent() {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getHomeIntent();
-        } finally {
-            current.release();
-        }
-    }
-    public List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(
-            Intent intent, String resolvedType, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getMatchingCrossProfileIntentFilters(intent, resolvedType,
-                    userId);
-        } finally {
-            current.release();
-        }
-    }
-    public List<ResolveInfo> applyPostResolutionFilter(
-            @NonNull List<ResolveInfo> resolveInfos,
-            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
-            boolean resolveForStart, int userId, Intent intent) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.applyPostResolutionFilter(resolveInfos, ephemeralPkgName,
-                    allowDynamicSplits, filterCallingUid, resolveForStart, userId, intent);
-        } finally {
-            current.release();
-        }
-    }
-    public PackageInfo generatePackageInfo(PackageStateInternal ps,
-            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.generatePackageInfo(ps, flags, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public PackageInfo getPackageInfo(String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getPackageInfo(packageName, flags, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public PackageInfo getPackageInfoInternal(String packageName, long versionCode,
-            long flags, int filterCallingUid, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getPackageInfoInternal(packageName, versionCode, flags,
-                    filterCallingUid, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public PackageStateInternal getPackageStateInternal(String packageName) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getPackageStateInternal(packageName);
-        } finally {
-            current.release();
-        }
-    }
-    public PackageStateInternal getPackageStateInternal(String packageName, int callingUid) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getPackageStateInternal(packageName, callingUid);
-        } finally {
-            current.release();
-        }
-    }
-
-    @Nullable
-    public PackageState getPackageStateCopied(@NonNull String packageName) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getPackageStateCopied(packageName);
-        } finally {
-            current.release();
-        }
-    }
-
-    public ParceledListSlice<PackageInfo> getInstalledPackages(long flags, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getInstalledPackages(flags, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
-            int sourceUserId, int targetUserId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.createForwardingResolveInfoUnchecked(filter, sourceUserId,
-                    targetUserId);
-        } finally {
-            current.release();
-        }
-    }
-    public ServiceInfo getServiceInfo(ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getServiceInfo(component, flags, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public SharedLibraryInfo getSharedLibraryInfo(String name, long version) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getSharedLibraryInfo(name, version);
-        } finally {
-            current.release();
-        }
-    }
-    public SigningDetails getSigningDetails(@NonNull String packageName) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getSigningDetails(packageName);
-        } finally {
-            current.release();
-        }
-    }
-    public SigningDetails getSigningDetails(int uid) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getSigningDetails(uid);
-        } finally {
-            current.release();
-        }
-    }
-    public String getInstantAppPackageName(int callingUid) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getInstantAppPackageName(callingUid);
-        } finally {
-            current.release();
-        }
-    }
-    public String resolveExternalPackageName(AndroidPackage pkg) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.resolveExternalPackageName(pkg);
-        } finally {
-            current.release();
-        }
-    }
-    public String resolveInternalPackageName(String packageName, long versionCode) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.resolveInternalPackageName(packageName, versionCode);
-        } finally {
-            current.release();
-        }
-    }
-    public String[] getPackagesForUid(int uid) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getPackagesForUid(uid);
-        } finally {
-            current.release();
-        }
-    }
-    public UserInfo getProfileParent(int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getProfileParent(userId);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean canViewInstantApps(int callingUid, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.canViewInstantApps(callingUid, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.filterAppAccess(pkg, callingUid, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean filterAppAccess(String packageName, int callingUid, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.filterAppAccess(packageName, callingUid, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean filterAppAccess(int uid, int callingUid) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.filterAppAccess(uid, callingUid);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean filterSharedLibPackage(@Nullable PackageStateInternal ps, int uid,
-            int userId, @PackageManager.ComponentInfoFlagsBits long flags) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.filterSharedLibPackage(ps, uid, userId, flags);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean isCallerSameApp(String packageName, int uid) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.isCallerSameApp(packageName, uid);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.isComponentVisibleToInstantApp(component);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean isComponentVisibleToInstantApp(@Nullable ComponentName component,
-            @PackageManager.ComponentType int type) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.isComponentVisibleToInstantApp(component, type);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent,
-            int userId, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent,
-                    userId, resolvedType, flags);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean isInstantApp(String packageName, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.isInstantApp(packageName, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
-            int callingUid) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.isInstantAppInternal(packageName, userId, callingUid);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean isSameProfileGroup(@UserIdInt int callerUserId,
-            @UserIdInt int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.isSameProfileGroup(callerUserId, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean shouldFilterApplication(@NonNull SharedUserSetting sus,
-            int callingUid, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.shouldFilterApplication(sus, callingUid, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean shouldFilterApplication(@Nullable PackageStateInternal ps,
-            int callingUid, @Nullable ComponentName component,
-            @PackageManager.ComponentType int componentType, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.shouldFilterApplication(ps, callingUid, component,
-                    componentType, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public boolean shouldFilterApplication(@Nullable PackageStateInternal ps,
-            int callingUid, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.shouldFilterApplication(ps, callingUid, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public int checkUidPermission(String permName, int uid) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.checkUidPermission(permName, uid);
-        } finally {
-            current.release();
-        }
-    }
-    public int getPackageUidInternal(String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, int userId, int callingUid) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.getPackageUidInternal(packageName, flags, userId,
-                    callingUid);
-        } finally {
-            current.release();
-        }
-    }
-    public long updateFlagsForApplication(long flags, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.updateFlagsForApplication(flags, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public long updateFlagsForComponent(long flags, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.updateFlagsForComponent(flags, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public long updateFlagsForPackage(long flags, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.updateFlagsForPackage(flags, userId);
-        } finally {
-            current.release();
-        }
-    }
-    public long updateFlagsForResolve(long flags, int userId, int callingUid,
-            boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.updateFlagsForResolve(flags, userId, callingUid,
-                    wantInstantApps, isImplicitImageCaptureIntentAndNotSetByDpc);
-        } finally {
-            current.release();
-        }
-    }
-    public long updateFlagsForResolve(long flags, int userId, int callingUid,
-            boolean wantInstantApps, boolean onlyExposedExplicitly,
-            boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.updateFlagsForResolve(flags, userId, callingUid,
-                    wantInstantApps, onlyExposedExplicitly,
-                    isImplicitImageCaptureIntentAndNotSetByDpc);
-        } finally {
-            current.release();
-        }
-    }
-    public void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
-        ThreadComputer current = snapshot();
-        try {
-            current.mComputer.dump(type, fd, pw, dumpState);
-        } finally {
-            current.release();
-        }
-    }
-    public void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
-            boolean requireFullPermission, boolean checkShell, String message) {
-        ThreadComputer current = snapshot();
-        try {
-            current.mComputer.enforceCrossUserOrProfilePermission(callingUid, userId,
-                    requireFullPermission, checkShell, message);
-        } finally {
-            current.release();
-        }
-    }
-    public void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
-            boolean requireFullPermission, boolean checkShell, String message) {
-        ThreadComputer current = snapshot();
-        try {
-            current.mComputer.enforceCrossUserPermission(callingUid, userId,
-                    requireFullPermission, checkShell, message);
-        } finally {
-            current.release();
-        }
-    }
-    public void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
-            boolean requireFullPermission, boolean checkShell,
-            boolean requirePermissionWhenSameUser, String message) {
-        ThreadComputer current = snapshot();
-        try {
-            current.mComputer.enforceCrossUserPermission(callingUid, userId,
-                    requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
-        } finally {
-            current.release();
-        }
-    }
-    public PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityInternal(
-            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
-            List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug,
-            int userId, boolean queryMayBeFiltered) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.findPreferredActivityInternal(intent, resolvedType, flags,
-                    query, always, removeMatches, debug, userId, queryMayBeFiltered);
-        } finally {
-            current.release();
-        }
-    }
-    public ResolveInfo findPersistentPreferredActivityLP(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
-            List<ResolveInfo> query, boolean debug, int userId) {
-        ThreadComputer current = snapshot();
-        try {
-            return current.mComputer.findPersistentPreferredActivityLP(intent, resolvedType,
-                    flags, query, debug, userId);
-        } finally {
-            current.release();
-        }
-    }
-
-    @Override
-    public String[] getAllAvailablePackageNames() {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getAllAvailablePackageNames();
-        }
-    }
-
-    @Override
-    public PreferredIntentResolver getPreferredActivities(int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPreferredActivities(userId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ArrayMap<String, ? extends PackageStateInternal> getPackageStates() {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPackageStates();
-        }
-    }
-
-    @Nullable
-    @Override
-    public String getRenamedPackage(@NonNull String packageName) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getRenamedPackage(packageName);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ArraySet<String> getNotifyPackagesForReplacedReceived(@NonNull String[] packages) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getNotifyPackagesForReplacedReceived(packages);
-        }
-    }
-
-    @Override
-    public int getPackageStartability(boolean safeMode, @NonNull String packageName, int callingUid,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPackageStartability(safeMode, packageName, callingUid,
-                    userId);
-        }
-    }
-
-    @Override
-    public boolean isPackageAvailable(String packageName, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.isPackageAvailable(packageName, userId);
-        }
-    }
-
-    @Override
-    public String[] currentToCanonicalPackageNames(String[] names) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.currentToCanonicalPackageNames(names);
-        }
-    }
-
-    @Override
-    public String[] canonicalToCurrentPackageNames(String[] names) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.canonicalToCurrentPackageNames(names);
-        }
-    }
-
-    @Override
-    public int[] getPackageGids(@NonNull String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPackageGids(packageName, flags, userId);
-        }
-    }
-
-    @Override
-    public int getTargetSdkVersion(@NonNull String packageName) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getTargetSdkVersion(packageName);
-        }
-    }
-
-    @Override
-    public boolean activitySupportsIntent(@NonNull ComponentName resolveComponentName,
-            @NonNull ComponentName component, @NonNull Intent intent, String resolvedType) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.activitySupportsIntent(resolveComponentName, component, intent,
-                    resolvedType);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ActivityInfo getReceiverInfo(@NonNull ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getReceiverInfo(component, flags, userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(@NonNull String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getSharedLibraries(packageName, flags, userId);
-        }
-    }
-
-    @Override
-    public boolean canRequestPackageInstalls(@NonNull String packageName, int callingUid,
-            @UserIdInt int userId, boolean throwIfPermNotDeclared) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.canRequestPackageInstalls(packageName, callingUid, userId,
-                    throwIfPermNotDeclared);
-        }
-    }
-
-    @Override
-    public boolean isInstallDisabledForPackage(@NonNull String packageName, int uid,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.isInstallDisabledForPackage(packageName, uid, userId);
-        }
-    }
-
-    @Override
-    public List<VersionedPackage> getPackagesUsingSharedLibrary(@NonNull SharedLibraryInfo libInfo,
-            @PackageManager.PackageInfoFlagsBits long flags, int callingUid,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPackagesUsingSharedLibrary(libInfo, flags, callingUid,
-                    userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
-            @NonNull String packageName, @PackageManager.PackageInfoFlagsBits long flags,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getDeclaredSharedLibraries(packageName, flags, userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ProviderInfo getProviderInfo(@NonNull ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getProviderInfo(component, flags, userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public String[] getSystemSharedLibraryNames() {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getSystemSharedLibraryNames();
-        }
-    }
-
-    @Override
-    public int checkSignatures(@NonNull String pkg1,
-            @NonNull String pkg2) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.checkSignatures(pkg1, pkg2);
-        }
-    }
-
-    @Override
-    public int checkUidSignatures(int uid1, int uid2) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.checkUidSignatures(uid1, uid2);
-        }
-    }
-
-    @Override
-    public boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate,
-            int type) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.hasSigningCertificate(packageName, certificate, type);
-        }
-    }
-
-    @Override
-    public boolean hasUidSigningCertificate(int uid, @NonNull byte[] certificate, int type) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.hasUidSigningCertificate(uid, certificate, type);
-        }
-    }
-
-    @Override
-    public List<String> getAllPackages() {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getAllPackages();
-        }
-    }
-
-    @Nullable
-    @Override
-    public String getNameForUid(int uid) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getNameForUid(uid);
-        }
-    }
-
-    @Nullable
-    @Override
-    public String[] getNamesForUids(int[] uids) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getNamesForUids(uids);
-        }
-    }
-
-    @Override
-    public int getUidForSharedUser(@NonNull String sharedUserName) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getUidForSharedUser(sharedUserName);
-        }
-    }
-
-    @Override
-    public int getFlagsForUid(int uid) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getFlagsForUid(uid);
-        }
-    }
-
-    @Override
-    public int getPrivateFlagsForUid(int uid) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPrivateFlagsForUid(uid);
-        }
-    }
-
-    @Override
-    public boolean isUidPrivileged(int uid) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.isUidPrivileged(uid);
-        }
-    }
-
-    @NonNull
-    @Override
-    public String[] getAppOpPermissionPackages(@NonNull String permissionName) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getAppOpPermissionPackages(permissionName);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
-            @NonNull String[] permissions, @PackageManager.PackageInfoFlagsBits long flags,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPackagesHoldingPermissions(permissions, flags, userId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public List<ApplicationInfo> getInstalledApplications(
-            @PackageManager.ApplicationInfoFlagsBits long flags, @UserIdInt int userId,
-            int callingUid) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getInstalledApplications(flags, userId, callingUid);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ProviderInfo resolveContentProvider(@NonNull String name,
-            @PackageManager.ResolveInfoFlagsBits long flags, @UserIdInt int userId,
-            int callingUid) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.resolveContentProvider(name, flags, userId, callingUid);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ProviderInfo getGrantImplicitAccessProviderInfo(int recipientUid,
-            @NonNull String visibleAuthority) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getGrantImplicitAccessProviderInfo(recipientUid,
-                    visibleAuthority);
-        }
-    }
-
-    @Override
-    public void querySyncProviders(boolean safeMode, @NonNull List<String> outNames,
-            @NonNull List<ProviderInfo> outInfo) {
-        try (ThreadComputer current = snapshot()) {
-            current.mComputer.querySyncProviders(safeMode, outNames, outInfo);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable String processName,
-            int uid, @PackageManager.ComponentInfoFlagsBits long flags,
-            @Nullable String metaDataKey) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.queryContentProviders(processName, uid, flags, metaDataKey);
-        }
-    }
-
-    @Nullable
-    @Override
-    public InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getInstrumentationInfo(component, flags);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ParceledListSlice<InstrumentationInfo> queryInstrumentation(
-            @NonNull String targetPackage, int flags) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.queryInstrumentation(targetPackage, flags);
-        }
-    }
-
-    @NonNull
-    @Override
-    public List<PackageStateInternal> findSharedNonSystemLibraries(
-            @NonNull PackageStateInternal pkgSetting) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.findSharedNonSystemLibraries(pkgSetting);
-        }
-    }
-
-    @Override
-    public boolean getApplicationHiddenSettingAsUser(@NonNull String packageName,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getApplicationHiddenSettingAsUser(packageName, userId);
-        }
-    }
-
-    @Override
-    public boolean isPackageSuspendedForUser(@NonNull String packageName, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.isPackageSuspendedForUser(packageName, userId);
-        }
-    }
-
-    @Override
-    public boolean isSuspendingAnyPackages(@NonNull String suspendingPackage,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.isSuspendingAnyPackages(suspendingPackage, userId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ParceledListSlice<IntentFilter> getAllIntentFilters(@NonNull String packageName) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getAllIntentFilters(packageName);
-        }
-    }
-
-    @Override
-    public boolean getBlockUninstallForUser(@NonNull String packageName, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getBlockUninstallForUser(packageName, userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public SparseArray<int[]> getBroadcastAllowList(@NonNull String packageName,
-            @UserIdInt int[] userIds, boolean isInstantApp) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getBroadcastAllowList(packageName, userIds, isInstantApp);
-        }
-    }
-
-    @Nullable
-    @Override
-    public String getInstallerPackageName(@NonNull String packageName) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getInstallerPackageName(packageName);
-        }
-    }
-
-    @Nullable
-    @Override
-    public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getInstallSourceInfo(packageName);
-        }
-    }
-
-    @Override
-    public int getApplicationEnabledSetting(@NonNull String packageName, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getApplicationEnabledSetting(packageName, userId);
-        }
-    }
-
-    @Override
-    public int getComponentEnabledSetting(@NonNull ComponentName component, int callingUid,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getComponentEnabledSetting(component, callingUid, userId);
-        }
-    }
-
-    @Override
-    public int getComponentEnabledSettingInternal(@NonNull ComponentName component, int callingUid,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getComponentEnabledSettingInternal(
-                    component, callingUid, userId);
-        }
-    }
-
-    @Override
-    public boolean isComponentEffectivelyEnabled(@NonNull ComponentInfo componentInfo,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.isComponentEffectivelyEnabled(componentInfo, userId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getKeySetByAlias(packageName, alias);
-        }
-    }
-
-    @Nullable
-    @Override
-    public KeySet getSigningKeySet(@NonNull String packageName) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getSigningKeySet(packageName);
-        }
-    }
-
-    @Override
-    public boolean isPackageSignedByKeySet(@NonNull String packageName, @NonNull KeySet ks) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.isPackageSignedByKeySet(packageName, ks);
-        }
-    }
-
-    @Override
-    public boolean isPackageSignedByKeySetExactly(@NonNull String packageName, @NonNull KeySet ks) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.isPackageSignedByKeySetExactly(packageName, ks);
-        }
-    }
-
-    @Nullable
-    @Override
-    public int[] getVisibilityAllowList(@NonNull String packageName, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getVisibilityAllowList(packageName, userId);
-        }
-    }
-
-    @Override
-    public boolean canQueryPackage(int callingUid, @Nullable String targetPackageName) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.canQueryPackage(callingUid, targetPackageName);
-        }
-    }
-
-    @Override
-    public int getPackageUid(@NonNull String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPackageUid(packageName, flags, userId);
-        }
-    }
-
-    @Override
-    public boolean canAccessComponent(int callingUid, @NonNull ComponentName component,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.canAccessComponent(callingUid, component, userId);
-        }
-    }
-
-    @Override
-    public boolean isCallerInstallerOfRecord(@NonNull AndroidPackage pkg, int callingUid) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.isCallerInstallerOfRecord(pkg, callingUid);
-        }
-    }
-
-    @Override
-    public int getInstallReason(@NonNull String packageName, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getInstallReason(packageName, userId);
-        }
-    }
-
-    @Override
-    public boolean canPackageQuery(@NonNull String sourcePackageName,
-            @NonNull String targetPackageName, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.canPackageQuery(sourcePackageName, targetPackageName, userId);
-        }
-    }
-
-    @Override
-    public boolean canForwardTo(@NonNull Intent intent, @Nullable String resolvedType,
-            @UserIdInt int sourceUserId, @UserIdInt int targetUserId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.canForwardTo(intent, resolvedType, sourceUserId, targetUserId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public List<ApplicationInfo> getPersistentApplications(boolean safeMode, int flags) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPersistentApplications(safeMode, flags);
-        }
-    }
-
-    @NonNull
-    @Override
-    public SparseArray<String> getAppsWithSharedUserIds() {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getAppsWithSharedUserIds();
-        }
-    }
-
-    @NonNull
-    @Override
-    public String[] getSharedUserPackagesForPackage(@NonNull String packageName,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getSharedUserPackagesForPackage(packageName, userId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getUnusedPackages(downgradeTimeThresholdMillis);
-        }
-    }
-
-    @Nullable
-    @Override
-    public CharSequence getHarmfulAppWarning(@NonNull String packageName, @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getHarmfulAppWarning(packageName, userId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public String[] filterOnlySystemPackages(@Nullable String... pkgNames) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.filterOnlySystemPackages(pkgNames);
-        }
-    }
-
-    @NonNull
-    @Override
-    public List<AndroidPackage> getPackagesForAppId(int appId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPackagesForAppId(appId);
-        }
-    }
-
-    @Override
-    public int getUidTargetSdkVersion(int uid) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getUidTargetSdkVersion(uid);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ArrayMap<String, ProcessInfo> getProcessesForUid(int uid) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getProcessesForUid(uid);
-        }
-    }
-
-    @Override
-    public PackageStateInternal getPackageStateFiltered(@NonNull String packageName, int callingUid,
-            @UserIdInt int userId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPackageStateFiltered(packageName, callingUid, userId);
-        }
-    }
-
-    @Override
-    public boolean getBlockUninstall(@UserIdInt int userId, @NonNull String packageName) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getBlockUninstall(userId, packageName);
-        }
-    }
-
-    @NonNull
-    @Override
-    public WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>> getSharedLibraries() {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getSharedLibraries();
-        }
-    }
-
-    @Nullable
-    @Override
-    public Pair<PackageStateInternal, SharedUserApi> getPackageOrSharedUser(int appId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getPackageOrSharedUser(appId);
-        }
-    }
-
-    @Nullable
-    @Override
-    public SharedUserApi getSharedUser(int sharedUserAppId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getSharedUser(sharedUserAppId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ArraySet<PackageStateInternal> getSharedUserPackages(int sharedUserAppId) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getSharedUserPackages(sharedUserAppId);
-        }
-    }
-
-    @NonNull
-    @Override
-    public ComponentResolverApi getComponentResolver() {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getComponentResolver();
-        }
-    }
-
-    @Nullable
-    @Override
-    public PackageStateInternal getDisabledSystemPackage(@NonNull String packageName) {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getDisabledSystemPackage(packageName);
-        }
-    }
-
-    @Nullable
-    @Override
-    public ResolveInfo getInstantAppInstallerInfo() {
-        try (ThreadComputer current = snapshot()) {
-            return current.mComputer.getInstantAppInstallerInfo();
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index b307984..89f8be2 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -112,7 +112,9 @@
             String callingFeatureId,
             ComponentName component,
             @UserIdInt int userId,
-            boolean launchMainActivity) throws RemoteException {
+            boolean launchMainActivity,
+            IBinder targetTask,
+            Bundle options) throws RemoteException {
         Objects.requireNonNull(callingPackage);
         Objects.requireNonNull(component);
 
@@ -145,8 +147,12 @@
         if (launchMainActivity) {
             launchIntent.setAction(Intent.ACTION_MAIN);
             launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-            launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+            if (targetTask == null) {
+                launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+            } else {
+                launchIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+            }
             // Only package name is set here, as opposed to component name, because intent action
             // and category are ignored if component name is present while we are resolving intent.
             launchIntent.setPackage(component.getPackageName());
@@ -170,15 +176,20 @@
         }
         verifyActivityCanHandleIntentAndExported(launchIntent, component, callingUid, userId);
 
+        // Always show the cross profile animation
+        if (options == null) {
+            options = ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle();
+        } else {
+            options.putAll(ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle());
+        }
+
         launchIntent.setPackage(null);
         launchIntent.setComponent(component);
         mInjector.getActivityTaskManagerInternal().startActivityAsUser(
                 caller, callingPackage, callingFeatureId, launchIntent,
-                /* resultTo= */ null,
-                Intent.FLAG_ACTIVITY_NEW_TASK,
-                launchMainActivity
-                        ? ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle()
-                        : null,
+                targetTask,
+                /* startFlags= */ 0,
+                options,
                 userId);
     }
 
@@ -225,6 +236,13 @@
 
         verifyActivityCanHandleIntent(launchIntent, callingUid, userId);
 
+        // Always show the cross profile animation
+        if (options == null) {
+            options = ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle();
+        } else {
+            options.putAll(ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle());
+        }
+
         mInjector.getActivityTaskManagerInternal()
                 .startActivityAsUser(
                         caller,
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 5b7cf2d..0e1c1ad 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -66,6 +66,8 @@
 import com.android.server.pm.pkg.PackageUserState;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
+import dalvik.system.VMRuntime;
+
 import java.util.Collections;
 import java.util.List;
 
@@ -145,6 +147,7 @@
         final SparseArray<TempUserState> priorUserStates;
         /** enabled state of the uninstalled application */
         synchronized (mPm.mLock) {
+            final Computer computer = mPm.snapshotComputer();
             uninstalledPs = mPm.mSettings.getPackageLPr(packageName);
             if (uninstalledPs == null) {
                 Slog.w(TAG, "Not removing non-existent package " + packageName);
@@ -168,10 +171,10 @@
             if (pkg != null) {
                 SharedLibraryInfo libraryInfo = null;
                 if (pkg.getStaticSharedLibName() != null) {
-                    libraryInfo = mPm.getSharedLibraryInfo(pkg.getStaticSharedLibName(),
+                    libraryInfo = computer.getSharedLibraryInfo(pkg.getStaticSharedLibName(),
                             pkg.getStaticSharedLibVersion());
                 } else if (pkg.getSdkLibName() != null) {
-                    libraryInfo = mPm.getSharedLibraryInfo(pkg.getSdkLibName(),
+                    libraryInfo = computer.getSharedLibraryInfo(pkg.getSdkLibName(),
                             pkg.getSdkLibVersionMajor());
                 }
 
@@ -181,7 +184,7 @@
                             continue;
                         }
                         List<VersionedPackage> libClientPackages =
-                                mPm.getPackagesUsingSharedLibrary(libraryInfo,
+                                computer.getPackagesUsingSharedLibrary(libraryInfo,
                                         MATCH_KNOWN_PACKAGES, Process.SYSTEM_UID, currUserId);
                         if (!ArrayUtils.isEmpty(libClientPackages)) {
                             Slog.w(TAG, "Not removing package " + pkg.getManifestPackageName()
@@ -241,12 +244,13 @@
         if (res) {
             final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
             info.sendPackageRemovedBroadcasts(killApp, removedBySystem);
-            if (disabledSystemPs != null) {
-                info.sendSystemPackageUpdatedBroadcasts(disabledSystemPs.getAppId());
-            }
+            info.sendSystemPackageUpdatedBroadcasts();
         }
-        // Force a gc here.
-        Runtime.getRuntime().gc();
+
+        // Force a gc to clear up things.
+        // Ask for a background one, it's fine to go on and not block here.
+        VMRuntime.getRuntime().requestConcurrentGC();
+
         // Delete the resources here after sending the broadcast to let
         // other processes clean up before deleting resources.
         synchronized (mPm.mInstallLock) {
@@ -451,11 +455,11 @@
         if (affectedUserIds == null) {
             affectedUserIds = mPm.resolveUserIds(userId);
         }
+        final Computer snapshot = mPm.snapshotComputer();
         for (final int affectedUserId : affectedUserIds) {
             if (hadSuspendAppsPermission.get(affectedUserId)) {
-                mPm.unsuspendForSuspendingPackage(mPm.snapshotComputer(), packageName,
-                        affectedUserId);
-                mPm.removeAllDistractingPackageRestrictions(affectedUserId);
+                mPm.unsuspendForSuspendingPackage(snapshot, packageName, affectedUserId);
+                mPm.removeAllDistractingPackageRestrictions(snapshot, affectedUserId);
             }
         }
 
@@ -598,9 +602,6 @@
         if (outInfo != null) {
             // Delete the updated package
             outInfo.mIsRemovedPackageSystemUpdate = true;
-            if (disabledPs.getAppId() != deletedPs.getAppId()) {
-                outInfo.mNewAppId = disabledPs.getAppId();
-            }
         }
 
         if (disabledPs.getVersionCode() < deletedPs.getVersionCode()
@@ -621,7 +622,8 @@
         final int callingUid = Binder.getCallingUid();
         mPm.mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.DELETE_PACKAGES, null);
-        final boolean canViewInstantApps = mPm.canViewInstantApps(callingUid, userId);
+        final Computer snapshot = mPm.snapshotComputer();
+        final boolean canViewInstantApps = snapshot.canViewInstantApps(callingUid, userId);
         Preconditions.checkNotNull(versionedPackage);
         Preconditions.checkNotNull(observer);
         Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
@@ -644,12 +646,13 @@
         }
 
         // Normalize package name to handle renamed packages and static libs
-        final String internalPackageName = mPm.resolveInternalPackageName(packageName, versionCode);
+        final String internalPackageName =
+                snapshot.resolveInternalPackageName(packageName, versionCode);
 
         final int uid = Binder.getCallingUid();
-        if (!isOrphaned(internalPackageName)
+        if (!isOrphaned(snapshot, internalPackageName)
                 && !allowSilentUninstall
-                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
+                && !isCallerAllowedToSilentlyUninstall(snapshot, uid, internalPackageName)) {
             mPm.mHandler.post(() -> {
                 try {
                     final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
@@ -680,7 +683,7 @@
             return;
         }
 
-        if (!deleteAllUsers && mPm.getBlockUninstallForUser(internalPackageName, userId)) {
+        if (!deleteAllUsers && snapshot.getBlockUninstallForUser(internalPackageName, userId)) {
             mPm.mHandler.post(() -> {
                 try {
                     observer.onPackageDeleted(packageName,
@@ -700,11 +703,14 @@
         // Queue up an async operation since the package deletion may take a little while.
         mPm.mHandler.post(() -> {
             int returnCode;
-            final PackageSetting ps = mPm.mSettings.getPackageLPr(internalPackageName);
+            final Computer innerSnapshot = mPm.snapshotComputer();
+            final PackageStateInternal packageState =
+                    innerSnapshot.getPackageStateInternal(internalPackageName);
             boolean doDeletePackage = true;
-            if (ps != null) {
+            if (packageState != null) {
                 final boolean targetIsInstantApp =
-                        ps.getInstantApp(UserHandle.getUserId(callingUid));
+                        packageState.getUserStateOrDefault(UserHandle.getUserId(callingUid))
+                                .isInstantApp();
                 doDeletePackage = !targetIsInstantApp
                         || canViewInstantApps;
             }
@@ -713,7 +719,7 @@
                     returnCode = deletePackageX(internalPackageName, versionCode,
                             userId, deleteFlags, false /*removedBySystem*/);
                 } else {
-                    int[] blockUninstallUserIds = getBlockUninstallForUsers(
+                    int[] blockUninstallUserIds = getBlockUninstallForUsers(innerSnapshot,
                             internalPackageName, users);
                     // If nobody is blocking uninstall, proceed with delete for all users
                     if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
@@ -752,51 +758,53 @@
         });
     }
 
-    private boolean isOrphaned(String packageName) {
-        final PackageStateInternal packageState = mPm.getPackageStateInternal(packageName);
+    private boolean isOrphaned(@NonNull Computer snapshot, String packageName) {
+        final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
         return packageState != null && packageState.getInstallSource().isOrphaned;
     }
 
-    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
+    private boolean isCallerAllowedToSilentlyUninstall(@NonNull Computer snapshot, int callingUid,
+            String pkgName) {
         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
                 || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
             return true;
         }
         final int callingUserId = UserHandle.getUserId(callingUid);
         // If the caller installed the pkgName, then allow it to silently uninstall.
-        if (callingUid == mPm.getPackageUid(
-                mPm.getInstallerPackageName(pkgName), 0, callingUserId)) {
+        if (callingUid == snapshot.getPackageUid(snapshot.getInstallerPackageName(pkgName), 0,
+                callingUserId)) {
             return true;
         }
 
         // Allow package verifier to silently uninstall.
-        if (mPm.mRequiredVerifierPackage != null && callingUid == mPm.getPackageUid(
-                mPm.mRequiredVerifierPackage, 0, callingUserId)) {
+        if (mPm.mRequiredVerifierPackage != null && callingUid == snapshot
+                .getPackageUid(mPm.mRequiredVerifierPackage, 0, callingUserId)) {
             return true;
         }
 
         // Allow package uninstaller to silently uninstall.
-        if (mPm.mRequiredUninstallerPackage != null && callingUid == mPm.getPackageUid(
-                mPm.mRequiredUninstallerPackage, 0, callingUserId)) {
+        if (mPm.mRequiredUninstallerPackage != null && callingUid == snapshot
+                .getPackageUid(mPm.mRequiredUninstallerPackage, 0, callingUserId)) {
             return true;
         }
 
         // Allow storage manager to silently uninstall.
-        if (mPm.mStorageManagerPackage != null && callingUid == mPm.getPackageUid(
+        if (mPm.mStorageManagerPackage != null && callingUid == snapshot.getPackageUid(
                 mPm.mStorageManagerPackage, 0, callingUserId)) {
             return true;
         }
 
         // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
         // uninstall for device owner provisioning.
-        return mPm.checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
+        return snapshot.checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
                 == PERMISSION_GRANTED;
     }
 
-    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
+    private int[] getBlockUninstallForUsers(@NonNull Computer snapshot, String packageName,
+            int[] userIds) {
         int[] result = EMPTY_INT_ARRAY;
         for (int userId : userIds) {
-            if (mPm.getBlockUninstallForUser(packageName, userId)) {
+            if (snapshot.getBlockUninstallForUser(packageName, userId)) {
                 result = ArrayUtils.appendInt(result, userId);
             }
         }
@@ -894,8 +902,8 @@
         int installedForUsersCount = 0;
         synchronized (mPm.mLock) {
             // Normalize package name to handle renamed packages and static libs
-            final String internalPkgName = mPm.resolveInternalPackageName(packageName,
-                    versionCode);
+            final String internalPkgName = mPm.snapshotComputer()
+                    .resolveInternalPackageName(packageName, versionCode);
             final PackageSetting ps = mPm.mSettings.getPackageLPr(internalPkgName);
             if (ps != null) {
                 int[] installedUsers = ps.queryInstalledUsers(mUserManagerInternal.getUserIds(),
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index c832693..50b2e23 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -266,8 +266,9 @@
             return;
         }
 
+        final Computer snapshot = mPm.snapshotComputer();
         List<PackageStateInternal> pkgSettings =
-                getPackagesForDexopt(mPm.getPackageStates().values(), mPm);
+                getPackagesForDexopt(snapshot.getPackageStates().values(), mPm);
 
         List<AndroidPackage> pkgs = new ArrayList<>(pkgSettings.size());
         for (int index = 0; index < pkgSettings.size(); index++) {
@@ -282,17 +283,19 @@
         final int elapsedTimeSeconds =
                 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
 
+        final Computer newSnapshot = mPm.snapshotComputer();
+
         MetricsLogger.histogram(mPm.mContext, "opt_dialog_num_dexopted", stats[0]);
         MetricsLogger.histogram(mPm.mContext, "opt_dialog_num_skipped", stats[1]);
         MetricsLogger.histogram(mPm.mContext, "opt_dialog_num_failed", stats[2]);
-        MetricsLogger.histogram(
-                mPm.mContext, "opt_dialog_num_total", getOptimizablePackages().size());
+        MetricsLogger.histogram(mPm.mContext, "opt_dialog_num_total",
+                getOptimizablePackages(newSnapshot).size());
         MetricsLogger.histogram(mPm.mContext, "opt_dialog_time_s", elapsedTimeSeconds);
     }
 
-    public ArraySet<String> getOptimizablePackages() {
+    public ArraySet<String> getOptimizablePackages(@NonNull Computer snapshot) {
         ArraySet<String> pkgs = new ArraySet<>();
-        mPm.forEachPackageState(packageState -> {
+        mPm.forEachPackageState(snapshot, packageState -> {
             final AndroidPackage pkg = packageState.getPkg();
             if (pkg != null && mPm.mPackageDexOptimizer.canOptimizePackage(pkg)) {
                 pkgs.add(packageState.getPackageName());
@@ -302,9 +305,10 @@
     }
 
     /*package*/ boolean performDexOpt(DexoptOptions options) {
-        if (mPm.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+        final Computer snapshot = mPm.snapshotComputer();
+        if (snapshot.getInstantAppPackageName(Binder.getCallingUid()) != null) {
             return false;
-        } else if (mPm.isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
+        } else if (snapshot.isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
             return false;
         }
 
@@ -416,10 +420,10 @@
                 mPm.getDexManager().getPackageUseInfoOrDefault(p.getPackageName()), options);
     }
 
-    public void forceDexOpt(String packageName) {
+    public void forceDexOpt(@NonNull Computer snapshot, String packageName) {
         PackageManagerServiceUtils.enforceSystemOrRoot("forceDexOpt");
 
-        final PackageStateInternal packageState = mPm.getPackageStateInternal(packageName);
+        final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
         final AndroidPackage pkg = packageState == null ? null : packageState.getPkg();
         if (packageState == null || pkg == null) {
             throw new IllegalArgumentException("Unknown package: " + packageName);
@@ -484,19 +488,21 @@
 
         ArrayList<PackageStateInternal> sortTemp = new ArrayList<>(remainingPkgSettings.size());
 
+        final Computer snapshot = packageManagerService.snapshotComputer();
+
         // Give priority to core apps.
-        applyPackageFilter(pkgSetting -> pkgSetting.getPkg().isCoreApp(), result,
+        applyPackageFilter(snapshot, pkgSetting -> pkgSetting.getPkg().isCoreApp(), result,
                 remainingPkgSettings, sortTemp, packageManagerService);
 
         // Give priority to system apps that listen for pre boot complete.
         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
         final ArraySet<String> pkgNames = getPackageNamesForIntent(intent, UserHandle.USER_SYSTEM);
-        applyPackageFilter(pkgSetting -> pkgNames.contains(pkgSetting.getPackageName()), result,
+        applyPackageFilter(snapshot, pkgSetting -> pkgNames.contains(pkgSetting.getPackageName()), result,
                 remainingPkgSettings, sortTemp, packageManagerService);
 
         // Give priority to apps used by other apps.
         DexManager dexManager = packageManagerService.getDexManager();
-        applyPackageFilter(pkgSetting ->
+        applyPackageFilter(snapshot, pkgSetting ->
                         dexManager.getPackageUseInfoOrDefault(pkgSetting.getPackageName())
                                 .isAnyCodePathUsedByOtherApps(),
                 result, remainingPkgSettings, sortTemp, packageManagerService);
@@ -534,7 +540,7 @@
             // No historical info. Take all.
             remainingPredicate = pkgSetting -> true;
         }
-        applyPackageFilter(remainingPredicate, result, remainingPkgSettings, sortTemp,
+        applyPackageFilter(snapshot, remainingPredicate, result, remainingPkgSettings, sortTemp,
                 packageManagerService);
 
         if (debug) {
@@ -549,7 +555,7 @@
     // package will be removed from {@code packages} and added to {@code result} with its
     // dependencies. If usage data is available, the positive packages will be sorted by usage
     // data (with {@code sortTemp} as temporary storage).
-    private static void applyPackageFilter(
+    private static void applyPackageFilter(@NonNull Computer snapshot,
             Predicate<PackageStateInternal> filter,
             Collection<PackageStateInternal> result,
             Collection<PackageStateInternal> packages,
@@ -567,8 +573,7 @@
         for (PackageStateInternal pkgSetting : sortTemp) {
             result.add(pkgSetting);
 
-            List<PackageStateInternal> deps =
-                    packageManagerService.findSharedNonSystemLibraries(pkgSetting);
+            List<PackageStateInternal> deps = snapshot.findSharedNonSystemLibraries(pkgSetting);
             if (!deps.isEmpty()) {
                 deps.removeAll(result);
                 result.addAll(deps);
diff --git a/services/core/java/com/android/server/pm/DomainVerificationConnection.java b/services/core/java/com/android/server/pm/DomainVerificationConnection.java
index db8c6dc..20e4dd8 100644
--- a/services/core/java/com/android/server/pm/DomainVerificationConnection.java
+++ b/services/core/java/com/android/server/pm/DomainVerificationConnection.java
@@ -21,7 +21,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
-import android.content.pm.PackageManagerInternal;
 import android.os.Binder;
 import android.os.Message;
 import android.os.UserHandle;
@@ -35,13 +34,10 @@
 public final class DomainVerificationConnection implements DomainVerificationService.Connection,
         DomainVerificationProxyV1.Connection, DomainVerificationProxyV2.Connection {
     final PackageManagerService mPm;
-    final PackageManagerInternal mPmInternal;
     final UserManagerInternal mUmInternal;
 
-    // TODO(b/198166813): remove PMS dependency
     DomainVerificationConnection(PackageManagerService pm) {
         mPm = pm;
-        mPmInternal = mPm.mInjector.getLocalService(PackageManagerInternal.class);
         mUmInternal = mPm.mInjector.getLocalService(UserManagerInternal.class);
     }
 
@@ -82,18 +78,18 @@
     @Override
     public boolean isCallerPackage(int callingUid, @NonNull String packageName) {
         final int callingUserId = UserHandle.getUserId(callingUid);
-        return callingUid == mPmInternal.getPackageUid(packageName, 0, callingUserId);
+        return callingUid == mPm.snapshotComputer().getPackageUid(packageName, 0, callingUserId);
     }
 
     @Nullable
     @Override
     public AndroidPackage getPackage(@NonNull String packageName) {
-        return mPmInternal.getPackage(packageName);
+        return mPm.snapshotComputer().getPackage(packageName);
     }
 
     @Override
     public boolean filterAppAccess(String packageName, int callingUid, int userId) {
-        return mPmInternal.filterAppAccess(packageName, callingUid, userId);
+        return mPm.snapshotComputer().filterAppAccess(packageName, callingUid, userId);
     }
 
     @Override
@@ -108,6 +104,6 @@
 
     @NonNull
     public Computer snapshot() {
-        return (Computer) mPmInternal.snapshot();
+        return mPm.snapshotComputer();
     }
 }
diff --git a/services/core/java/com/android/server/pm/DumpHelper.java b/services/core/java/com/android/server/pm/DumpHelper.java
index 2b46ed4..f83ef5a 100644
--- a/services/core/java/com/android/server/pm/DumpHelper.java
+++ b/services/core/java/com/android/server/pm/DumpHelper.java
@@ -55,6 +55,7 @@
 
     @NeverCompile // Avoid size overhead of debugging code.
     public void doDump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        final Computer snapshot = mPm.snapshotComputer();
         DumpState dumpState = new DumpState();
         ArraySet<String> permissionNames = null;
 
@@ -121,7 +122,7 @@
                 }
 
                 // Normalize package name to handle renamed packages and static libs
-                pkg = mPm.resolveInternalPackageName(pkg, PackageManager.VERSION_CODE_HIGHEST);
+                pkg = snapshot.resolveInternalPackageName(pkg, PackageManager.VERSION_CODE_HIGHEST);
 
                 pw.println(mPm.checkPermission(perm, pkg, user));
                 return;
@@ -243,7 +244,7 @@
 
         // Return if the package doesn't exist.
         if (packageName != null
-                && mPm.getPackageStateInternal(packageName) == null
+                && snapshot.getPackageStateInternal(packageName) == null
                 && !mPm.mApexManager.isApexPackage(packageName)) {
             pw.println("Unable to find package: " + packageName);
             return;
@@ -257,7 +258,7 @@
         if (!checkin
                 && dumpState.isDumping(DumpState.DUMP_VERSION)
                 && packageName == null) {
-            mPm.dumpComputer(DumpState.DUMP_VERSION, fd, pw, dumpState);
+            snapshot.dump(DumpState.DUMP_VERSION, fd, pw, dumpState);
         }
 
         if (!checkin
@@ -273,7 +274,7 @@
                 final String knownPackage = PackageManagerInternal.knownPackageToString(i);
                 ipw.print(knownPackage);
                 ipw.println(":");
-                final String[] pkgNames = mPm.getKnownPackageNamesInternal(i,
+                final String[] pkgNames = mPm.getKnownPackageNamesInternal(snapshot, i,
                         UserHandle.USER_SYSTEM);
                 ipw.increaseIndent();
                 if (ArrayUtils.isEmpty(pkgNames)) {
@@ -299,14 +300,14 @@
                 pw.print("  Required: ");
                 pw.print(requiredVerifierPackage);
                 pw.print(" (uid=");
-                pw.print(mPm.getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
-                        UserHandle.USER_SYSTEM));
+                pw.print(snapshot.getPackageUid(requiredVerifierPackage,
+                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM));
                 pw.println(")");
             } else if (requiredVerifierPackage != null) {
                 pw.print("vrfy,"); pw.print(requiredVerifierPackage);
                 pw.print(",");
-                pw.println(mPm.getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
-                        UserHandle.USER_SYSTEM));
+                pw.println(snapshot.getPackageUid(requiredVerifierPackage,
+                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM));
             }
         }
 
@@ -324,14 +325,14 @@
                     pw.print("  Using: ");
                     pw.print(verifierPackageName);
                     pw.print(" (uid=");
-                    pw.print(mPm.getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
-                            UserHandle.USER_SYSTEM));
+                    pw.print(snapshot.getPackageUid(verifierPackageName,
+                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM));
                     pw.println(")");
                 } else if (verifierPackageName != null) {
                     pw.print("dv,"); pw.print(verifierPackageName);
                     pw.print(",");
-                    pw.println(mPm.getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
-                            UserHandle.USER_SYSTEM));
+                    pw.println(snapshot.getPackageUid(verifierPackageName,
+                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM));
                 }
             } else {
                 pw.println();
@@ -341,7 +342,7 @@
 
         if (dumpState.isDumping(DumpState.DUMP_LIBS)
                 && packageName == null) {
-            mPm.dumpComputer(DumpState.DUMP_LIBS, fd, pw, dumpState);
+            snapshot.dump(DumpState.DUMP_LIBS, fd, pw, dumpState);
         }
 
         if (dumpState.isDumping(DumpState.DUMP_FEATURES)
@@ -387,17 +388,17 @@
         }
 
         if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
-            mPm.dumpComputer(DumpState.DUMP_PREFERRED, fd, pw, dumpState);
+            snapshot.dump(DumpState.DUMP_PREFERRED, fd, pw, dumpState);
         }
 
         if (!checkin
                 && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)
                 && packageName == null) {
-            mPm.dumpComputer(DumpState.DUMP_PREFERRED_XML, fd, pw, dumpState);
+            snapshot.dump(DumpState.DUMP_PREFERRED_XML, fd, pw, dumpState);
         }
 
         if (!checkin && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)) {
-            mPm.dumpComputer(DumpState.DUMP_DOMAIN_PREFERRED, fd, pw, dumpState);
+            snapshot.dump(DumpState.DUMP_DOMAIN_PREFERRED, fd, pw, dumpState);
         }
 
         if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
@@ -405,7 +406,7 @@
         }
 
         if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
-            mPm.mComponentResolver.dumpContentProviders(mPm.snapshotComputer(), pw, dumpState,
+            mPm.mComponentResolver.dumpContentProviders(snapshot, pw, dumpState,
                     packageName);
         }
 
@@ -427,7 +428,7 @@
 
         if (!checkin
                 && dumpState.isDumping(DumpState.DUMP_QUERIES)) {
-            mPm.dumpComputer(DumpState.DUMP_QUERIES, fd, pw, dumpState);
+            snapshot.dump(DumpState.DUMP_QUERIES, fd, pw, dumpState);
         }
 
         if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
@@ -527,12 +528,12 @@
 
         if (!checkin
                 && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
-            mPm.dumpComputer(DumpState.DUMP_DEXOPT, fd, pw, dumpState);
+            snapshot.dump(DumpState.DUMP_DEXOPT, fd, pw, dumpState);
         }
 
         if (!checkin
                 && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
-            mPm.dumpComputer(DumpState.DUMP_COMPILER_STATS, fd, pw, dumpState);
+            snapshot.dump(DumpState.DUMP_COMPILER_STATS, fd, pw, dumpState);
         }
 
         if (dumpState.isDumping(DumpState.DUMP_MESSAGES)
@@ -579,7 +580,7 @@
             pw.println("    Known digesters list flag: "
                     + PackageManagerService.getKnownDigestersList());
 
-            PerUidReadTimeouts[] items = mPm.getPerUidReadTimeouts();
+            PerUidReadTimeouts[] items = mPm.getPerUidReadTimeouts(snapshot);
             pw.println("    Timeouts (" + items.length + "):");
             for (PerUidReadTimeouts item : items) {
                 pw.print("        (");
@@ -661,13 +662,14 @@
         final ProtoOutputStream proto = new ProtoOutputStream(fd);
 
         synchronized (mPm.mLock) {
+            final Computer snapshot = mPm.snapshotComputer();
             final long requiredVerifierPackageToken =
                     proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
             proto.write(PackageServiceDumpProto.PackageShortProto.NAME,
                     mPm.mRequiredVerifierPackage);
             proto.write(
                     PackageServiceDumpProto.PackageShortProto.UID,
-                    mPm.getPackageUid(
+                    snapshot.getPackageUid(
                             mPm.mRequiredVerifierPackage,
                             MATCH_DEBUG_TRIAGED_MISSING,
                             UserHandle.USER_SYSTEM));
@@ -682,7 +684,7 @@
                 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
                 proto.write(
                         PackageServiceDumpProto.PackageShortProto.UID,
-                        mPm.getPackageUid(
+                        snapshot.getPackageUid(
                                 verifierPackageName,
                                 MATCH_DEBUG_TRIAGED_MISSING,
                                 UserHandle.USER_SYSTEM));
diff --git a/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java b/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
index c65c2b1..b4bcd5b 100644
--- a/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
+++ b/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
@@ -22,11 +22,12 @@
 import android.app.job.JobService;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageManagerInternal;
 import android.os.Process;
-import android.os.ServiceManager;
 import android.util.EventLog;
 import android.util.Log;
 
+import com.android.server.LocalServices;
 import com.android.server.pm.dex.DynamicCodeLogger;
 
 import libcore.util.HexEncoding;
@@ -133,8 +134,7 @@
     }
 
     private static DynamicCodeLogger getDynamicCodeLogger() {
-        PackageManagerService pm = (PackageManagerService) ServiceManager.getService("package");
-        return pm.getDexManager().getDynamicCodeLogger();
+        return LocalServices.getService(PackageManagerInternal.class).getDynamicCodeLogger();
     }
 
     private class IdleLoggingThread extends Thread {
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
new file mode 100644
index 0000000..e1aee6d
--- /dev/null
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -0,0 +1,1189 @@
+/*
+ * 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.pm;
+
+
+import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.UserIdInt;
+import android.app.role.RoleManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
+import android.content.pm.IPackageInstaller;
+import android.content.pm.IPackageManager;
+import android.content.pm.IPackageStatsObserver;
+import android.content.pm.InstallSourceInfo;
+import android.content.pm.InstrumentationInfo;
+import android.content.pm.IntentFilterVerificationInfo;
+import android.content.pm.KeySet;
+import android.content.pm.ModuleInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.SharedLibraryInfo;
+import android.content.pm.VersionedPackage;
+import android.content.pm.dex.IArtManager;
+import android.os.Binder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.permission.PermissionManager;
+
+import com.android.internal.R;
+import com.android.internal.content.InstallLocationUtils;
+import com.android.internal.util.CollectionUtils;
+import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
+import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV1;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Contains all simply proxy methods which need a snapshot instance and just calls a method on it,
+ * with no additional logic. Separated with all methods marked final and deprecated to prevent their
+ * use from other methods which may need a snapshot for non-trivial reasons.
+ */
+public abstract class IPackageManagerBase extends IPackageManager.Stub {
+
+    @NonNull
+    private final PackageManagerService mService;
+
+    @NonNull
+    private final Context mContext;
+
+    @NonNull private final DexOptHelper mDexOptHelper;
+    @NonNull private final ModuleInfoProvider mModuleInfoProvider;
+    @NonNull private final PreferredActivityHelper mPreferredActivityHelper;
+    @NonNull private final ResolveIntentHelper mResolveIntentHelper;
+
+    @NonNull
+    private final DomainVerificationManagerInternal mDomainVerificationManager;
+
+    @NonNull
+    private final DomainVerificationConnection mDomainVerificationConnection;
+
+    @NonNull
+    private final PackageInstallerService mInstallerService;
+
+    @NonNull
+    private final PackageProperty mPackageProperty;
+
+    @NonNull
+    private final ComponentName mResolveComponentName;
+
+    @Nullable
+    private final ComponentName mInstantAppResolverSettingsComponent;
+
+    @NonNull
+    private final String mRequiredSupplementalProcessPackage;
+
+    @Nullable
+    private final String mServicesExtensionPackageName;
+
+    @Nullable
+    private final String mSharedSystemSharedLibraryPackageName;
+
+    public IPackageManagerBase(@NonNull PackageManagerService service, @NonNull Context context,
+            @NonNull DexOptHelper dexOptHelper, @NonNull ModuleInfoProvider moduleInfoProvider,
+            @NonNull PreferredActivityHelper preferredActivityHelper,
+            @NonNull ResolveIntentHelper resolveIntentHelper,
+            @NonNull DomainVerificationManagerInternal domainVerificationManager,
+            @NonNull DomainVerificationConnection domainVerificationConnection,
+            @NonNull PackageInstallerService installerService,
+            @NonNull PackageProperty packageProperty, @NonNull ComponentName resolveComponentName,
+            @Nullable ComponentName instantAppResolverSettingsComponent,
+            @NonNull String requiredSupplementalProcessPackage,
+            @Nullable String servicesExtensionPackageName,
+            @Nullable String sharedSystemSharedLibraryPackageName) {
+        mService = service;
+        mContext = context;
+        mDexOptHelper = dexOptHelper;
+        mModuleInfoProvider = moduleInfoProvider;
+        mPreferredActivityHelper = preferredActivityHelper;
+        mResolveIntentHelper = resolveIntentHelper;
+        mDomainVerificationManager = domainVerificationManager;
+        mDomainVerificationConnection = domainVerificationConnection;
+        mInstallerService = installerService;
+        mPackageProperty = packageProperty;
+        mResolveComponentName = resolveComponentName;
+        mInstantAppResolverSettingsComponent = instantAppResolverSettingsComponent;
+        mRequiredSupplementalProcessPackage = requiredSupplementalProcessPackage;
+        mServicesExtensionPackageName = servicesExtensionPackageName;
+        mSharedSystemSharedLibraryPackageName = sharedSystemSharedLibraryPackageName;
+    }
+
+    protected Computer snapshot() {
+        return mService.snapshotComputer();
+    }
+
+    @Override
+    @Deprecated
+    public final boolean activitySupportsIntent(ComponentName component, Intent intent,
+            String resolvedType) {
+        return snapshot().activitySupportsIntent(mResolveComponentName, component, intent,
+                resolvedType);
+    }
+
+    @Override
+    @Deprecated
+    public final void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
+            int sourceUserId, int targetUserId, int flags) {
+        mService.addCrossProfileIntentFilter(snapshot(),
+                new WatchedIntentFilter(intentFilter), ownerPackage, sourceUserId, targetUserId,
+                flags);
+    }
+
+    // NOTE: Can't remove due to unsupported app usage
+    @Override
+    @Deprecated
+    public final boolean addPermission(PermissionInfo info) {
+        // Because this is accessed via the package manager service AIDL,
+        // go through the permission manager service AIDL
+        return mContext.getSystemService(PermissionManager.class).addPermission(info, false);
+    }
+
+    // NOTE: Can't remove due to unsupported app usage
+    @Override
+    @Deprecated
+    public final boolean addPermissionAsync(PermissionInfo info) {
+        // Because this is accessed via the package manager service AIDL,
+        // go through the permission manager service AIDL
+        return mContext.getSystemService(PermissionManager.class).addPermission(info, true);
+    }
+
+    @Override
+    @Deprecated
+    public final void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
+            int userId) {
+        mPreferredActivityHelper.addPersistentPreferredActivity(new WatchedIntentFilter(filter),
+                activity, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void addPreferredActivity(IntentFilter filter, int match,
+            ComponentName[] set, ComponentName activity, int userId, boolean removeExisting) {
+        mPreferredActivityHelper.addPreferredActivity(snapshot(),
+                new WatchedIntentFilter(filter), match, set, activity, true, userId,
+                "Adding preferred", removeExisting);
+    }
+
+    /*
+     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
+     */
+    @Override
+    @Deprecated
+    public final boolean canForwardTo(@NonNull Intent intent, @Nullable String resolvedType,
+            @UserIdInt int sourceUserId, @UserIdInt int targetUserId) {
+        return snapshot().canForwardTo(intent, resolvedType, sourceUserId, targetUserId);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean canRequestPackageInstalls(String packageName, int userId) {
+        return snapshot().canRequestPackageInstalls(packageName, Binder.getCallingUid(), userId,
+                true /* throwIfPermNotDeclared*/);
+    }
+
+    @Override
+    @Deprecated
+    public final String[] canonicalToCurrentPackageNames(String[] names) {
+        return snapshot().canonicalToCurrentPackageNames(names);
+    }
+
+    // NOTE: Can't remove due to unsupported app usage
+    @Override
+    @Deprecated
+    public final int checkPermission(String permName, String pkgName, int userId) {
+        return mService.checkPermission(permName, pkgName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final int checkSignatures(@NonNull String pkg1, @NonNull String pkg2) {
+        return snapshot().checkSignatures(pkg1, pkg2);
+    }
+
+    @Override
+    @Deprecated
+    public final int checkUidPermission(String permName, int uid) {
+        return snapshot().checkUidPermission(permName, uid);
+    }
+
+    @Override
+    @Deprecated
+    public final int checkUidSignatures(int uid1, int uid2) {
+        return snapshot().checkUidSignatures(uid1, uid2);
+    }
+
+    @Override
+    @Deprecated
+    public final void clearPackagePersistentPreferredActivities(String packageName, int userId) {
+        mPreferredActivityHelper.clearPackagePersistentPreferredActivities(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void clearPackagePreferredActivities(String packageName) {
+        mPreferredActivityHelper.clearPackagePreferredActivities(snapshot(),
+                packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final String[] currentToCanonicalPackageNames(String[] names) {
+        return snapshot().currentToCanonicalPackageNames(names);
+    }
+
+    @Override
+    @Deprecated
+    public final void deleteExistingPackageAsUser(VersionedPackage versionedPackage,
+            final IPackageDeleteObserver2 observer, final int userId) {
+        mService.deleteExistingPackageAsUser(versionedPackage, observer, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void deletePackageAsUser(String packageName, int versionCode,
+            IPackageDeleteObserver observer, int userId, int flags) {
+        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
+                new PackageManager.LegacyPackageDeleteObserver(observer).getBinder(), userId,
+                flags);
+    }
+
+    @Override
+    @Deprecated
+    public final void deletePackageVersioned(VersionedPackage versionedPackage,
+            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
+        mService.deletePackageVersioned(versionedPackage, observer, userId, deleteFlags);
+    }
+
+    @Override
+    @Deprecated
+    public final ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
+        return mPreferredActivityHelper.findPersistentPreferredActivity(snapshot(), intent, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void forceDexOpt(String packageName) {
+        mDexOptHelper.forceDexOpt(snapshot(), packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final ActivityInfo getActivityInfo(ComponentName component,
+            @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
+        return snapshot().getActivityInfo(component, flags, userId);
+    }
+
+    @NonNull
+    @Override
+    @Deprecated
+    public final ParceledListSlice<IntentFilter> getAllIntentFilters(@NonNull String packageName) {
+        return snapshot().getAllIntentFilters(packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final List<String> getAllPackages() {
+        return snapshot().getAllPackages();
+    }
+
+    // NOTE: Can't remove due to unsupported app usage
+    @NonNull
+    @Override
+    @Deprecated
+    public final String[] getAppOpPermissionPackages(@NonNull String permissionName) {
+        return snapshot().getAppOpPermissionPackages(permissionName);
+    }
+
+    @Override
+    @Deprecated
+    public final String getAppPredictionServicePackageName() {
+        return mService.mAppPredictionServicePackage;
+    }
+
+    @PackageManager.EnabledState
+    @Override
+    @Deprecated
+    public final int getApplicationEnabledSetting(@NonNull String packageName,
+            @UserIdInt int userId) {
+        return snapshot().getApplicationEnabledSetting(packageName, userId);
+    }
+
+    /**
+     * Returns true if application is not found or there was an error. Otherwise it returns the
+     * hidden state of the package for the given user.
+     */
+    @Override
+    @Deprecated
+    public final boolean getApplicationHiddenSettingAsUser(@NonNull String packageName,
+            @UserIdInt int userId) {
+        return snapshot().getApplicationHiddenSettingAsUser(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final ApplicationInfo getApplicationInfo(String packageName,
+            @PackageManager.ApplicationInfoFlagsBits long flags, int userId) {
+        return snapshot().getApplicationInfo(packageName, flags, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final IArtManager getArtManager() {
+        return mService.mArtManagerService;
+    }
+
+    @Override
+    @Deprecated
+    public final @Nullable
+    String getAttentionServicePackageName() {
+        return mService.ensureSystemPackageName(snapshot(),
+                mService.getPackageFromComponentString(R.string.config_defaultAttentionService));
+    }
+
+    @Override
+    @Deprecated
+    public final boolean getBlockUninstallForUser(@NonNull String packageName,
+            @UserIdInt int userId) {
+        return snapshot().getBlockUninstallForUser(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
+        return snapshot().getComponentEnabledSetting(component, Binder.getCallingUid(), userId);
+    }
+
+    @Override
+    @Deprecated
+    public final String getContentCaptureServicePackageName() {
+        return mService.ensureSystemPackageName(snapshot(),
+                mService.getPackageFromComponentString(
+                        R.string.config_defaultContentCaptureService));
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
+            @NonNull String packageName, @PackageManager.PackageInfoFlagsBits long flags,
+            @NonNull int userId) {
+        return snapshot().getDeclaredSharedLibraries(packageName, flags, userId);
+    }
+
+    /**
+     * Non-Binder method, support for the backup/restore mechanism: write the default browser (etc)
+     * settings in its canonical XML format.  Returns the default browser XML representation as a
+     * byte array, or null if there is none.
+     */
+    @Override
+    @Deprecated
+    public final byte[] getDefaultAppsBackup(int userId) {
+        return mPreferredActivityHelper.getDefaultAppsBackup(userId);
+    }
+
+    @Override
+    @Deprecated
+    public final String getDefaultTextClassifierPackageName() {
+        return mService.mDefaultTextClassifierPackage;
+    }
+
+    @Override
+    @Deprecated
+    public final int getFlagsForUid(int uid) {
+        return snapshot().getFlagsForUid(uid);
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final CharSequence getHarmfulAppWarning(@NonNull String packageName,
+            @UserIdInt int userId) {
+        return snapshot().getHarmfulAppWarning(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
+        final Computer snapshot = snapshot();
+        if (snapshot.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+            return null;
+        }
+        return snapshot.getHomeActivitiesAsUser(allHomeCandidates,
+                UserHandle.getCallingUserId());
+    }
+
+    @Deprecated
+    public final String getIncidentReportApproverPackageName() {
+        return mService.mIncidentReportApproverPackage;
+    }
+
+    @Override
+    @Deprecated
+    public final int getInstallLocation() {
+        // allow instant app access
+        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
+                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
+                InstallLocationUtils.APP_INSTALL_AUTO);
+    }
+
+    @PackageManager.InstallReason
+    @Override
+    @Deprecated
+    public final int getInstallReason(@NonNull String packageName, @UserIdInt int userId) {
+        return snapshot().getInstallReason(packageName, userId);
+    }
+
+    @Override
+    @Nullable
+    @Deprecated
+    public final InstallSourceInfo getInstallSourceInfo(@NonNull String packageName) {
+        return snapshot().getInstallSourceInfo(packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final ParceledListSlice<ApplicationInfo> getInstalledApplications(
+            @PackageManager.ApplicationInfoFlagsBits long flags, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        return new ParceledListSlice<>(
+                snapshot().getInstalledApplications(flags, userId, callingUid));
+    }
+
+    @Override
+    @Deprecated
+    public final List<ModuleInfo> getInstalledModules(int flags) {
+        return mModuleInfoProvider.getInstalledModules(flags);
+    }
+
+    @Override
+    @Deprecated
+    public final ParceledListSlice<PackageInfo> getInstalledPackages(
+            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+        return snapshot().getInstalledPackages(flags, userId);
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final String getInstallerPackageName(@NonNull String packageName) {
+        return snapshot().getInstallerPackageName(packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final ComponentName getInstantAppInstallerComponent() {
+        final Computer snapshot = snapshot();
+        if (snapshot.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+            return null;
+        }
+        return snapshot.getInstantAppInstallerComponent();
+    }
+
+    @Override
+    @Deprecated
+    public final @Nullable
+    ComponentName getInstantAppResolverComponent() {
+        final Computer snapshot = snapshot();
+        if (snapshot.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+            return null;
+        }
+        return mService.getInstantAppResolver(snapshot);
+    }
+
+    @Override
+    @Deprecated
+    public final ComponentName getInstantAppResolverSettingsComponent() {
+        return mInstantAppResolverSettingsComponent;
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component,
+            int flags) {
+        return snapshot().getInstrumentationInfo(component, flags);
+    }
+
+    @Override
+    @Deprecated
+    public final @NonNull
+    ParceledListSlice<IntentFilterVerificationInfo>
+    getIntentFilterVerifications(String packageName) {
+        return ParceledListSlice.emptyList();
+    }
+
+    @Override
+    @Deprecated
+    public final int getIntentVerificationStatus(String packageName, int userId) {
+        return mDomainVerificationManager.getLegacyState(packageName, userId);
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias) {
+        return snapshot().getKeySetByAlias(packageName, alias);
+    }
+
+    @Override
+    @Deprecated
+    public final ModuleInfo getModuleInfo(String packageName,
+            @PackageManager.ModuleInfoFlags int flags) {
+        return mModuleInfoProvider.getModuleInfo(packageName, flags);
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final String getNameForUid(int uid) {
+        return snapshot().getNameForUid(uid);
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final String[] getNamesForUids(@NonNull int[] uids) {
+        return snapshot().getNamesForUids(uids);
+    }
+
+    @Override
+    @Deprecated
+    public final int[] getPackageGids(String packageName,
+            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+        return snapshot().getPackageGids(packageName, flags, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final PackageInfo getPackageInfo(String packageName,
+            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+        return snapshot().getPackageInfo(packageName, flags, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
+            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+        return snapshot().getPackageInfoInternal(versionedPackage.getPackageName(),
+                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
+    }
+
+    @Override
+    @Deprecated
+    public final IPackageInstaller getPackageInstaller() {
+        // Return installer service for internal calls.
+        if (PackageManagerServiceUtils.isSystemOrRoot()) {
+            return mInstallerService;
+        }
+        final Computer snapshot = snapshot();
+        // Return null for InstantApps.
+        if (snapshot.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+            return null;
+        }
+        return mInstallerService;
+    }
+
+    @Override
+    @Deprecated
+    public final void getPackageSizeInfo(final String packageName, int userId,
+            final IPackageStatsObserver observer) {
+        throw new UnsupportedOperationException(
+                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
+    }
+
+    @Override
+    @Deprecated
+    public final int getPackageUid(@NonNull String packageName,
+            @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) {
+        return snapshot().getPackageUid(packageName, flags, userId);
+    }
+
+    /**
+     * <em>IMPORTANT:</em> Not all packages returned by this method may be known
+     * to the system. There are two conditions in which this may occur:
+     * <ol>
+     *   <li>The package is on adoptable storage and the device has been removed</li>
+     *   <li>The package is being removed and the internal structures are partially updated</li>
+     * </ol>
+     * The second is an artifact of the current data structures and should be fixed. See
+     * b/111075456 for one such instance.
+     * This binder API is cached.  If the algorithm in this method changes,
+     * or if the underlying objecs (as returned by getSettingLPr()) change
+     * then the logic that invalidates the cache must be revisited.  See
+     * calls to invalidateGetPackagesForUidCache() to locate the points at
+     * which the cache is invalidated.
+     */
+    @Override
+    @Deprecated
+    public final String[] getPackagesForUid(int uid) {
+        final int callingUid = Binder.getCallingUid();
+        final int userId = UserHandle.getUserId(uid);
+        snapshot().enforceCrossUserOrProfilePermission(callingUid, userId,
+                /* requireFullPermission */ false,
+                /* checkShell */ false, "getPackagesForUid");
+        return snapshot().getPackagesForUid(uid);
+    }
+
+    @Override
+    @Deprecated
+    public final ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
+            @NonNull String[] permissions, @PackageManager.PackageInfoFlagsBits long flags,
+            @UserIdInt int userId) {
+        return snapshot().getPackagesHoldingPermissions(permissions, flags, userId);
+    }
+
+    // NOTE: Can't remove due to unsupported app usage
+    @Override
+    @Deprecated
+    public final PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
+        return mService.getPermissionGroupInfo(groupName, flags);
+    }
+
+    @Override
+    @Deprecated
+    public final @NonNull
+    ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
+        final Computer snapshot = snapshot();
+        if (snapshot.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+            return ParceledListSlice.emptyList();
+        }
+        return new ParceledListSlice<>(snapshot.getPersistentApplications(isSafeMode(), flags));
+    }
+
+    @Override
+    @Deprecated
+    public final int getPreferredActivities(List<IntentFilter> outFilters,
+            List<ComponentName> outActivities, String packageName) {
+        return mPreferredActivityHelper.getPreferredActivities(snapshot(), outFilters,
+                outActivities, packageName);
+    }
+
+    /**
+     * Non-Binder method, support for the backup/restore mechanism: write the full set of preferred
+     * activities in its canonical XML format.  Returns the XML output as a byte array, or null if
+     * there is none.
+     */
+    @Override
+    @Deprecated
+    public final byte[] getPreferredActivityBackup(int userId) {
+        return mPreferredActivityHelper.getPreferredActivityBackup(userId);
+    }
+
+    @Override
+    @Deprecated
+    public final int getPrivateFlagsForUid(int uid) {
+        return snapshot().getPrivateFlagsForUid(uid);
+    }
+
+    @Override
+    @Deprecated
+    public final PackageManager.Property getProperty(String propertyName, String packageName,
+            String className) {
+        Objects.requireNonNull(propertyName);
+        Objects.requireNonNull(packageName);
+        PackageStateInternal packageState = snapshot().getPackageStateFiltered(packageName,
+                Binder.getCallingUid(), UserHandle.getCallingUserId());
+        if (packageState == null) {
+            return null;
+        }
+        return mPackageProperty.getProperty(propertyName, packageName, className);
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final ProviderInfo getProviderInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
+        return snapshot().getProviderInfo(component, flags, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final ActivityInfo getReceiverInfo(ComponentName component,
+            @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
+        return snapshot().getReceiverInfo(component, flags, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final @Nullable
+    String getRotationResolverPackageName() {
+        return mService.ensureSystemPackageName(snapshot(),
+                mService.getPackageFromComponentString(
+                        R.string.config_defaultRotationResolverService));
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final ServiceInfo getServiceInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
+        return snapshot().getServiceInfo(component, flags, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final @NonNull
+    String getServicesSystemSharedLibraryPackageName() {
+        return mServicesExtensionPackageName;
+    }
+
+    @Override
+    @Deprecated
+    public final String getSetupWizardPackageName() {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("Non-system caller");
+        }
+        return mService.mSetupWizardPackage;
+    }
+
+    @Override
+    @Deprecated
+    public final ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
+            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+        return snapshot().getSharedLibraries(packageName, flags, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final @NonNull
+    String getSharedSystemSharedLibraryPackageName() {
+        return mSharedSystemSharedLibraryPackageName;
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final KeySet getSigningKeySet(@NonNull String packageName) {
+        return snapshot().getSigningKeySet(packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final String getSdkSandboxPackageName() {
+        return mService.getSdkSandboxPackageName();
+    }
+
+    @Override
+    @Deprecated
+    public final String getSystemCaptionsServicePackageName() {
+        return mService.ensureSystemPackageName(snapshot(),
+                mService.getPackageFromComponentString(
+                        R.string.config_defaultSystemCaptionsService));
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final String[] getSystemSharedLibraryNames() {
+        return snapshot().getSystemSharedLibraryNames();
+    }
+
+    @Override
+    @Deprecated
+    public final String getSystemTextClassifierPackageName() {
+        return mService.mSystemTextClassifierPackageName;
+    }
+
+    @Override
+    @Deprecated
+    public final int getTargetSdkVersion(@NonNull String packageName) {
+        return snapshot().getTargetSdkVersion(packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final int getUidForSharedUser(@NonNull String sharedUserName) {
+        return snapshot().getUidForSharedUser(sharedUserName);
+    }
+
+    @SuppressLint("MissingPermission")
+    @Override
+    @Deprecated
+    public final String getWellbeingPackageName() {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return CollectionUtils.firstOrNull(
+                    mContext.getSystemService(RoleManager.class).getRoleHolders(
+                            RoleManager.ROLE_SYSTEM_WELLBEING));
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    // NOTE: Can't remove due to unsupported app usage
+    @SuppressLint("MissingPermission")
+    @Override
+    @Deprecated
+    public final void grantRuntimePermission(String packageName, String permName,
+            final int userId) {
+        // Because this is accessed via the package manager service AIDL,
+        // go through the permission manager service AIDL
+        mContext.getSystemService(PermissionManager.class)
+                .grantRuntimePermission(packageName, permName, UserHandle.of(userId));
+    }
+
+    @Override
+    @Deprecated
+    public final boolean hasSigningCertificate(@NonNull String packageName,
+            @NonNull byte[] certificate,
+            @PackageManager.CertificateInputType int type) {
+        return snapshot().hasSigningCertificate(packageName, certificate, type);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean hasSystemFeature(String name, int version) {
+        return mService.hasSystemFeature(name, version);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean hasSystemUidErrors() {
+        // allow instant applications
+        return false;
+    }
+
+    @Override
+    @Deprecated
+    public final boolean hasUidSigningCertificate(int uid, @NonNull byte[] certificate,
+            @PackageManager.CertificateInputType int type) {
+        return snapshot().hasUidSigningCertificate(uid, certificate, type);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isDeviceUpgrading() {
+        return mService.isDeviceUpgrading();
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isFirstBoot() {
+        return mService.isFirstBoot();
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isInstantApp(String packageName, int userId) {
+        return snapshot().isInstantApp(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isOnlyCoreApps() {
+        return mService.isOnlyCoreApps();
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isPackageAvailable(String packageName, int userId) {
+        return snapshot().isPackageAvailable(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isPackageDeviceAdminOnAnyUser(String packageName) {
+        return mService.isPackageDeviceAdminOnAnyUser(snapshot(),
+                packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isPackageSignedByKeySet(@NonNull String packageName, @NonNull KeySet ks) {
+        return snapshot().isPackageSignedByKeySet(packageName, ks);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isPackageSignedByKeySetExactly(@NonNull String packageName,
+            @NonNull KeySet ks) {
+        return snapshot().isPackageSignedByKeySetExactly(packageName, ks);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isPackageSuspendedForUser(@NonNull String packageName,
+            @UserIdInt int userId) {
+        return snapshot().isPackageSuspendedForUser(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isSafeMode() {
+        // allow instant applications
+        return mService.getSafeMode();
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isStorageLow() {
+        return mService.isStorageLow();
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isUidPrivileged(int uid) {
+        return snapshot().isUidPrivileged(uid);
+    }
+
+    /**
+     * Ask the package manager to perform a dex-opt with the given compiler filter.
+     * <p>
+     * Note: exposed only for the shell command to allow moving packages explicitly to a definite
+     * state.
+     */
+    @Override
+    @Deprecated
+    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);
+    }
+
+    /**
+     * Ask the package manager to perform a dex-opt with the given compiler filter on the secondary
+     * dex files belonging to the given package.
+     * <p>
+     * Note: exposed only for the shell command to allow moving packages explicitly to a definite
+     * state.
+     */
+    @Override
+    @Deprecated
+    public final boolean performDexOptSecondary(String packageName, String compilerFilter,
+            boolean force) {
+        return mDexOptHelper.performDexOptSecondary(packageName, compilerFilter, force);
+    }
+
+    @Override
+    @Deprecated
+    public final @NonNull
+    ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
+            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+        try {
+            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
+
+            return new ParceledListSlice<>(snapshot().queryIntentActivitiesInternal(intent,
+                    resolvedType, flags, userId));
+        } finally {
+            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+        }
+    }
+
+    @NonNull
+    @Override
+    @Deprecated
+    public final ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable String processName,
+            int uid, @PackageManager.ComponentInfoFlagsBits long flags,
+            @Nullable String metaDataKey) {
+        return snapshot().queryContentProviders(processName, uid, flags, metaDataKey);
+    }
+
+    @NonNull
+    @Override
+    @Deprecated
+    public final ParceledListSlice<InstrumentationInfo> queryInstrumentation(
+            @NonNull String targetPackage, int flags) {
+        return snapshot().queryInstrumentation(targetPackage, flags);
+    }
+
+    @Override
+    @Deprecated
+    public final @NonNull
+    ParceledListSlice<ResolveInfo> queryIntentActivityOptions(
+            ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent,
+            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+        return new ParceledListSlice<>(mResolveIntentHelper.queryIntentActivityOptionsInternal(
+                snapshot(), caller, specifics, specificTypes, intent, resolvedType, flags,
+                userId));
+    }
+
+    @Override
+    @Deprecated
+    public final @NonNull
+    ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
+            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+        return new ParceledListSlice<>(mResolveIntentHelper.queryIntentContentProvidersInternal(
+                snapshot(), intent, resolvedType, flags, userId));
+    }
+
+    @Override
+    @Deprecated
+    public final @NonNull
+    ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
+            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+        return new ParceledListSlice<>(mResolveIntentHelper.queryIntentReceiversInternal(
+                snapshot(), intent, resolvedType, flags, userId, Binder.getCallingUid()));
+    }
+
+    @Override
+    @Deprecated
+    public final @NonNull
+    ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
+            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        return new ParceledListSlice<>(snapshot().queryIntentServicesInternal(
+                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
+    }
+
+    @Override
+    @Deprecated
+    public final void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
+        snapshot().querySyncProviders(isSafeMode(), outNames, outInfo);
+    }
+
+    @Override
+    @Deprecated
+    public final void removePermission(String permName) {
+        // Because this is accessed via the package manager service AIDL,
+        // go through the permission manager service AIDL
+        mContext.getSystemService(PermissionManager.class).removePermission(permName);
+    }
+
+    @Override
+    @Deprecated
+    public final void replacePreferredActivity(IntentFilter filter, int match,
+            ComponentName[] set, ComponentName activity, int userId) {
+        mPreferredActivityHelper.replacePreferredActivity(snapshot(),
+                new WatchedIntentFilter(filter), match, set, activity, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final ProviderInfo resolveContentProvider(String name,
+            @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+        return snapshot().resolveContentProvider(name, flags, userId, Binder.getCallingUid());
+    }
+
+    @Override
+    @Deprecated
+    public final void resetApplicationPreferences(int userId) {
+        mPreferredActivityHelper.resetApplicationPreferences(userId);
+    }
+
+    @Override
+    @Deprecated
+    public final ResolveInfo resolveIntent(Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+        return mResolveIntentHelper.resolveIntentInternal(snapshot(), intent,
+                resolvedType, flags, 0 /*privateResolveFlags*/, userId, false,
+                Binder.getCallingUid());
+    }
+
+    @Override
+    @Deprecated
+    public final ResolveInfo resolveService(Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        return mResolveIntentHelper.resolveServiceInternal(snapshot(), intent,
+                resolvedType, flags, userId, callingUid);
+    }
+
+    @Override
+    @Deprecated
+    public final void restoreDefaultApps(byte[] backup, int userId) {
+        mPreferredActivityHelper.restoreDefaultApps(backup, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void restorePreferredActivities(byte[] backup, int userId) {
+        mPreferredActivityHelper.restorePreferredActivities(backup, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void setHomeActivity(ComponentName comp, int userId) {
+        mPreferredActivityHelper.setHomeActivity(snapshot(), comp, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void setLastChosenActivity(Intent intent, String resolvedType, int flags,
+            IntentFilter filter, int match, ComponentName activity) {
+        mPreferredActivityHelper.setLastChosenActivity(snapshot(), intent, resolvedType,
+                flags, new WatchedIntentFilter(filter), match, activity);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean updateIntentVerificationStatus(String packageName, int status,
+            int userId) {
+        return mDomainVerificationManager.setLegacyUserState(packageName, userId, status);
+    }
+
+    @Override
+    @Deprecated
+    public final void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
+        DomainVerificationProxyV1.queueLegacyVerifyResult(mContext, mDomainVerificationConnection,
+                id, verificationCode, failedDomains, Binder.getCallingUid());
+    }
+
+    @Override
+    @Deprecated
+    public final boolean canPackageQuery(@NonNull String sourcePackageName,
+            @NonNull String targetPackageName, @UserIdInt int userId) {
+        return snapshot().canPackageQuery(sourcePackageName, targetPackageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void deletePreloadsFileCache() throws RemoteException {
+        mService.deletePreloadsFileCache();
+    }
+
+    @Override
+    @Deprecated
+    public final void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden)
+            throws RemoteException {
+        mService.setSystemAppHiddenUntilInstalled(snapshot(), packageName, hidden);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean setSystemAppInstallState(String packageName,
+            boolean installed, int userId) throws RemoteException {
+        return mService.setSystemAppInstallState(snapshot(), packageName, installed, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void finishPackageInstall(int token, boolean didLaunch) throws RemoteException {
+        mService.finishPackageInstall(token, didLaunch);
+    }
+}
diff --git a/services/core/java/com/android/server/pm/IncrementalProgressListener.java b/services/core/java/com/android/server/pm/IncrementalProgressListener.java
index fa11924..703bbda 100644
--- a/services/core/java/com/android/server/pm/IncrementalProgressListener.java
+++ b/services/core/java/com/android/server/pm/IncrementalProgressListener.java
@@ -33,7 +33,8 @@
 
     @Override
     public void onPackageLoadingProgressChanged(float progress) {
-        PackageStateInternal packageState = mPm.getPackageStateInternal(mPackageName);
+        PackageStateInternal packageState = mPm.snapshotComputer()
+                .getPackageStateInternal(mPackageName);
         if (packageState == null) {
             return;
         }
diff --git a/services/core/java/com/android/server/pm/InitAndSystemPackageHelper.java b/services/core/java/com/android/server/pm/InitAndSystemPackageHelper.java
index 6dbe9b6..91750de 100644
--- a/services/core/java/com/android/server/pm/InitAndSystemPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InitAndSystemPackageHelper.java
@@ -30,6 +30,7 @@
 import static com.android.server.pm.PackageManagerService.SCAN_REQUIRE_KNOWN;
 import static com.android.server.pm.PackageManagerService.SYSTEM_PARTITIONS;
 import static com.android.server.pm.PackageManagerService.TAG;
+import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_CHECK_MAX_SDK_VERSION;
 
 import android.annotation.Nullable;
 import android.content.pm.parsing.ApkLiteParseUtils;
@@ -170,7 +171,7 @@
             }
         }
         OverlayConfig overlayConfig = OverlayConfig.initializeSystemInstance(
-                consumer -> mPm.forEachPackage(
+                consumer -> mPm.forEachPackage(mPm.snapshotComputer(),
                         pkg -> consumer.accept(pkg, pkg.isSystem(),
                           apkInApexPreInstalledPaths.get(pkg.getPackageName()))));
         // Prune any system packages that no longer exist.
@@ -313,10 +314,14 @@
 
     @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
     private void scanDirTracedLI(File scanDir, List<File> frameworkSplits,
-            final int parseFlags, int scanFlags,
+            int parseFlags, int scanFlags,
             long currentTime, PackageParser2 packageParser, ExecutorService executorService) {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
         try {
+            if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
+                // when scanning apk in apexes, we want to check the maxSdkVersion
+                parseFlags |= PARSE_CHECK_MAX_SDK_VERSION;
+            }
             mInstallPackageHelper.installPackagesFromDir(scanDir, frameworkSplits, parseFlags,
                     scanFlags, currentTime, packageParser, executorService);
         } finally {
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index a780f3c..b39b24f 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -86,6 +86,7 @@
 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
+import static com.android.server.pm.SharedUidMigration.BEST_EFFORT;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -287,6 +288,12 @@
         SharedUserSetting sharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(pkgSetting);
         if (sharedUserSetting != null) {
             sharedUserSetting.addPackage(pkgSetting);
+            if (parsedPackage.isLeavingSharedUid()
+                    && SharedUidMigration.applyStrategy(BEST_EFFORT)
+                    && sharedUserSetting.isSingleUser()) {
+                // Attempt the transparent shared UID migration
+                mPm.mSettings.convertSharedUserSettingsLPw(sharedUserSetting);
+            }
         }
         if (reconciledPkg.mInstallArgs != null
                 && reconciledPkg.mInstallArgs.mForceQueryableOverride) {
@@ -520,8 +527,10 @@
                     + android.Manifest.permission.INSTALL_PACKAGES + ".");
         }
         PackageSetting pkgSetting;
-        mPm.enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
-                true /* checkShell */, "installExistingPackage for user " + userId);
+        final Computer preLockSnapshot = mPm.snapshotComputer();
+        preLockSnapshot.enforceCrossUserPermission(callingUid, userId,
+                true /* requireFullPermission */, true /* checkShell */,
+                "installExistingPackage for user " + userId);
         if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
         }
@@ -536,11 +545,12 @@
 
             // writer
             synchronized (mPm.mLock) {
+                final Computer snapshot = mPm.snapshotComputer();
                 pkgSetting = mPm.mSettings.getPackageLPr(packageName);
                 if (pkgSetting == null) {
                     return PackageManager.INSTALL_FAILED_INVALID_URI;
                 }
-                if (!mPm.canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
+                if (!snapshot.canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
                     // only allow the existing package to be used if it's installed as a full
                     // application for at least one user
                     boolean installAllowed = false;
@@ -590,7 +600,8 @@
                         mAppDataHelper.prepareAppDataAfterInstallLIF(pkgSetting.getPkg());
                     }
                 }
-                mPm.sendPackageAddedForUser(packageName, pkgSetting, userId, DataLoaderType.NONE);
+                mPm.sendPackageAddedForUser(mPm.snapshotComputer(), packageName, pkgSetting, userId,
+                        DataLoaderType.NONE);
                 synchronized (mPm.mLock) {
                     mPm.updateSequenceNumberLP(pkgSetting, new int[]{ userId });
                 }
@@ -951,10 +962,6 @@
                     createdAppId.put(packageName, optimisticallyRegisterAppId(result));
                     versionInfos.put(result.mPkgSetting.getPkg().getPackageName(),
                             mPm.getSettingsVersionForPackage(result.mPkgSetting.getPkg()));
-                    if (result.needsNewAppId()) {
-                        request.mInstallResult.mRemovedInfo.mNewAppId =
-                                result.mPkgSetting.getAppId();
-                    }
                 } catch (PackageManagerException e) {
                     request.mInstallResult.setError("Scanning Failed.", e);
                     return;
@@ -1899,8 +1906,8 @@
                 AndroidPackage oldPackage = mPm.mPackages.get(packageName);
 
                 // Set the update and install times
-                PackageStateInternal deletedPkgSetting = mPm.getPackageStateInternal(
-                        oldPackage.getPackageName());
+                PackageStateInternal deletedPkgSetting = mPm.snapshotComputer()
+                        .getPackageStateInternal(oldPackage.getPackageName());
                 reconciledPkg.mPkgSetting
                         .setFirstInstallTimeFromReplaced(deletedPkgSetting, request.mAllUsers)
                         .setLastUpdateTime(System.currentTimeMillis());
@@ -2216,23 +2223,8 @@
                 }
                 incrementalStorages.add(storage);
             }
-            int previousAppId = 0;
-            if (reconciledPkg.mScanResult.needsNewAppId()) {
-                // Only set previousAppId if the app is migrating out of shared UID
-                previousAppId = reconciledPkg.mScanResult.mPreviousAppId;
-
-                if (pkg.shouldInheritKeyStoreKeys()) {
-                    // Migrate keystore data
-                    mAppDataHelper.migrateKeyStoreData(
-                            previousAppId, reconciledPkg.mPkgSetting.getAppId());
-                }
-
-                if (reconciledPkg.mInstallResult.mRemovedInfo.mRemovedAppId == previousAppId) {
-                    // If the previous app ID is removed, clear the keys
-                    mAppDataHelper.clearKeystoreData(UserHandle.USER_ALL, previousAppId);
-                }
-            }
-            mAppDataHelper.prepareAppDataPostCommitLIF(pkg, previousAppId);
+            // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
+            mAppDataHelper.prepareAppDataPostCommitLIF(pkg, 0);
             if (reconciledPkg.mPrepareResult.mClearCodeCache) {
                 mAppDataHelper.clearAppDataLIF(pkg, UserHandle.USER_ALL,
                         FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
@@ -2583,9 +2575,10 @@
             size = i;
             mPm.mPendingBroadcasts.clear();
         }
+        final Computer snapshot = mPm.snapshotComputer();
         // Send broadcasts
         for (int i = 0; i < size; i++) {
-            mPm.sendPackageChangedBroadcast(packages[i], true /* dontKillApp */,
+            mPm.sendPackageChangedBroadcast(snapshot, packages[i], true /* dontKillApp */,
                     components[i], uids[i], null /* reason */);
         }
         Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
@@ -2602,11 +2595,9 @@
         final int dataLoaderType = installArgs.mDataLoaderType;
         final boolean succeeded = res.mReturnCode == PackageManager.INSTALL_SUCCEEDED;
         final boolean update = res.mRemovedInfo != null && res.mRemovedInfo.mRemovedPackage != null;
-        final int previousAppId = (res.mRemovedInfo != null && res.mRemovedInfo.mNewAppId >= 0)
-                ? res.mRemovedInfo.mUid : Process.INVALID_UID;
         final String packageName = res.mName;
         final PackageStateInternal pkgSetting =
-                succeeded ? mPm.getPackageStateInternal(packageName) : null;
+                succeeded ? mPm.snapshotComputer().getPackageStateInternal(packageName) : null;
         final boolean removedBeforeUpdate = (pkgSetting == null)
                 || (pkgSetting.isSystem() && !pkgSetting.getPath().getPath().equals(
                 res.mPkg.getPath()));
@@ -2704,17 +2695,14 @@
                 // sendPackageAddedForNewUsers also deals with system apps
                 int appId = UserHandle.getAppId(res.mUid);
                 boolean isSystem = res.mPkg.isSystem();
-                mPm.sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
-                        virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds,
-                        dataLoaderType);
+                mPm.sendPackageAddedForNewUsers(mPm.snapshotComputer(), packageName,
+                        isSystem || virtualPreload, virtualPreload /*startReceiver*/, appId,
+                        firstUserIds, firstInstantUserIds, dataLoaderType);
 
                 // Send added for users that don't see the package for the first time
                 Bundle extras = new Bundle();
                 extras.putInt(Intent.EXTRA_UID, res.mUid);
-                if (previousAppId != Process.INVALID_UID) {
-                    extras.putBoolean(Intent.EXTRA_UID_CHANGING, true);
-                    extras.putInt(Intent.EXTRA_PREVIOUS_UID, previousAppId);
-                } else if (update) {
+                if (update) {
                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
                 }
                 extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
@@ -2722,7 +2710,8 @@
                 final SparseArray<int[]> newBroadcastAllowList;
                 synchronized (mPm.mLock) {
                     newBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList(
-                            mPm.getPackageStateInternal(packageName, Process.SYSTEM_UID),
+                            mPm.snapshotComputer()
+                                    .getPackageStateInternal(packageName, Process.SYSTEM_UID),
                             updateUserIds, mPm.mSettings.getPackagesLocked());
                 }
                 mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
@@ -2757,27 +2746,24 @@
 
                 // Send replaced for users that don't see the package for the first time
                 if (update) {
-                    // Only send PACKAGE_REPLACED if appId has not changed
-                    if (previousAppId == Process.INVALID_UID) {
-                        mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
-                                packageName, extras, 0 /*flags*/,
-                                null /*targetPackage*/, null /*finishedReceiver*/,
-                                updateUserIds, instantUserIds, res.mRemovedInfo.mBroadcastAllowList,
+                    mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
+                            packageName, extras, 0 /*flags*/,
+                            null /*targetPackage*/, null /*finishedReceiver*/,
+                            updateUserIds, instantUserIds, res.mRemovedInfo.mBroadcastAllowList,
+                            null);
+                    if (installerPackageName != null) {
+                        mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
+                                extras, 0 /*flags*/,
+                                installerPackageName, null /*finishedReceiver*/,
+                                updateUserIds, instantUserIds, null /*broadcastAllowList*/,
                                 null);
-                        if (installerPackageName != null) {
-                            mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
-                                    extras, 0 /*flags*/,
-                                    installerPackageName, null /*finishedReceiver*/,
-                                    updateUserIds, instantUserIds, null /*broadcastAllowList*/,
-                                    null);
-                        }
-                        if (notifyVerifier) {
-                            mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
-                                    extras, 0 /*flags*/,
-                                    mPm.mRequiredVerifierPackage, null /*finishedReceiver*/,
-                                    updateUserIds, instantUserIds, null /*broadcastAllowList*/,
-                                    null);
-                        }
+                    }
+                    if (notifyVerifier) {
+                        mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
+                                extras, 0 /*flags*/,
+                                mPm.mRequiredVerifierPackage, null /*finishedReceiver*/,
+                                updateUserIds, instantUserIds, null /*broadcastAllowList*/,
+                                null);
                     }
                     mPm.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
                             null /*package*/, null /*extras*/, 0 /*flags*/,
@@ -2827,11 +2813,12 @@
                 }
             } else if (!ArrayUtils.isEmpty(res.mLibraryConsumers)) { // if static shared lib
                 // No need to kill consumers if it's installation of new version static shared lib.
+                final Computer snapshot = mPm.snapshotComputer();
                 final boolean dontKillApp = !update && res.mPkg.getStaticSharedLibName() != null;
                 for (int i = 0; i < res.mLibraryConsumers.size(); i++) {
                     AndroidPackage pkg = res.mLibraryConsumers.get(i);
                     // send broadcast that all consumers of the static shared library have changed
-                    mPm.sendPackageChangedBroadcast(pkg.getPackageName(), dontKillApp,
+                    mPm.sendPackageChangedBroadcast(snapshot, pkg.getPackageName(), dontKillApp,
                             new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
                             pkg.getUid(), null);
                 }
@@ -2875,13 +2862,14 @@
                 VMRuntime.getRuntime().requestConcurrentGC();
             }
 
+            final Computer snapshot = mPm.snapshotComputer();
             // Notify DexManager that the package was installed for new users.
             // The updated users should already be indexed and the package code paths
             // should not change.
             // Don't notify the manager for ephemeral apps as they are not expected to
             // survive long enough to benefit of background optimizations.
             for (int userId : firstUserIds) {
-                PackageInfo info = mPm.getPackageInfo(packageName, /*flags*/ 0, userId);
+                PackageInfo info = snapshot.getPackageInfo(packageName, /*flags*/ 0, userId);
                 // There's a race currently where some install events may interleave with an
                 // uninstall. This can lead to package info being null (b/36642664).
                 if (info != null) {
@@ -2988,7 +2976,6 @@
      * APK will be installed and the package will be disabled. To recover from this situation,
      * the user will need to go into system settings and re-enable the package.
      */
-    @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
     boolean enableCompressedPackage(AndroidPackage stubPkg,
             @NonNull PackageSetting stubPkgSetting) {
         final int parseFlags = mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_CHATTY
@@ -2998,8 +2985,8 @@
             try (PackageFreezer freezer =
                          mPm.freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
                 pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/);
+                mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
                 synchronized (mPm.mLock) {
-                    mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
                     try {
                         mSharedLibraries.updateSharedLibrariesLPw(
                                 pkg, stubPkgSetting, null, null,
@@ -3027,8 +3014,7 @@
                     installPackageFromSystemLIF(stubPkg.getPath(),
                             mPm.mUserManager.getUserIds() /*allUserHandles*/,
                             null /*origUserHandles*/,
-                            true /*writeSettings*/,
-                            Process.INVALID_UID /*previousAppId*/);
+                            true /*writeSettings*/);
                 } catch (PackageManagerException pme) {
                     // Serious WTF; we have to be able to install the stub
                     Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(),
@@ -3056,7 +3042,7 @@
         return true;
     }
 
-    @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
+    @GuardedBy("mPm.mInstallLock")
     private AndroidPackage installStubPackageLI(AndroidPackage stubPkg,
             @ParsingPackageUtils.ParseFlags int parseFlags,
             @PackageManagerService.ScanFlags int scanFlags)
@@ -3149,27 +3135,26 @@
             mPm.mSettings.enableSystemPackageLPw(disabledPs.getPkg().getPackageName());
             // Remove any native libraries from the upgraded package.
             PackageManagerServiceUtils.removeNativeBinariesLI(deletedPs);
-
-            // Install the system package
-            if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
-            try {
-                synchronized (mPm.mInstallLock) {
-                    final int[] origUsers = outInfo == null ? null : outInfo.mOrigUsers;
-                    final int previousAppId = disabledPs.getAppId() != deletedPs.getAppId()
-                            ? deletedPs.getAppId() : Process.INVALID_UID;
-                    installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles,
-                            origUsers, writeSettings, previousAppId);
-                }
-            } catch (PackageManagerException e) {
-                Slog.w(TAG, "Failed to restore system package:" + deletedPs.getPackageName() + ": "
-                        + e.getMessage());
-                // TODO(b/194319951): can we avoid this; throw would come from scan...
-                throw new SystemDeleteException(e);
-            } finally {
-                if (disabledPs.getPkg().isStub()) {
-                    // We've re-installed the stub; make sure it's disabled here. If package was
-                    // originally enabled, we'll install the compressed version of the application
-                    // and re-enable it afterward.
+        }
+        // Install the system package
+        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
+        try {
+            synchronized (mPm.mInstallLock) {
+                final int[] origUsers = outInfo == null ? null : outInfo.mOrigUsers;
+                installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles,
+                        origUsers, writeSettings);
+            }
+        } catch (PackageManagerException e) {
+            Slog.w(TAG, "Failed to restore system package:" + deletedPs.getPackageName() + ": "
+                    + e.getMessage());
+            // TODO(b/194319951): can we avoid this; throw would come from scan...
+            throw new SystemDeleteException(e);
+        } finally {
+            if (disabledPs.getPkg().isStub()) {
+                // We've re-installed the stub; make sure it's disabled here. If package was
+                // originally enabled, we'll install the compressed version of the application
+                // and re-enable it afterward.
+                synchronized (mPm.mLock) {
                     disableStubPackage(action, deletedPs, allUserHandles);
                 }
             }
@@ -3197,10 +3182,10 @@
     /**
      * Installs a package that's already on the system partition.
      */
-    @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
+    @GuardedBy("mPm.mInstallLock")
     private void installPackageFromSystemLIF(@NonNull String codePathString,
             @NonNull int[] allUserHandles, @Nullable int[] origUserHandles,
-            boolean writeSettings, int previousAppId)
+            boolean writeSettings)
             throws PackageManagerException {
         final File codePath = new File(codePathString);
         @ParsingPackageUtils.ParseFlags int parseFlags =
@@ -3223,13 +3208,12 @@
 
         mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
 
-        setPackageInstalledForSystemPackage(pkg, allUserHandles,
-                origUserHandles, writeSettings, previousAppId);
+        setPackageInstalledForSystemPackage(pkg, allUserHandles, origUserHandles, writeSettings);
     }
 
     private void setPackageInstalledForSystemPackage(@NonNull AndroidPackage pkg,
             @NonNull int[] allUserHandles, @Nullable int[] origUserHandles,
-            boolean writeSettings, int previousAppId) {
+            boolean writeSettings) {
         // writer
         synchronized (mPm.mLock) {
             PackageSetting ps = mPm.mSettings.getPackageLPr(pkg.getPackageName());
@@ -3263,7 +3247,7 @@
 
             // The method below will take care of removing obsolete permissions and granting
             // install permissions.
-            mPm.mPermissionManager.onPackageInstalled(pkg, previousAppId,
+            mPm.mPermissionManager.onPackageInstalled(pkg, Process.INVALID_UID,
                     PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT,
                     UserHandle.USER_ALL);
             for (final int userId : allUserHandles) {
@@ -3701,7 +3685,14 @@
             }
             disabledPkgSetting = mPm.mSettings.getDisabledSystemPkgLPr(
                     parsedPackage.getPackageName());
-            if (parsedPackage.getSharedUserId() != null && !parsedPackage.isLeavingSharedUid()) {
+
+            boolean ignoreSharedUserId = false;
+            if (installedPkgSetting == null) {
+                // We can directly ignore sharedUserSetting for new installs
+                ignoreSharedUserId = parsedPackage.isLeavingSharedUid();
+            }
+
+            if (!ignoreSharedUserId && parsedPackage.getSharedUserId() != null) {
                 sharedUserSetting = mPm.mSettings.getSharedUserLPw(
                         parsedPackage.getSharedUserId(),
                         0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
diff --git a/services/core/java/com/android/server/pm/InstallParams.java b/services/core/java/com/android/server/pm/InstallParams.java
index 6c80976..18d2b0c 100644
--- a/services/core/java/com/android/server/pm/InstallParams.java
+++ b/services/core/java/com/android/server/pm/InstallParams.java
@@ -289,8 +289,8 @@
      */
     private int fixUpInstallReason(String installerPackageName, int installerUid,
             int installReason) {
-        if (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
-                == PERMISSION_GRANTED) {
+        if (mPm.snapshotComputer().checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES,
+                installerUid) == PERMISSION_GRANTED) {
             // If the install is being performed by a system app, we trust that app to have set the
             // install reason correctly.
             return installReason;
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 742cc02..76b9830 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -92,6 +92,7 @@
     public static final int FLAG_STORAGE_DE = IInstalld.FLAG_STORAGE_DE;
     public static final int FLAG_STORAGE_CE = IInstalld.FLAG_STORAGE_CE;
     public static final int FLAG_STORAGE_EXTERNAL = IInstalld.FLAG_STORAGE_EXTERNAL;
+    public static final int FLAG_STORAGE_SDK = IInstalld.FLAG_STORAGE_SDK;
 
     public static final int FLAG_CLEAR_CACHE_ONLY = IInstalld.FLAG_CLEAR_CACHE_ONLY;
     public static final int FLAG_CLEAR_CODE_CACHE_ONLY = IInstalld.FLAG_CLEAR_CODE_CACHE_ONLY;
@@ -190,12 +191,16 @@
     // We explicitly do NOT set previousAppId because the default value should always be 0.
     // Manually override previousAppId after building CreateAppDataArgs for specific behaviors.
     static CreateAppDataArgs buildCreateAppDataArgs(String uuid, String packageName,
-            int userId, int flags, int appId, String seInfo, int targetSdkVersion) {
+            int userId, int flags, int appId, String seInfo, int targetSdkVersion,
+            boolean usesSdk) {
         final CreateAppDataArgs args = new CreateAppDataArgs();
         args.uuid = uuid;
         args.packageName = packageName;
         args.userId = userId;
         args.flags = flags;
+        if (usesSdk) {
+            args.flags |= FLAG_STORAGE_SDK;
+        }
         args.appId = appId;
         args.seInfo = seInfo;
         args.targetSdkVersion = targetSdkVersion;
@@ -215,6 +220,8 @@
         if (!checkBeforeRemote()) {
             return buildPlaceholderCreateAppDataResult();
         }
+        // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
+        args.previousAppId = 0;
         try {
             return mInstalld.createAppData(args);
         } catch (Exception e) {
@@ -229,6 +236,10 @@
             Arrays.fill(results, buildPlaceholderCreateAppDataResult());
             return results;
         }
+        // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088)
+        for (final CreateAppDataArgs arg : args) {
+            arg.previousAppId = 0;
+        }
         try {
             return mInstalld.createAppDataBatched(args);
         } catch (Exception e) {
diff --git a/services/core/java/com/android/server/pm/IntentResolverInterceptor.java b/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
new file mode 100644
index 0000000..0ee07b6
--- /dev/null
+++ b/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
@@ -0,0 +1,126 @@
+/*
+ * 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.pm;
+
+import static com.android.server.wm.ActivityInterceptorCallback.INTENT_RESOLVER_ORDERED_ID;
+
+import android.Manifest;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.app.ActivityTaskManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.RemoteException;
+import android.provider.DeviceConfig;
+import android.util.Slog;
+
+import com.android.internal.R;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.server.LocalServices;
+import com.android.server.wm.ActivityInterceptorCallback;
+import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptorInfo;
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+/**
+ * Service to register an {@code ActivityInterceptorCallback} that modifies any {@code Intent}
+ * that's being used to launch a user-space {@code ChooserActivity}, by adding
+ * EXTRA_PERMISSION_TOKEN, a Binder representing a single-use-only permission to invoke the
+ * #startActivityAsCaller() API (which normally isn't available in user-space); and setting the
+ * destination component to the delegated component when appropriate.
+ */
+public final class IntentResolverInterceptor {
+    private static final String TAG = "IntentResolverIntercept";
+
+    private final Context mContext;
+    private boolean mUseDelegateChooser;
+
+    private final ActivityInterceptorCallback mActivityInterceptorCallback =
+            new ActivityInterceptorCallback() {
+                @Nullable
+                @Override
+                public ActivityInterceptResult intercept(ActivityInterceptorInfo info) {
+                    if (mUseDelegateChooser && isChooserActivity(info)) {
+                        return new ActivityInterceptResult(
+                                modifyChooserIntent(info.intent),
+                                info.checkedOptions);
+                    }
+                    return null;
+                }
+            };
+
+    public IntentResolverInterceptor(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Start listening for intents and USE_DELEGATE_CHOOSER property changes.
+     */
+    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
+    public void registerListeners() {
+        LocalServices.getService(ActivityTaskManagerInternal.class)
+                .registerActivityStartInterceptor(INTENT_RESOLVER_ORDERED_ID,
+                        mActivityInterceptorCallback);
+
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
+                mContext.getMainExecutor(), properties -> updateUseDelegateChooser());
+        updateUseDelegateChooser();
+    }
+
+    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
+    private void updateUseDelegateChooser() {
+        mUseDelegateChooser = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.USE_DELEGATE_CHOOSER,
+                false);
+    }
+
+    private Intent modifyChooserIntent(Intent intent) {
+        intent.setComponent(getUnbundledChooserComponentName());
+        addStartActivityPermissionTokenToIntent(intent, getUnbundledChooserComponentName());
+        return intent;
+    }
+
+    private static boolean isChooserActivity(ActivityInterceptorInfo info) {
+        ComponentName targetComponent = new ComponentName(info.aInfo.packageName, info.aInfo.name);
+
+        return targetComponent.equals(getSystemChooserComponentName())
+                || targetComponent.equals(getUnbundledChooserComponentName());
+    }
+
+    private static Intent addStartActivityPermissionTokenToIntent(
+            Intent intent, ComponentName grantee) {
+        try {
+            intent.putExtra(
+                    ActivityTaskManager.EXTRA_PERMISSION_TOKEN,
+                    ActivityTaskManager.getService().requestStartActivityPermissionToken(grantee));
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Failed to add permission token to chooser intent");
+        }
+        return intent;
+    }
+
+    private static ComponentName getSystemChooserComponentName() {
+        return new ComponentName("android", "com.android.internal.app.ChooserActivity");
+    }
+
+    private static ComponentName getUnbundledChooserComponentName() {
+        return ComponentName.unflattenFromString(
+                Resources.getSystem().getString(R.string.config_chooserActivity));
+    }
+}
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 6b3ce77..5e0fc3b 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -320,8 +320,12 @@
 
         private PackageInstallerService getPackageInstallerService() {
             if (mPackageInstallerService == null) {
-                mPackageInstallerService = ((PackageInstallerService) ((PackageManagerService)
-                        ServiceManager.getService("package")).getPackageInstaller());
+                try {
+                    mPackageInstallerService = ((PackageInstallerService) ((IPackageManager)
+                            ServiceManager.getService("package")).getPackageInstaller());
+                } catch (RemoteException e) {
+                    Slog.wtf(TAG, "Error gettig IPackageInstaller", e);
+                }
             }
             return mPackageInstallerService;
         }
@@ -1109,13 +1113,11 @@
             // Note the target activity doesn't have to be exported.
 
             // Flag for bubble
-            if (startActivityOptions != null) {
-                ActivityOptions options = ActivityOptions.fromBundle(startActivityOptions);
-                if (options.isApplyActivityFlagsForBubbles()) {
-                    // Flag for bubble to make behaviour match documentLaunchMode=always.
-                    intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT);
-                    intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
-                }
+            ActivityOptions options = ActivityOptions.fromBundle(startActivityOptions);
+            if (options != null && options.isApplyActivityFlagsForBubbles()) {
+                // Flag for bubble to make behaviour match documentLaunchMode=always.
+                intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT);
+                intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
             }
 
             intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/services/core/java/com/android/server/pm/ModuleInfoProvider.java b/services/core/java/com/android/server/pm/ModuleInfoProvider.java
index 0ffc1ed..230f555 100644
--- a/services/core/java/com/android/server/pm/ModuleInfoProvider.java
+++ b/services/core/java/com/android/server/pm/ModuleInfoProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.server.pm;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.content.pm.IPackageManager;
 import android.content.pm.ModuleInfo;
@@ -25,6 +26,7 @@
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -58,7 +60,7 @@
     private static final String MODULE_METADATA_KEY = "android.content.pm.MODULE_METADATA";
 
     private final Context mContext;
-    private final IPackageManager mPackageManager;
+    private IPackageManager mPackageManager;
     private final ApexManager mApexManager;
     private final Map<String, ModuleInfo> mModuleInfo;
 
@@ -66,9 +68,8 @@
     private volatile boolean mMetadataLoaded;
     private volatile String mPackageName;
 
-    ModuleInfoProvider(Context context, IPackageManager packageManager) {
+    ModuleInfoProvider(Context context) {
         mContext = context;
-        mPackageManager = packageManager;
         mApexManager = ApexManager.getInstance();
         mModuleInfo = new ArrayMap<>();
     }
@@ -77,12 +78,20 @@
     public ModuleInfoProvider(
             XmlResourceParser metadata, Resources resources, ApexManager apexManager) {
         mContext = null;
-        mPackageManager = null;
         mApexManager = apexManager;
         mModuleInfo = new ArrayMap<>();
         loadModuleMetadata(metadata, resources);
     }
 
+    @NonNull
+    private IPackageManager getPackageManager() {
+        if (mPackageManager == null) {
+            mPackageManager = IPackageManager.Stub.asInterface(
+                    ServiceManager.getService("package"));
+        }
+        return mPackageManager;
+    }
+
     /** Called by the {@code PackageManager} when it has completed its boot sequence */
     public void systemReady() {
         mPackageName = mContext.getResources().getString(
@@ -95,7 +104,7 @@
         final Resources packageResources;
         final PackageInfo pi;
         try {
-            pi = mPackageManager.getPackageInfo(mPackageName,
+            pi =  getPackageManager().getPackageInfo(mPackageName,
                 PackageManager.GET_META_DATA, UserHandle.USER_SYSTEM);
 
             Context packageContext = mContext.createPackageContext(mPackageName, 0);
@@ -183,7 +192,7 @@
 
         List<PackageInfo> allPackages;
         try {
-            allPackages = mPackageManager.getInstalledPackages(
+            allPackages =  getPackageManager().getInstalledPackages(
                     flags | PackageManager.MATCH_APEX, UserHandle.getCallingUserId()).getList();
         } catch (RemoteException e) {
             Slog.w(TAG, "Unable to retrieve all package names", e);
diff --git a/services/core/java/com/android/server/pm/MovePackageHelper.java b/services/core/java/com/android/server/pm/MovePackageHelper.java
index 5fc90b1..c5ca06c 100644
--- a/services/core/java/com/android/server/pm/MovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/MovePackageHelper.java
@@ -57,6 +57,8 @@
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
+import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.pkg.PackageStateUtils;
 
 import java.io.File;
 import java.util.Objects;
@@ -77,81 +79,74 @@
         final StorageManager storage = mPm.mInjector.getSystemService(StorageManager.class);
         final PackageManager pm = mPm.mContext.getPackageManager();
 
-        final String currentVolumeUuid;
-        final File codeFile;
-        final InstallSource installSource;
-        final String packageAbiOverride;
-        final int appId;
-        final String seinfo;
-        final String label;
-        final int targetSdkVersion;
-        final PackageFreezer freezer;
-        final int[] installedUserIds;
-        final boolean isCurrentLocationExternal;
+        Computer snapshot = mPm.snapshotComputer();
+        final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
+        if (packageState == null
+                || packageState.getPkg() == null
+                || snapshot.shouldFilterApplication(packageState, callingUid, user.getIdentifier())) {
+            throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
+        }
+        final AndroidPackage pkg = packageState.getPkg();
+        if (pkg.isSystem()) {
+            throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
+                    "Cannot move system application");
+        }
+
+        final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
+        final boolean allow3rdPartyOnInternal = mPm.mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
+        if (isInternalStorage && !allow3rdPartyOnInternal) {
+            throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
+                    "3rd party apps are not allowed on internal storage");
+        }
+
+
+        final String currentVolumeUuid = packageState.getVolumeUuid();
+
+        final File probe = new File(pkg.getPath());
+        final File probeOat = new File(probe, "oat");
+        if (!probe.isDirectory() || !probeOat.isDirectory()) {
+            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
+                    "Move only supported for modern cluster style installs");
+        }
+
+        if (Objects.equals(currentVolumeUuid, volumeUuid)) {
+            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
+                    "Package already moved to " + volumeUuid);
+        }
+        if (!pkg.isExternalStorage()
+                && mPm.isPackageDeviceAdminOnAnyUser(snapshot, packageName)) {
+            throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
+                    "Device admin cannot be moved");
+        }
+
+        if (snapshot.getFrozenPackages().containsKey(packageName)) {
+            throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
+                    "Failed to move already frozen package");
+        }
+
+        final boolean isCurrentLocationExternal = pkg.isExternalStorage();
+        final File codeFile = new File(pkg.getPath());
+        final InstallSource installSource = packageState.getInstallSource();
+        final String packageAbiOverride = packageState.getCpuAbiOverride();
+        final int appId = UserHandle.getAppId(pkg.getUid());
+        final String seinfo = AndroidPackageUtils.getSeInfo(pkg, packageState);
+        final String label = String.valueOf(pm.getApplicationLabel(
+                AndroidPackageUtils.generateAppInfoWithoutState(pkg)));
+        final int targetSdkVersion = pkg.getTargetSdkVersion();
+        final int[] installedUserIds = PackageStateUtils.queryInstalledUsers(packageState,
+                mPm.mUserManager.getUserIds(), true);
         final String fromCodePath;
+        if (codeFile.getParentFile().getName().startsWith(
+                PackageManagerService.RANDOM_DIR_PREFIX)) {
+            fromCodePath = codeFile.getParentFile().getAbsolutePath();
+        } else {
+            fromCodePath = codeFile.getAbsolutePath();
+        }
 
-        // reader
+        final PackageFreezer freezer;
         synchronized (mPm.mLock) {
-            final AndroidPackage pkg = mPm.mPackages.get(packageName);
-            final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
-            if (pkg == null
-                    || ps == null
-                    || mPm.shouldFilterApplication(ps, callingUid, user.getIdentifier())) {
-                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
-            }
-            if (pkg.isSystem()) {
-                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
-                        "Cannot move system application");
-            }
-
-            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
-            final boolean allow3rdPartyOnInternal = mPm.mContext.getResources().getBoolean(
-                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
-            if (isInternalStorage && !allow3rdPartyOnInternal) {
-                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
-                        "3rd party apps are not allowed on internal storage");
-            }
-
-            currentVolumeUuid = ps.getVolumeUuid();
-
-            final File probe = new File(pkg.getPath());
-            final File probeOat = new File(probe, "oat");
-            if (!probe.isDirectory() || !probeOat.isDirectory()) {
-                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
-                        "Move only supported for modern cluster style installs");
-            }
-
-            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
-                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
-                        "Package already moved to " + volumeUuid);
-            }
-            if (!pkg.isExternalStorage() && mPm.isPackageDeviceAdminOnAnyUser(packageName)) {
-                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
-                        "Device admin cannot be moved");
-            }
-
-            if (mPm.mFrozenPackages.containsKey(packageName)) {
-                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
-                        "Failed to move already frozen package");
-            }
-
-            isCurrentLocationExternal = pkg.isExternalStorage();
-            codeFile = new File(pkg.getPath());
-            installSource = ps.getInstallSource();
-            packageAbiOverride = ps.getCpuAbiOverride();
-            appId = UserHandle.getAppId(pkg.getUid());
-            seinfo = AndroidPackageUtils.getSeInfo(pkg, ps);
-            label = String.valueOf(pm.getApplicationLabel(
-                    AndroidPackageUtils.generateAppInfoWithoutState(pkg)));
-            targetSdkVersion = pkg.getTargetSdkVersion();
             freezer = mPm.freezePackage(packageName, "movePackageInternal");
-            installedUserIds = ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true);
-            if (codeFile.getParentFile().getName().startsWith(
-                    PackageManagerService.RANDOM_DIR_PREFIX)) {
-                fromCodePath = codeFile.getParentFile().getAbsolutePath();
-            } else {
-                fromCodePath = codeFile.getAbsolutePath();
-            }
         }
 
         final Bundle extras = new Bundle();
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index c219f80..8534fab 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -15,7 +15,9 @@
 per-file AbstractStatsBase.java = file:dex/OWNERS
 per-file BackgroundDexOptService.java = file:dex/OWNERS
 per-file CompilerStats.java = file:dex/OWNERS
+per-file DexOptHelper.java = file:dex/OWNERS
 per-file DynamicCodeLoggingService.java = file:dex/OWNERS
+per-file Installer.java = file:dex/OWNERS
 per-file InstructionSets.java = file:dex/OWNERS
 per-file OtaDexoptService.java = file:dex/OWNERS
 per-file OtaDexoptShellCommand.java = file:dex/OWNERS
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index bd00914..cc4a760 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -131,8 +131,9 @@
         Predicate<PackageStateInternal> isPlatformPackage = pkgSetting ->
                 PLATFORM_PACKAGE_NAME.equals(pkgSetting.getPkg().getPackageName());
         // Important: the packages we need to run with ab-ota compiler-reason.
+        final Computer snapshot = mPackageManagerService.snapshotComputer();
         final Collection<? extends PackageStateInternal> allPackageStates =
-                mPackageManagerService.getPackageStates().values();
+                snapshot.getPackageStates().values();
         important = DexOptHelper.getPackagesForDexopt(allPackageStates,mPackageManagerService,
                 DEBUG_DEXOPT);
         // Remove Platform Package from A/B OTA b/160735835.
@@ -165,7 +166,7 @@
             Log.i(TAG, "Low on space, deleting oat files in an attempt to free up space: "
                     + DexOptHelper.packagesToString(others));
             for (PackageStateInternal pkg : others) {
-                mPackageManagerService.deleteOatArtifactsOfPackage(pkg.getPackageName());
+                mPackageManagerService.deleteOatArtifactsOfPackage(snapshot, pkg.getPackageName());
             }
         }
         long spaceAvailableNow = getAvailableSpace();
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index fe2fe09..4e702e2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -334,7 +334,7 @@
                 StagingManager.StagedSession stagedSession = session.mStagedSession;
                 if (!stagedSession.isInTerminalState() && stagedSession.hasParentSessionId()
                         && getSession(stagedSession.getParentSessionId()) == null) {
-                    stagedSession.setSessionFailed(SessionInfo.SESSION_ACTIVATION_FAILED,
+                    stagedSession.setSessionFailed(PackageManager.INSTALL_ACTIVATION_FAILED,
                             "An orphan staged session " + stagedSession.sessionId() + " is found, "
                                 + "parent " + stagedSession.getParentSessionId() + " is missing");
                     continue;
@@ -597,8 +597,8 @@
             String installerAttributionTag, int userId)
             throws IOException {
         final int callingUid = Binder.getCallingUid();
-        mPm.enforceCrossUserPermission(
-                callingUid, userId, true, true, "createSession");
+        final Computer snapshot = mPm.snapshotComputer();
+        snapshot.enforceCrossUserPermission(callingUid, userId, true, true, "createSession");
 
         if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
             throw new SecurityException("User restriction prevents installing");
@@ -663,7 +663,7 @@
             params.installFlags &= ~PackageManager.INSTALL_ALL_USERS;
             params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
             if ((params.installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0
-                    && !mPm.isCallerVerifier(callingUid)) {
+                    && !mPm.isCallerVerifier(snapshot, callingUid)) {
                 params.installFlags &= ~PackageManager.INSTALL_VIRTUAL_PRELOAD;
             }
             if (mContext.checkCallingOrSelfPermission(
@@ -676,7 +676,7 @@
         String originatingPackageName = null;
         if (params.originatingUid != SessionParams.UID_UNKNOWN
                 && params.originatingUid != callingUid) {
-            String[] packages = mPm.getPackagesForUid(params.originatingUid);
+            String[] packages = snapshot.getPackagesForUid(params.originatingUid);
             if (packages != null && packages.length > 0) {
                 // Choose an arbitrary representative package in the case of a shared UID.
                 originatingPackageName = packages[0];
@@ -727,7 +727,8 @@
 
         if ((params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0
                 && !isCalledBySystemOrShell(callingUid)
-                && (mPm.getFlagsForUid(callingUid) & ApplicationInfo.FLAG_SYSTEM) == 0) {
+                && (snapshot.getFlagsForUid(callingUid) & ApplicationInfo.FLAG_SYSTEM)
+                == 0) {
             throw new SecurityException(
                     "Only system apps could use the PackageManager.INSTALL_INSTANT_APP flag.");
         }
@@ -852,7 +853,7 @@
                 mSilentUpdatePolicy, mInstallThread.getLooper(), mStagingManager, sessionId,
                 userId, callingUid, installSource, params, createdMillis, 0L, stageDir, stageCid,
                 null, null, false, false, false, false, null, SessionInfo.INVALID_ID,
-                false, false, false, SessionInfo.SESSION_NO_ERROR, "");
+                false, false, false, PackageManager.INSTALL_UNKNOWN, "");
 
         synchronized (mSessions) {
             mSessions.put(sessionId, session);
@@ -1037,11 +1038,12 @@
         return "smdl" + sessionId + ".tmp";
     }
 
-    private boolean shouldFilterSession(int uid, SessionInfo info) {
+    private boolean shouldFilterSession(@NonNull Computer snapshot, int uid, SessionInfo info) {
         if (info == null) {
             return false;
         }
-        return uid != info.getInstallerUid() && !mPm.canQueryPackage(uid, info.getAppPackageName());
+        return uid != info.getInstallerUid()
+                && !snapshot.canQueryPackage(uid, info.getAppPackageName());
     }
 
     @Override
@@ -1054,7 +1056,7 @@
                     ? session.generateInfoForCaller(true /* includeIcon */, callingUid)
                     : null;
         }
-        return shouldFilterSession(callingUid, result) ? null : result;
+        return shouldFilterSession(mPm.snapshotComputer(), callingUid, result) ? null : result;
     }
 
     @Override
@@ -1069,15 +1071,16 @@
                 }
             }
         }
-        result.removeIf(info -> shouldFilterSession(callingUid, info));
+        final Computer snapshot = mPm.snapshotComputer();
+        result.removeIf(info -> shouldFilterSession(snapshot, callingUid, info));
         return new ParceledListSlice<>(result);
     }
 
     @Override
     public ParceledListSlice<SessionInfo> getAllSessions(int userId) {
         final int callingUid = Binder.getCallingUid();
-        mPm.enforceCrossUserPermission(
-                callingUid, userId, true, false, "getAllSessions");
+        final Computer snapshot = mPm.snapshotComputer();
+        snapshot.enforceCrossUserPermission(callingUid, userId, true, false, "getAllSessions");
 
         final List<SessionInfo> result = new ArrayList<>();
         synchronized (mSessions) {
@@ -1089,15 +1092,16 @@
                 }
             }
         }
-        result.removeIf(info -> shouldFilterSession(callingUid, info));
+        result.removeIf(info -> shouldFilterSession(snapshot, callingUid, info));
         return new ParceledListSlice<>(result);
     }
 
     @Override
     public ParceledListSlice<SessionInfo> getMySessions(String installerPackageName, int userId) {
-        mPm.enforceCrossUserPermission(
-                Binder.getCallingUid(), userId, true, false, "getMySessions");
-        mAppOps.checkPackage(Binder.getCallingUid(), installerPackageName);
+        final Computer snapshot = mPm.snapshotComputer();
+        final int callingUid = Binder.getCallingUid();
+        snapshot.enforceCrossUserPermission(callingUid, userId, true, false, "getMySessions");
+        mAppOps.checkPackage(callingUid, installerPackageName);
 
         final List<SessionInfo> result = new ArrayList<>();
         synchronized (mSessions) {
@@ -1119,8 +1123,9 @@
     @Override
     public void uninstall(VersionedPackage versionedPackage, String callerPackageName, int flags,
                 IntentSender statusReceiver, int userId) {
+        final Computer snapshot = mPm.snapshotComputer();
         final int callingUid = Binder.getCallingUid();
-        mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
+        snapshot.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
         if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) {
             mAppOps.checkPackage(callingUid, callerPackageName);
         }
@@ -1153,7 +1158,7 @@
                     .setAdmin(callerPackageName)
                     .write();
         } else {
-            ApplicationInfo appInfo = mPm.getApplicationInfo(callerPackageName, 0, userId);
+            ApplicationInfo appInfo = snapshot.getApplicationInfo(callerPackageName, 0, userId);
             if (appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
                 mContext.enforceCallingOrSelfPermission(Manifest.permission.REQUEST_DELETE_PACKAGES,
                         null);
@@ -1172,7 +1177,8 @@
             String callerPackageName, IntentSender statusReceiver, int userId) {
         final int callingUid = Binder.getCallingUid();
         mContext.enforceCallingOrSelfPermission(Manifest.permission.DELETE_PACKAGES, null);
-        mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
+        final Computer snapshot = mPm.snapshotComputer();
+        snapshot.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
         if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) {
             mAppOps.checkPackage(callingUid, callerPackageName);
         }
@@ -1204,8 +1210,9 @@
 
     @Override
     public void registerCallback(IPackageInstallerCallback callback, int userId) {
-        mPm.enforceCrossUserPermission(
-                Binder.getCallingUid(), userId, true, false, "registerCallback");
+        final Computer snapshot = mPm.snapshotComputer();
+        snapshot.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
+                "registerCallback");
         registerCallback(callback, eventUserId -> userId == eventUserId);
     }
 
@@ -1293,13 +1300,13 @@
         }
     }
 
-    private boolean shouldFilterSession(int uid, int sessionId) {
+    private boolean shouldFilterSession(@NonNull Computer snapshot, int uid, int sessionId) {
         final PackageInstallerSession session = getSession(sessionId);
         if (session == null) {
             return false;
         }
         return uid != session.getInstallerUid()
-                && !mPm.canQueryPackage(uid, session.getPackageName());
+                && !snapshot.canQueryPackage(uid, session.getPackageName());
     }
 
     static class PackageDeleteObserverAdapter extends PackageDeleteObserver {
@@ -1452,11 +1459,12 @@
             final int sessionId = msg.arg1;
             final int userId = msg.arg2;
             final int n = mCallbacks.beginBroadcast();
+            final Computer snapshot = mPm.snapshotComputer();
             for (int i = 0; i < n; i++) {
                 final IPackageInstallerCallback callback = mCallbacks.getBroadcastItem(i);
                 final BroadcastCookie cookie = (BroadcastCookie) mCallbacks.getBroadcastCookie(i);
                 if (cookie.userCheck.test(userId)
-                        && !shouldFilterSession(cookie.callingUid, sessionId)) {
+                        && !shouldFilterSession(snapshot, cookie.callingUid, sessionId)) {
                     try {
                         invokeCallback(callback, msg);
                     } catch (RemoteException ignored) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 55fc785..68be64f 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -82,7 +82,6 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionInfo;
-import android.content.pm.PackageInstaller.SessionInfo.SessionErrorCode;
 import android.content.pm.PackageInstaller.SessionParams;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
@@ -127,6 +126,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.EventLog;
 import android.util.ExceptionUtils;
 import android.util.IntArray;
 import android.util.MathUtils;
@@ -462,7 +462,7 @@
     @GuardedBy("mLock")
     private boolean mSessionFailed;
     @GuardedBy("mLock")
-    private int mSessionErrorCode = SessionInfo.SESSION_NO_ERROR;
+    private int mSessionErrorCode = PackageManager.INSTALL_UNKNOWN;
     @GuardedBy("mLock")
     private String mSessionErrorMessage;
 
@@ -817,25 +817,26 @@
         }
         // It is safe to access mInstallerUid and mInstallSource without lock
         // because they are immutable after sealing.
+        final Computer snapshot = mPm.snapshotComputer();
         final boolean isInstallPermissionGranted =
-                (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES,
+                (snapshot.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES,
                         mInstallerUid) == PackageManager.PERMISSION_GRANTED);
         final boolean isSelfUpdatePermissionGranted =
-                (mPm.checkUidPermission(android.Manifest.permission.INSTALL_SELF_UPDATES,
+                (snapshot.checkUidPermission(android.Manifest.permission.INSTALL_SELF_UPDATES,
                         mInstallerUid) == PackageManager.PERMISSION_GRANTED);
         final boolean isUpdatePermissionGranted =
-                (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGE_UPDATES,
+                (snapshot.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGE_UPDATES,
                         mInstallerUid) == PackageManager.PERMISSION_GRANTED);
-        final boolean isUpdateWithoutUserActionPermissionGranted = (mPm.checkUidPermission(
+        final boolean isUpdateWithoutUserActionPermissionGranted = (snapshot.checkUidPermission(
                 android.Manifest.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION, mInstallerUid)
                 == PackageManager.PERMISSION_GRANTED);
-        final boolean isInstallDpcPackagesPermissionGranted = (mPm.checkUidPermission(
+        final boolean isInstallDpcPackagesPermissionGranted = (snapshot.checkUidPermission(
                 android.Manifest.permission.INSTALL_DPC_PACKAGES, mInstallerUid)
                 == PackageManager.PERMISSION_GRANTED);
-        final int targetPackageUid = mPm.getPackageUid(packageName, 0, userId);
+        final int targetPackageUid = snapshot.getPackageUid(packageName, 0, userId);
         final boolean isUpdate = targetPackageUid != -1 || isApexSession();
         final InstallSourceInfo existingInstallSourceInfo = isUpdate
-                ? mPm.getInstallSourceInfo(packageName)
+                ? snapshot.getInstallSourceInfo(packageName)
                 : null;
         final String existingInstallerPackageName = existingInstallSourceInfo != null
                 ? existingInstallSourceInfo.getInstallingPackageName()
@@ -859,7 +860,8 @@
             return USER_ACTION_NOT_NEEDED;
         }
 
-        if (mPm.isInstallDisabledForPackage(getInstallerPackageName(), mInstallerUid, userId)) {
+        if (snapshot.isInstallDisabledForPackage(getInstallerPackageName(), mInstallerUid,
+                userId)) {
             // show the installer to account for device poslicy or unknown sources use cases
             return USER_ACTION_REQUIRED;
         }
@@ -2009,12 +2011,13 @@
     @Override
     public void transfer(String packageName) {
         Preconditions.checkArgument(!TextUtils.isEmpty(packageName));
-        ApplicationInfo newOwnerAppInfo = mPm.getApplicationInfo(packageName, 0, userId);
+        final Computer snapshot = mPm.snapshotComputer();
+        ApplicationInfo newOwnerAppInfo = snapshot.getApplicationInfo(packageName, 0, userId);
         if (newOwnerAppInfo == null) {
             throw new ParcelableException(new PackageManager.NameNotFoundException(packageName));
         }
 
-        if (PackageManager.PERMISSION_GRANTED != mPm.checkUidPermission(
+        if (PackageManager.PERMISSION_GRANTED != snapshot.checkUidPermission(
                 Manifest.permission.INSTALL_PACKAGES, newOwnerAppInfo.uid)) {
             throw new SecurityException("Destination package " + packageName + " does not have "
                     + "the " + Manifest.permission.INSTALL_PACKAGES + " permission");
@@ -2329,7 +2332,7 @@
                 }
             } else {
                 PackageManagerException e = (PackageManagerException) t.getCause();
-                setSessionFailed(SessionInfo.SESSION_ACTIVATION_FAILED,
+                setSessionFailed(e.error,
                         PackageManager.installStatusToString(e.error, e.getMessage()));
                 dispatchSessionFinished(e.error, e.getMessage(), null);
                 maybeFinishChildSessions(e.error, e.getMessage());
@@ -2509,7 +2512,7 @@
             // Package didn't install; no valid uid
             packageUid = Process.INVALID_UID;
         } else {
-            packageUid = mPm.getPackageUid(packageName, 0, userId);
+            packageUid = mPm.snapshotComputer().getPackageUid(packageName, 0, userId);
         }
         FrameworkStatsLog.write(FrameworkStatsLog.PACKAGE_INSTALLER_V2_REPORTED,
                 isIncrementalInstallation(),
@@ -2667,7 +2670,7 @@
         mResolvedStagedFiles.clear();
         mResolvedInheritedFiles.clear();
 
-        final PackageInfo pkgInfo = mPm.getPackageInfo(
+        final PackageInfo pkgInfo = mPm.snapshotComputer().getPackageInfo(
                 params.appPackageName, PackageManager.GET_SIGNATURES
                         | PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES /*flags*/, userId);
 
@@ -2860,6 +2863,11 @@
                 inheritFileLocked(mResolvedBaseFile);
                 // Collect the requiredSplitTypes from base
                 CollectionUtils.addAll(requiredSplitTypes, existing.getBaseRequiredSplitTypes());
+            } else if ((params.installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
+                EventLog.writeEvent(0x534e4554, "219044664");
+
+                // Installing base.apk. Make sure the app is restarted.
+                params.setDontKillApp(false);
             }
 
             // Inherit splits if not overridden.
@@ -3556,6 +3564,11 @@
     }
 
     @Override
+    public int getInstallFlags() {
+        return params.installFlags;
+    }
+
+    @Override
     public DataLoaderParamsParcel getDataLoaderParams() {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null);
         return params.dataLoaderParams != null ? params.dataLoaderParams.getData() : null;
@@ -3743,7 +3756,8 @@
         };
 
         if (!manualStartAndDestroy) {
-            final PerUidReadTimeouts[] perUidReadTimeouts = mPm.getPerUidReadTimeouts();
+            final PerUidReadTimeouts[] perUidReadTimeouts =
+                    mPm.getPerUidReadTimeouts(mPm.snapshotComputer());
 
             final StorageHealthCheckParams healthCheckParams = new StorageHealthCheckParams();
             healthCheckParams.blockedTimeoutMs = INCREMENTAL_STORAGE_BLOCKED_TIMEOUT_MS;
@@ -3778,8 +3792,8 @@
             };
 
             try {
-                final PackageInfo pkgInfo = mPm.getPackageInfo(this.params.appPackageName, 0,
-                        userId);
+                final PackageInfo pkgInfo = mPm.snapshotComputer()
+                        .getPackageInfo(this.params.appPackageName, 0, userId);
                 final File inheritedDir =
                         (pkgInfo != null && pkgInfo.applicationInfo != null) ? new File(
                                 pkgInfo.applicationInfo.getCodePath()).getParentFile() : null;
@@ -4035,7 +4049,7 @@
             mSessionReady = true;
             mSessionApplied = false;
             mSessionFailed = false;
-            mSessionErrorCode = SessionInfo.SESSION_NO_ERROR;
+            mSessionErrorCode = PackageManager.INSTALL_UNKNOWN;
             mSessionErrorMessage = "";
         }
         mCallback.onSessionChanged(this);
@@ -4063,7 +4077,7 @@
             mSessionReady = false;
             mSessionApplied = true;
             mSessionFailed = false;
-            mSessionErrorCode = SessionInfo.SESSION_NO_ERROR;
+            mSessionErrorCode = INSTALL_SUCCEEDED;
             mSessionErrorMessage = "";
             Slog.d(TAG, "Marking session " + sessionId + " as applied");
         }
@@ -4093,7 +4107,6 @@
     }
 
     /** {@hide} */
-    @SessionErrorCode
     int getSessionErrorCode() {
         synchronized (mLock) {
             return mSessionErrorCode;
@@ -4524,8 +4537,9 @@
         final String installerPackageName = readStringAttribute(in, ATTR_INSTALLER_PACKAGE_NAME);
         final String installerAttributionTag = readStringAttribute(in,
                 ATTR_INSTALLER_ATTRIBUTION_TAG);
-        final int installerUid = in.getAttributeInt(null, ATTR_INSTALLER_UID, pm.getPackageUid(
-                installerPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId));
+        final int installerUid = in.getAttributeInt(null, ATTR_INSTALLER_UID, pm.snapshotComputer()
+                .getPackageUid(installerPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES,
+                        userId));
         final String installInitiatingPackageName =
                 readStringAttribute(in, ATTR_INITIATING_PACKAGE_NAME);
         final String installOriginatingPackageName =
@@ -4581,7 +4595,7 @@
         final boolean isFailed = in.getAttributeBoolean(null, ATTR_IS_FAILED, false);
         final boolean isApplied = in.getAttributeBoolean(null, ATTR_IS_APPLIED, false);
         final int sessionErrorCode = in.getAttributeInt(null, ATTR_SESSION_ERROR_CODE,
-                SessionInfo.SESSION_NO_ERROR);
+                PackageManager.INSTALL_UNKNOWN);
         final String sessionErrorMessage = readStringAttribute(in, ATTR_SESSION_ERROR_MESSAGE);
 
         if (!isStagedSessionStateValid(isReady, isApplied, isFailed)) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
new file mode 100644
index 0000000..2b73375
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
@@ -0,0 +1,751 @@
+/*
+ * 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.pm;
+
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+import static android.content.pm.PackageManager.RESTRICTION_NONE;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.AuxiliaryResolveInfo;
+import android.content.pm.Checksum;
+import android.content.pm.IOnChecksumsReadyListener;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.content.pm.ProcessInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.SuspendDialogInfo;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Process;
+import android.os.storage.StorageManager;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.SparseArray;
+
+import com.android.server.pm.dex.DexManager;
+import com.android.server.pm.dex.DynamicCodeLogger;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
+import com.android.server.pm.pkg.AndroidPackageApi;
+import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.pkg.PackageStateUtils;
+import com.android.server.pm.pkg.SharedUserApi;
+import com.android.server.pm.pkg.component.ParsedMainComponent;
+import com.android.server.pm.pkg.mutate.PackageStateMutator;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Internal manager variant of {@link IPackageManagerBase}. See that class for info.
+ * {@link PackageManagerInternal} should eventually passing in a snapshot instance, deprecating
+ * this class, but that requires much larger refactor.
+ */
+abstract class PackageManagerInternalBase extends PackageManagerInternal {
+
+    @NonNull
+    private final PackageManagerService mService;
+
+    public PackageManagerInternalBase(@NonNull PackageManagerService service) {
+        mService = service;
+    }
+
+    @NonNull protected abstract Context getContext();
+    @NonNull protected abstract PermissionManagerServiceInternal getPermissionManager();
+    @NonNull protected abstract AppDataHelper getAppDataHelper();
+    @NonNull protected abstract PackageObserverHelper getPackageObserverHelper();
+    @NonNull protected abstract ResolveIntentHelper getResolveIntentHelper();
+    @NonNull protected abstract SuspendPackageHelper getSuspendPackageHelper();
+    @NonNull protected abstract ProtectedPackages getProtectedPackages();
+    @NonNull protected abstract UserNeedsBadgingCache getUserNeedsBadging();
+    @NonNull protected abstract InstantAppRegistry getInstantAppRegistry();
+    @NonNull protected abstract ApexManager getApexManager();
+    @NonNull protected abstract DexManager getDexManager();
+
+    @Override
+    public final Computer snapshot() {
+        return mService.snapshotComputer();
+    }
+
+    @Override
+    @Deprecated
+    public final List<ApplicationInfo> getInstalledApplications(
+            @PackageManager.ApplicationInfoFlagsBits long flags, int userId, int callingUid) {
+        return snapshot().getInstalledApplications(flags, userId, callingUid);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isInstantApp(String packageName, int userId) {
+        return snapshot().isInstantApp(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final String getInstantAppPackageName(int uid) {
+        return snapshot().getInstantAppPackageName(uid);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
+        return snapshot().filterAppAccess(pkg, callingUid, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean filterAppAccess(String packageName, int callingUid, int userId) {
+        return snapshot().filterAppAccess(packageName, callingUid, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean filterAppAccess(int uid, int callingUid) {
+        return snapshot().filterAppAccess(uid, callingUid);
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final int[] getVisibilityAllowList(@NonNull String packageName, int userId) {
+        return snapshot().getVisibilityAllowList(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean canQueryPackage(int callingUid, @Nullable String packageName) {
+        return snapshot().canQueryPackage(callingUid, packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final AndroidPackage getPackage(String packageName) {
+        return snapshot().getPackage(packageName);
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final AndroidPackageApi getAndroidPackage(@NonNull String packageName) {
+        return snapshot().getPackage(packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final AndroidPackage getPackage(int uid) {
+        return snapshot().getPackage(uid);
+    }
+
+    @Override
+    @Deprecated
+    public final List<AndroidPackage> getPackagesForAppId(int appId) {
+        return snapshot().getPackagesForAppId(appId);
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final PackageStateInternal getPackageStateInternal(String packageName) {
+        return snapshot().getPackageStateInternal(packageName);
+    }
+
+    @NonNull
+    @Override
+    @Deprecated
+    public final ArrayMap<String, ? extends PackageStateInternal> getPackageStates() {
+        return snapshot().getPackageStates();
+    }
+
+    @Override
+    @Deprecated
+    public final void removePackageListObserver(PackageListObserver observer) {
+        getPackageObserverHelper().removeObserver(observer);
+    }
+
+    @Override
+    @Deprecated
+    public final PackageStateInternal getDisabledSystemPackage(@NonNull String packageName) {
+        return snapshot().getDisabledSystemPackage(packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
+        return mService.getKnownPackageNamesInternal(snapshot(), knownPackage, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void setKeepUninstalledPackages(final List<String> packageList) {
+        mService.setKeepUninstalledPackagesInternal(snapshot(), packageList);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isPermissionsReviewRequired(String packageName, int userId) {
+        return getPermissionManager().isPermissionsReviewRequired(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final PackageInfo getPackageInfo(String packageName,
+            @PackageManager.PackageInfoFlagsBits long flags, int filterCallingUid, int userId) {
+        return snapshot().getPackageInfoInternal(packageName,
+                PackageManager.VERSION_CODE_HIGHEST, flags, filterCallingUid, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
+        return getSuspendPackageHelper().getSuspendedPackageLauncherExtras(snapshot(), packageName,
+                userId, Binder.getCallingUid());
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isPackageSuspended(String packageName, int userId) {
+        return getSuspendPackageHelper().isPackageSuspended(snapshot(), packageName, userId,
+                Binder.getCallingUid());
+    }
+
+    @Override
+    @Deprecated
+    public final void removeNonSystemPackageSuspensions(String packageName, int userId) {
+        getSuspendPackageHelper().removeSuspensionsBySuspendingPackage(snapshot(),
+                new String[]{packageName},
+                (suspendingPackage) -> !PackageManagerService.PLATFORM_PACKAGE_NAME.equals(
+                        suspendingPackage),
+                userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void removeDistractingPackageRestrictions(String packageName, int userId) {
+        mService.removeDistractingPackageRestrictions(snapshot(), new String[]{packageName},
+                userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void removeAllDistractingPackageRestrictions(int userId) {
+        mService.removeAllDistractingPackageRestrictions(snapshot(), userId);
+    }
+
+    @Override
+    @Deprecated
+    public final String getSuspendingPackage(String suspendedPackage, int userId) {
+        return getSuspendPackageHelper().getSuspendingPackage(snapshot(), suspendedPackage, userId,
+                Binder.getCallingUid());
+    }
+
+    @Override
+    @Deprecated
+    public final SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage,
+            String suspendingPackage, int userId) {
+        return getSuspendPackageHelper().getSuspendedDialogInfo(snapshot(), suspendedPackage,
+                suspendingPackage, userId, Binder.getCallingUid());
+    }
+
+    @Override
+    @Deprecated
+    public final int getDistractingPackageRestrictions(String packageName, int userId) {
+        final PackageStateInternal packageState = getPackageStateInternal(packageName);
+        return (packageState == null) ? RESTRICTION_NONE
+                : packageState.getUserStateOrDefault(userId).getDistractionFlags();
+    }
+
+    @Override
+    @Deprecated
+    public final int getPackageUid(String packageName,
+            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+        return snapshot().getPackageUidInternal(packageName, flags, userId, Process.SYSTEM_UID);
+    }
+
+    @Override
+    @Deprecated
+    public final ApplicationInfo getApplicationInfo(String packageName,
+            @PackageManager.ApplicationInfoFlagsBits long flags, int filterCallingUid, int userId) {
+        return snapshot().getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final ActivityInfo getActivityInfo(ComponentName component,
+            @PackageManager.ComponentInfoFlagsBits long flags, int filterCallingUid, int userId) {
+        return snapshot().getActivityInfoInternal(component, flags, filterCallingUid, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final List<ResolveInfo> queryIntentActivities(
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
+            int filterCallingUid, int userId) {
+        return snapshot().queryIntentActivitiesInternal(intent, resolvedType, flags, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final List<ResolveInfo> queryIntentReceivers(Intent intent,
+            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
+            int filterCallingUid, int userId) {
+        return getResolveIntentHelper().queryIntentReceiversInternal(
+                snapshot(), intent, resolvedType, flags, userId, filterCallingUid);
+    }
+
+    @Override
+    @Deprecated
+    public final List<ResolveInfo> queryIntentServices(
+            Intent intent, @PackageManager.ResolveInfoFlagsBits long flags, int callingUid,
+            int userId) {
+        final String resolvedType = intent.resolveTypeIfNeeded(getContext().getContentResolver());
+        return snapshot().queryIntentServicesInternal(intent, resolvedType, flags, userId,
+                callingUid, false);
+    }
+
+    @Override
+    @Deprecated
+    public final ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
+            int userId) {
+        return snapshot().getHomeActivitiesAsUser(allHomeCandidates, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final ComponentName getDefaultHomeActivity(int userId) {
+        return snapshot().getDefaultHomeActivity(userId);
+    }
+
+    @Override
+    @Deprecated
+    public final ComponentName getSystemUiServiceComponent() {
+        return ComponentName.unflattenFromString(getContext().getResources().getString(
+                com.android.internal.R.string.config_systemUIServiceComponent));
+    }
+
+    @Override
+    @Deprecated
+    public final void setDeviceOwnerProtectedPackages(
+            String deviceOwnerPackageName, List<String> packageNames) {
+        getProtectedPackages().setDeviceOwnerProtectedPackages(
+                deviceOwnerPackageName, packageNames);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isPackageDataProtected(int userId, String packageName) {
+        return getProtectedPackages().isPackageDataProtected(userId, packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isPackageStateProtected(String packageName, int userId) {
+        return getProtectedPackages().isPackageStateProtected(userId, packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isPackageEphemeral(int userId, String packageName) {
+        final PackageStateInternal packageState = getPackageStateInternal(packageName);
+        return packageState != null
+                && packageState.getUserStateOrDefault(userId).isInstantApp();
+    }
+
+    @Override
+    @Deprecated
+    public final boolean wasPackageEverLaunched(String packageName, int userId) {
+        final PackageStateInternal packageState = getPackageStateInternal(packageName);
+        if (packageState == null) {
+            throw new IllegalArgumentException("Unknown package: " + packageName);
+        }
+        return !packageState.getUserStateOrDefault(userId).isNotLaunched();
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isEnabledAndMatches(ParsedMainComponent component, long flags, int userId) {
+        return PackageStateUtils.isEnabledAndMatches(
+                getPackageStateInternal(component.getPackageName()), component, flags, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean userNeedsBadging(int userId) {
+        return getUserNeedsBadging().get(userId);
+    }
+
+    @Override
+    @Deprecated
+    public final String getNameForUid(int uid) {
+        return snapshot().getNameForUid(uid);
+    }
+
+    @Override
+    @Deprecated
+    public final void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
+            Intent origIntent, String resolvedType, String callingPackage,
+            @Nullable String callingFeatureId, boolean isRequesterInstantApp,
+            Bundle verificationBundle, int userId) {
+        mService.requestInstantAppResolutionPhaseTwo(responseObj, origIntent,
+                resolvedType, callingPackage, callingFeatureId, isRequesterInstantApp,
+                verificationBundle, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void grantImplicitAccess(int userId, Intent intent,
+            int recipientAppId, int visibleUid, boolean direct) {
+        grantImplicitAccess(userId, intent, recipientAppId, visibleUid, direct,
+                false /* retainOnUpdate */);
+    }
+
+    @Override
+    @Deprecated
+    public final void grantImplicitAccess(int userId, Intent intent,
+            int recipientAppId, int visibleUid, boolean direct, boolean retainOnUpdate) {
+        mService.grantImplicitAccess(snapshot(), userId, intent,
+                recipientAppId, visibleUid, direct, retainOnUpdate);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isInstantAppInstallerComponent(ComponentName component) {
+        final ActivityInfo instantAppInstallerActivity = mService.mInstantAppInstallerActivity;
+        return instantAppInstallerActivity != null
+                && instantAppInstallerActivity.getComponentName().equals(component);
+    }
+
+    @Override
+    @Deprecated
+    public final void pruneInstantApps() {
+        getInstantAppRegistry().pruneInstantApps(snapshot());
+    }
+
+    @Override
+    @Deprecated
+    public final String getSetupWizardPackageName() {
+        return mService.mSetupWizardPackage;
+    }
+
+    @Override
+    @Deprecated
+    public final ResolveInfo resolveIntent(Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlagsBits long flags,
+            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
+            boolean resolveForStart, int filterCallingUid) {
+        return getResolveIntentHelper().resolveIntentInternal(snapshot(),
+                intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
+                filterCallingUid);
+    }
+
+    @Override
+    @Deprecated
+    public final ResolveInfo resolveService(Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlagsBits long flags, int userId, int callingUid) {
+        return getResolveIntentHelper().resolveServiceInternal(snapshot(), intent,
+                resolvedType, flags, userId, callingUid);
+    }
+
+    @Override
+    @Deprecated
+    public final ProviderInfo resolveContentProvider(String name,
+            @PackageManager.ResolveInfoFlagsBits long flags, int userId, int callingUid) {
+        return snapshot().resolveContentProvider(name, flags, userId,callingUid);
+    }
+
+    @Override
+    @Deprecated
+    public final int getUidTargetSdkVersion(int uid) {
+        return snapshot().getUidTargetSdkVersion(uid);
+    }
+
+    @Override
+    @Deprecated
+    public final int getPackageTargetSdkVersion(String packageName) {
+        final PackageStateInternal packageState = getPackageStateInternal(packageName);
+        if (packageState != null && packageState.getPkg() != null) {
+            return packageState.getPkg().getTargetSdkVersion();
+        }
+        return Build.VERSION_CODES.CUR_DEVELOPMENT;
+    }
+
+    @Override
+    @Deprecated
+    public final boolean canAccessInstantApps(int callingUid, @UserIdInt int userId) {
+        return snapshot().canViewInstantApps(callingUid, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean canAccessComponent(int callingUid, @NonNull ComponentName component,
+            @UserIdInt int userId) {
+        return snapshot().canAccessComponent(callingUid, component, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean hasInstantApplicationMetadata(String packageName, int userId) {
+        return getInstantAppRegistry().hasInstantApplicationMetadata(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final SparseArray<String> getAppsWithSharedUserIds() {
+        return snapshot().getAppsWithSharedUserIds();
+    }
+
+    @Override
+    @NonNull
+    @Deprecated
+    public final String[] getSharedUserPackagesForPackage(String packageName, int userId) {
+        return snapshot().getSharedUserPackagesForPackage(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final ArrayMap<String, ProcessInfo> getProcessesForUid(int uid) {
+        return snapshot().getProcessesForUid(uid);
+    }
+
+    @Override
+    @Deprecated
+    public final int[] getPermissionGids(String permissionName, int userId) {
+        return getPermissionManager().getPermissionGids(permissionName, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isOnlyCoreApps() {
+        return mService.isOnlyCoreApps();
+    }
+
+    @Override
+    @Deprecated
+    public final void freeStorage(String volumeUuid, long bytes,
+            @StorageManager.AllocateFlags int flags) throws IOException {
+        mService.freeStorage(volumeUuid, bytes, flags);
+    }
+
+    @Override
+    @Deprecated
+    public final void freeAllAppCacheAboveQuota(@NonNull String volumeUuid) throws IOException {
+        mService.freeAllAppCacheAboveQuota(volumeUuid);
+    }
+
+    @Override
+    @Deprecated
+    public final void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
+        mService.forEachPackageSetting(actionLocked);
+    }
+
+    @Override
+    @Deprecated
+    public final void forEachPackageState(Consumer<PackageStateInternal> action) {
+        mService.forEachPackageState(snapshot(), action);
+    }
+
+    @Override
+    @Deprecated
+    public final void forEachPackage(Consumer<AndroidPackage> action) {
+        mService.forEachPackage(snapshot(), action);
+    }
+
+    @Override
+    @Deprecated
+    public final void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> action,
+            @UserIdInt int userId) {
+        mService.forEachInstalledPackage(snapshot(), action, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final ArraySet<String> getEnabledComponents(String packageName, int userId) {
+        final PackageStateInternal packageState = getPackageStateInternal(packageName);
+        if (packageState == null) {
+            return new ArraySet<>();
+        }
+        return packageState.getUserStateOrDefault(userId).getEnabledComponents();
+    }
+
+    @Override
+    @Deprecated
+    public final ArraySet<String> getDisabledComponents(String packageName, int userId) {
+        final PackageStateInternal packageState = getPackageStateInternal(packageName);
+        if (packageState == null) {
+            return new ArraySet<>();
+        }
+        return packageState.getUserStateOrDefault(userId).getDisabledComponents();
+    }
+
+    @Override
+    @Deprecated
+    public final @PackageManager.EnabledState int getApplicationEnabledState(
+            String packageName, int userId) {
+        final PackageStateInternal packageState = getPackageStateInternal(packageName);
+        if (packageState == null) {
+            return COMPONENT_ENABLED_STATE_DEFAULT;
+        }
+        return packageState.getUserStateOrDefault(userId).getEnabledState();
+    }
+
+    @Override
+    @Deprecated
+    public final @PackageManager.EnabledState int getComponentEnabledSetting(
+            @NonNull ComponentName componentName, int callingUid, int userId) {
+        return snapshot().getComponentEnabledSettingInternal(
+                componentName, callingUid, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void setEnableRollbackCode(int token, int enableRollbackCode) {
+        mService.setEnableRollbackCode(token, enableRollbackCode);
+    }
+
+    @Override
+    @Deprecated
+    public final void finishPackageInstall(int token, boolean didLaunch) {
+        mService.finishPackageInstall(token, didLaunch);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isApexPackage(String packageName) {
+        return getApexManager().isApexPackage(packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final List<String> getApksInApex(String apexPackageName) {
+        return getApexManager().getApksInApex(apexPackageName);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isCallerInstallerOfRecord(@NonNull AndroidPackage pkg, int callingUid) {
+        return snapshot().isCallerInstallerOfRecord(pkg, callingUid);
+    }
+
+    @Override
+    @Deprecated
+    public final List<String> getMimeGroup(String packageName, String mimeGroup) {
+        return mService.getMimeGroupInternal(snapshot(), packageName, mimeGroup);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isSystemPackage(@NonNull String packageName) {
+        return packageName.equals(mService.ensureSystemPackageName(snapshot(), packageName));
+    }
+
+    @Override
+    @Deprecated
+    public final void unsuspendForSuspendingPackage(final String packageName, int affectedUser) {
+        mService.unsuspendForSuspendingPackage(snapshot(), packageName, affectedUser);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isSuspendingAnyPackages(String suspendingPackage, int userId) {
+        return snapshot().isSuspendingAnyPackages(suspendingPackage, userId);
+    }
+
+    @Override
+    @Deprecated
+    public final void requestChecksums(@NonNull String packageName, boolean includeSplits,
+            @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
+            @Nullable List trustedInstallers,
+            @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId,
+            @NonNull Executor executor, @NonNull Handler handler) {
+        mService.requestChecksumsInternal(snapshot(), packageName, includeSplits, optional,
+                required, trustedInstallers, onChecksumsReadyListener, userId, executor,
+                handler);
+    }
+
+    @Override
+    @Deprecated
+    public final boolean isPackageFrozen(@NonNull String packageName,
+            int callingUid, int userId) {
+        return snapshot().getPackageStartability(mService.getSafeMode(), packageName, callingUid, userId)
+                == PackageManagerService.PACKAGE_STARTABILITY_FROZEN;
+    }
+
+    @Override
+    @Deprecated
+    public final long deleteOatArtifactsOfPackage(String packageName) {
+        return mService.deleteOatArtifactsOfPackage(snapshot(), packageName);
+    }
+
+    @Override
+    @Deprecated
+    public final void reconcileAppsData(int userId, @StorageManager.StorageFlags int flags,
+            boolean migrateAppsData) {
+        getAppDataHelper().reconcileAppsData(userId, flags, migrateAppsData);
+    }
+
+    @Override
+    @NonNull
+    public ArraySet<PackageStateInternal> getSharedUserPackages(int sharedUserAppId) {
+        return snapshot().getSharedUserPackages(sharedUserAppId);
+    }
+
+    @Override
+    @Nullable
+    public SharedUserApi getSharedUserApi(int sharedUserAppId) {
+        return snapshot().getSharedUser(sharedUserAppId);
+    }
+
+    @NonNull
+    @Override
+    @Deprecated
+    public final PackageStateMutator.InitialState recordInitialState() {
+        return mService.recordInitialState();
+    }
+
+    @Nullable
+    @Override
+    @Deprecated
+    public final PackageStateMutator.Result commitPackageStateMutation(
+            @Nullable PackageStateMutator.InitialState state,
+            @NonNull Consumer<PackageStateMutator> consumer) {
+        return mService.commitPackageStateMutation(state, consumer);
+    }
+
+    @Override
+    @Deprecated
+    public final void shutdown() {
+        mService.shutdown();
+    }
+
+    @Override
+    @Deprecated
+    public final DynamicCodeLogger getDynamicCodeLogger() {
+        return getDexManager().getDynamicCodeLogger();
+    }
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerNative.java b/services/core/java/com/android/server/pm/PackageManagerNative.java
index 37daf11..9a43008 100644
--- a/services/core/java/com/android/server/pm/PackageManagerNative.java
+++ b/services/core/java/com/android/server/pm/PackageManagerNative.java
@@ -71,7 +71,7 @@
 
     @Override
     public String[] getAllPackages() {
-        return mPm.getAllPackages().toArray(new String[0]);
+        return mPm.snapshotComputer().getAllPackages().toArray(new String[0]);
     }
 
     @Override
@@ -82,7 +82,7 @@
             if (uids == null || uids.length == 0) {
                 return null;
             }
-            names = mPm.getNamesForUids(uids);
+            names = mPm.snapshotComputer().getNamesForUids(uids);
             results = (names != null) ? names : new String[uids.length];
             // massage results so they can be parsed by the native binder
             for (int i = results.length - 1; i >= 0; --i) {
@@ -104,13 +104,14 @@
     // NB: this differentiates between preloads and sideloads
     @Override
     public String getInstallerForPackage(String packageName) throws RemoteException {
-        final String installerName = mPm.getInstallerPackageName(packageName);
+        final Computer snapshot = mPm.snapshotComputer();
+        final String installerName = snapshot.getInstallerPackageName(packageName);
         if (!TextUtils.isEmpty(installerName)) {
             return installerName;
         }
         // differentiate between preload and sideload
         int callingUser = UserHandle.getUserId(Binder.getCallingUid());
-        ApplicationInfo appInfo = mPm.getApplicationInfo(packageName,
+        ApplicationInfo appInfo = snapshot.getApplicationInfo(packageName,
                 /*flags*/ 0,
                 /*userId*/ callingUser);
         if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
@@ -123,7 +124,8 @@
     public long getVersionCodeForPackage(String packageName) throws RemoteException {
         try {
             int callingUser = UserHandle.getUserId(Binder.getCallingUid());
-            PackageInfo pInfo = mPm.getPackageInfo(packageName, 0, callingUser);
+            PackageInfo pInfo = mPm.snapshotComputer()
+                    .getPackageInfo(packageName, 0, callingUser);
             if (pInfo != null) {
                 return pInfo.getLongVersionCode();
             }
@@ -134,7 +136,7 @@
 
     @Override
     public int getTargetSdkVersionForPackage(String packageName) throws RemoteException {
-        int targetSdk = mPm.getTargetSdkVersion(packageName);
+        int targetSdk = mPm.snapshotComputer().getTargetSdkVersion(packageName);
         if (targetSdk != -1) {
             return targetSdk;
         }
@@ -145,7 +147,8 @@
     @Override
     public boolean isPackageDebuggable(String packageName) throws RemoteException {
         int callingUser = UserHandle.getCallingUserId();
-        ApplicationInfo appInfo = mPm.getApplicationInfo(packageName, 0, callingUser);
+        ApplicationInfo appInfo = mPm.snapshotComputer()
+                .getApplicationInfo(packageName, 0, callingUser);
         if (appInfo != null) {
             return (0 != (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE));
         }
@@ -157,9 +160,10 @@
     public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames)
             throws RemoteException {
         int callingUser = UserHandle.getUserId(Binder.getCallingUid());
+        final Computer snapshot = mPm.snapshotComputer();
         boolean[] results = new boolean[packageNames.length];
         for (int i = results.length - 1; i >= 0; --i) {
-            ApplicationInfo appInfo = mPm.getApplicationInfo(packageNames[i], 0, callingUser);
+            ApplicationInfo appInfo = snapshot.getApplicationInfo(packageNames[i], 0, callingUser);
             results[i] = appInfo != null && appInfo.isAudioPlaybackCaptureAllowed();
         }
         return results;
@@ -168,7 +172,7 @@
     @Override
     public int getLocationFlags(String packageName) throws RemoteException {
         int callingUser = UserHandle.getUserId(Binder.getCallingUid());
-        ApplicationInfo appInfo = mPm.getApplicationInfo(packageName,
+        ApplicationInfo appInfo = mPm.snapshotComputer().getApplicationInfo(packageName,
                 /*flags*/ 0,
                 /*userId*/ callingUser);
         if (appInfo == null) {
@@ -188,7 +192,8 @@
     @Override
     public boolean hasSha256SigningCertificate(String packageName, byte[] certificate)
             throws RemoteException {
-        return mPm.hasSigningCertificate(packageName, certificate, CERT_INPUT_SHA256);
+        return mPm.snapshotComputer()
+                .hasSigningCertificate(packageName, certificate, CERT_INPUT_SHA256);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f07418f..67056ea 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -29,7 +29,6 @@
 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.content.pm.PackageManager.RESTRICTION_NONE;
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
 import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
@@ -83,21 +82,15 @@
 import android.content.pm.IOnChecksumsReadyListener;
 import android.content.pm.IPackageChangeObserver;
 import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageInstallObserver2;
-import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageLoadingProgressCallback;
 import android.content.pm.IPackageManager;
 import android.content.pm.IPackageMoveObserver;
-import android.content.pm.IPackageStatsObserver;
 import android.content.pm.IncrementalStatesInfo;
 import android.content.pm.InstallSourceInfo;
 import android.content.pm.InstantAppInfo;
 import android.content.pm.InstantAppRequest;
-import android.content.pm.InstrumentationInfo;
-import android.content.pm.IntentFilterVerificationInfo;
-import android.content.pm.KeySet;
 import android.content.pm.ModuleInfo;
 import android.content.pm.PackageChangeEvent;
 import android.content.pm.PackageInfo;
@@ -105,20 +98,12 @@
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.ComponentEnabledSetting;
-import android.content.pm.PackageManager.ComponentType;
-import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
-import android.content.pm.PackageManager.ModuleInfoFlags;
-import android.content.pm.PackageManager.Property;
-import android.content.pm.PackageManager.PropertyLocation;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackagePartitions;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.PermissionGroupInfo;
-import android.content.pm.PermissionInfo;
-import android.content.pm.ProcessInfo;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
 import android.content.pm.SharedLibraryInfo;
 import android.content.pm.Signature;
 import android.content.pm.SigningDetails;
@@ -127,7 +112,6 @@
 import android.content.pm.UserInfo;
 import android.content.pm.VerifierDeviceIdentity;
 import android.content.pm.VersionedPackage;
-import android.content.pm.dex.IArtManager;
 import android.content.pm.overlay.OverlayPaths;
 import android.content.pm.parsing.PackageLite;
 import android.content.res.Resources;
@@ -229,10 +213,7 @@
 import com.android.server.pm.permission.LegacyPermissionManagerService;
 import com.android.server.pm.permission.PermissionManagerService;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
-import com.android.server.pm.pkg.AndroidPackageApi;
-import com.android.server.pm.pkg.PackageState;
 import com.android.server.pm.pkg.PackageStateInternal;
-import com.android.server.pm.pkg.PackageStateUtils;
 import com.android.server.pm.pkg.PackageUserState;
 import com.android.server.pm.pkg.PackageUserStateInternal;
 import com.android.server.pm.pkg.SharedUserApi;
@@ -334,8 +315,8 @@
  * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
  * </pre>
  */
-public class PackageManagerService extends IPackageManager.Stub
-        implements PackageSender, TestUtilityService {
+public class PackageManagerService implements PackageSender, TestUtilityService {
+
     static final String TAG = "PackageManager";
     public static final boolean DEBUG_SETTINGS = false;
     static final boolean DEBUG_PREFERRED = false;
@@ -417,7 +398,8 @@
     public @interface ScanFlags {}
 
     /**
-     * Used as the result code of the {@link #getPackageStartability}.
+     * Used as the result code of the {@link Computer#getPackageStartability(boolean, String, int,
+     * int)}.
      */
     @IntDef(value = {
         PACKAGE_STARTABILITY_OK,
@@ -430,40 +412,43 @@
     public @interface PackageStartability {}
 
     /**
-     * Used as the result code of the {@link #getPackageStartability} to indicate
-     * the given package is allowed to start.
+     * Used as the result code of the {@link Computer#getPackageStartability(boolean, String, int,
+     * int)} to indicate the given package is allowed to start.
      */
     public static final int PACKAGE_STARTABILITY_OK = 0;
 
     /**
-     * Used as the result code of the {@link #getPackageStartability} to indicate
-     * the given package is <b>not</b> allowed to start because it's not found
+     * Used as the result code of the {@link Computer#getPackageStartability(boolean, String, int,
+     * int)} to indicate the given package is <b>not</b> allowed to start because it's not found
      * (could be due to that package is invisible to the given user).
      */
     public static final int PACKAGE_STARTABILITY_NOT_FOUND = 1;
 
     /**
-     * Used as the result code of the {@link #getPackageStartability} to indicate
-     * the given package is <b>not</b> allowed to start because it's not a system app
-     * and the system is running in safe mode.
+     * Used as the result code of the {@link Computer#getPackageStartability(boolean, String, int,
+     * int)} to indicate the given package is <b>not</b> allowed to start because it's not a system
+     * app and the system is running in safe mode.
      */
     public static final int PACKAGE_STARTABILITY_NOT_SYSTEM = 2;
 
     /**
-     * Used as the result code of the {@link #getPackageStartability} to indicate
-     * the given package is <b>not</b> allowed to start because it's currently frozen.
+     * Used as the result code of the {@link Computer#getPackageStartability(boolean, String, int,
+     * int)} to indicate the given package is <b>not</b> allowed to start because it's currently
+     * frozen.
      */
     public static final int PACKAGE_STARTABILITY_FROZEN = 3;
 
     /**
-     * Used as the result code of the {@link #getPackageStartability} to indicate
-     * the given package is <b>not</b> allowed to start because it doesn't support
+     * Used as the result code of the {@link Computer#getPackageStartability(boolean, String, int,
+     * int)} to indicate the given package is <b>not</b> allowed to start because it doesn't support
      * direct boot.
      */
     public static final int PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED = 4;
 
     private static final String STATIC_SHARED_LIB_DELIMITER = "_";
-    /** Extension of the compressed packages */
+    /**
+     * Extension of the compressed packages
+     */
     public final static String COMPRESSED_EXTENSION = ".gz";
     /** Suffix of stub packages on the system partition */
     public final static String STUB_SUFFIX = "-Stub";
@@ -648,7 +633,6 @@
      */
     boolean mPromoteSystemApps;
 
-    private final PackageManagerInternal mPmInternal;
     private final TestUtilityService mTestUtilityService;
 
     @Watched
@@ -958,6 +942,7 @@
     private final ResolveIntentHelper mResolveIntentHelper;
     private final DexOptHelper mDexOptHelper;
     private final SuspendPackageHelper mSuspendPackageHelper;
+    private final IntentResolverInterceptor mIntentResolverInterceptor;
 
     /**
      * Invalidate the package info cache, which includes updating the cached computer.
@@ -1058,9 +1043,6 @@
     // A lock-free cache for frequently called functions.
     private volatile Computer mSnapshotComputer;
 
-    // A trampoline that directs callers to either the live or snapshot computer.
-    private final ComputerTracker mComputer = new ComputerTracker(this);
-
     // If true, the snapshot is invalid (stale).  The attribute is static since it may be
     // set from outside classes.  The attribute may be set to true anywhere, although it
     // should only be set true while holding mLock.  However, the attribute id guaranteed
@@ -1089,6 +1071,8 @@
      * Return the cached computer.  The method will rebuild the cached computer if necessary.
      * The live computer will be returned if snapshots are disabled.
      */
+    @VisibleForTesting(visibility = Visibility.PACKAGE)
+    @NonNull
     public Computer snapshotComputer() {
         if (Thread.holdsLock(mLock)) {
             // If the current thread holds mLock then it may have modified state but not
@@ -1167,15 +1151,6 @@
         onChange(null);
     }
 
-    @Override
-    public void notifyPackagesReplacedReceived(String[] packages) {
-        Computer computer = snapshotComputer();
-        ArraySet<String> packagesToNotify = computer.getNotifyPackagesForReplacedReceived(packages);
-        for (int index = 0; index < packagesToNotify.size(); index++) {
-            notifyInstallObserver(packagesToNotify.valueAt(index), false /* killApp */);
-        }
-    }
-
     void notifyInstallObserver(String packageName, boolean killApp) {
         final Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
                 killApp ? mPendingKillInstallObservers.remove(packageName)
@@ -1232,16 +1207,6 @@
                 PRUNE_UNUSED_SHARED_LIBRARIES_DELAY);
     }
 
-    @Override
-    public void requestPackageChecksums(@NonNull String packageName, boolean includeSplits,
-            @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
-            @Nullable List trustedInstallers,
-            @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId) {
-        requestChecksumsInternal(packageName, includeSplits, optional, required, trustedInstallers,
-                onChecksumsReadyListener, userId, mInjector.getBackgroundExecutor(),
-                mInjector.getBackgroundHandler());
-    }
-
     /**
      * Requests checksums for the APK file.
      * See {@link PackageInstaller.Session#requestChecksums} for details.
@@ -1267,15 +1232,15 @@
             ApkChecksums.Injector injector = new ApkChecksums.Injector(
                     () -> mContext,
                     () -> handler,
-                    () -> mInjector.getIncrementalManager(),
-                    () -> mPmInternal);
+                    mInjector::getIncrementalManager,
+                    () -> mInjector.getLocalService(PackageManagerInternal.class));
             ApkChecksums.getChecksums(filesToChecksum, optional, required, installerPackageName,
                     trustedCerts, onChecksumsReadyListener, injector);
         });
     }
 
-    private void requestChecksumsInternal(@NonNull String packageName, boolean includeSplits,
-            @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
+    void requestChecksumsInternal(@NonNull Computer snapshot, @NonNull String packageName,
+            boolean includeSplits, @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
             @Nullable List trustedInstallers,
             @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId,
             @NonNull Executor executor, @NonNull Handler handler) {
@@ -1284,12 +1249,12 @@
         Objects.requireNonNull(executor);
         Objects.requireNonNull(handler);
 
-        final ApplicationInfo applicationInfo = getApplicationInfoInternal(packageName, 0,
+        final ApplicationInfo applicationInfo = snapshot.getApplicationInfoInternal(packageName, 0,
                 Binder.getCallingUid(), userId);
         if (applicationInfo == null) {
             throw new ParcelableException(new PackageManager.NameNotFoundException(packageName));
         }
-        final InstallSourceInfo installSourceInfo = getInstallSourceInfo(packageName);
+        final InstallSourceInfo installSourceInfo = snapshot.getInstallSourceInfo(packageName);
         final String installerPackageName =
                 installSourceInfo != null ? installSourceInfo.getInitiatingPackageName() : null;
 
@@ -1313,8 +1278,8 @@
             ApkChecksums.Injector injector = new ApkChecksums.Injector(
                     () -> mContext,
                     () -> handler,
-                    () -> mInjector.getIncrementalManager(),
-                    () -> mPmInternal);
+                    mInjector::getIncrementalManager,
+                    () -> mInjector.getLocalService(PackageManagerInternal.class));
             ApkChecksums.getChecksums(filesToChecksum, optional, required, installerPackageName,
                     trustedCerts, onChecksumsReadyListener, injector);
         });
@@ -1431,9 +1396,9 @@
         }
     }
 
-    public static PackageManagerService main(Context context, Installer installer,
-            @NonNull DomainVerificationService domainVerificationService, boolean factoryTest,
-            boolean onlyCore) {
+    public static Pair<PackageManagerService, IPackageManager> main(Context context,
+            Installer installer, @NonNull DomainVerificationService domainVerificationService,
+            boolean factoryTest, boolean onlyCore) {
         // Self-check for initial settings.
         PackageManagerServiceCompilerMapping.checkProperties();
         final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
@@ -1459,14 +1424,14 @@
                         RuntimePermissionsPersistence.createInstance(),
                         i.getPermissionManagerServiceInternal(),
                         domainVerificationService, lock),
-                (i, pm) -> AppsFilter.create(pm.mPmInternal, i),
+                (i, pm) -> AppsFilter.create(i, i.getLocalService(PackageManagerInternal.class)),
                 (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),
                 (i, pm) -> SystemConfig.getInstance(),
                 (i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(),
                         i.getContext(), "*dexopt*"),
-                (i, pm) -> new DexManager(i.getContext(), pm, i.getPackageDexOptimizer(),
+                (i, pm) -> new DexManager(i.getContext(), i.getPackageDexOptimizer(),
                         i.getInstaller(), i.getInstallLock()),
-                (i, pm) -> new ArtManagerService(i.getContext(), pm, i.getInstaller(),
+                (i, pm) -> new ArtManagerService(i.getContext(), i.getInstaller(),
                         i.getInstallLock()),
                 (i, pm) -> ApexManager.getInstance(),
                 (i, pm) -> new ViewCompiler(i.getInstallLock(), i.getInstaller()),
@@ -1489,7 +1454,7 @@
                         i.getContext(), pm, i::getScanningPackageParser),
                 (i, pm, cn) -> new InstantAppResolverConnection(
                         i.getContext(), cn, Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE),
-                (i, pm) -> new ModuleInfoProvider(i.getContext(), pm),
+                (i, pm) -> new ModuleInfoProvider(i.getContext()),
                 (i, pm) -> LegacyPermissionManagerService.create(i.getContext()),
                 (i, pm) -> domainVerificationService,
                 (i, pm) -> {
@@ -1517,13 +1482,15 @@
 
         final CompatChange.ChangeListener selinuxChangeListener = packageName -> {
             synchronized (m.mInstallLock) {
-                final PackageStateInternal packageState = m.getPackageStateInternal(packageName);
+                final Computer snapshot = m.snapshotComputer();
+                final PackageStateInternal packageState =
+                        snapshot.getPackageStateInternal(packageName);
                 if (packageState == null) {
                     Slog.e(TAG, "Failed to find package setting " + packageName);
                     return;
                 }
                 AndroidPackage pkg = packageState.getPkg();
-                SharedUserApi sharedUser = m.mComputer.getSharedUser(
+                SharedUserApi sharedUser = snapshot.getSharedUser(
                         packageState.getSharedUserAppId());
                 String oldSeInfo = AndroidPackageUtils.getSeInfo(pkg, packageState);
 
@@ -1550,11 +1517,12 @@
                 selinuxChangeListener);
 
         m.installAllowlistedSystemPackages();
-        ServiceManager.addService("package", m);
+        IPackageManagerImpl iPackageManager = m.new IPackageManagerImpl();
+        ServiceManager.addService("package", iPackageManager);
         final PackageManagerNative pmn = new PackageManagerNative(m);
         ServiceManager.addService("package_native", pmn);
         LocalManagerRegistry.addManager(PackageManagerLocal.class, m.new PackageManagerLocalImpl());
-        return m;
+        return Pair.create(m, iPackageManager);
     }
 
     /** Install/uninstall system packages for all users based on their user-type, as applicable. */
@@ -1660,7 +1628,6 @@
         mPackageDexOptimizer = testParams.packageDexOptimizer;
         mPackageParserCallback = testParams.packageParserCallback;
         mPendingBroadcasts = testParams.pendingPackageBroadcasts;
-        mPmInternal = testParams.pmInternal;
         mTestUtilityService = testParams.testUtilityService;
         mProcessLoggingHandler = testParams.processLoggingHandler;
         mProtectedPackages = testParams.protectedPackages;
@@ -1712,6 +1679,8 @@
 
         mSharedLibraries.setDeletePackageHelper(mDeletePackageHelper);
 
+        mIntentResolverInterceptor = null;
+
         registerObservers(false);
         invalidatePackageInfoCache();
     }
@@ -1749,10 +1718,9 @@
         t.traceBegin("createSubComponents");
 
         // Expose private service for system components to use.
-        mPmInternal = new PackageManagerInternalImpl();
+        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
         LocalServices.addService(TestUtilityService.class, this);
         mTestUtilityService = LocalServices.getService(TestUtilityService.class);
-        LocalServices.addService(PackageManagerInternal.class, mPmInternal);
         mUserManager = injector.getUserManagerService();
         mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager);
         mComponentResolver = injector.getComponentResolver();
@@ -1900,9 +1868,10 @@
                 final int dependencyCount = entry.dependencies.length;
                 for (int j = 0; j < dependencyCount; j++) {
                     final SharedLibraryInfo dependency =
-                        getSharedLibraryInfo(entry.dependencies[j], undefinedVersion);
+                        computer.getSharedLibraryInfo(entry.dependencies[j], undefinedVersion);
                     if (dependency != null) {
-                        getSharedLibraryInfo(name, undefinedVersion).addDependency(dependency);
+                        computer.getSharedLibraryInfo(name, undefinedVersion)
+                                .addDependency(dependency);
                     }
                 }
             }
@@ -1914,7 +1883,7 @@
             t.traceEnd();
 
             t.traceBegin("read user settings");
-            mFirstBoot = !mSettings.readLPw(mLiveComputer,
+            mFirstBoot = !mSettings.readLPw(computer,
                     mInjector.getUserManagerInternal().getUsers(
                     /* excludePartial= */ true,
                     /* excludeDying= */ false,
@@ -1995,17 +1964,26 @@
             // Resolve protected action filters. Only the setup wizard is allowed to
             // have a high priority filter for these actions.
             mSetupWizardPackage = getSetupWizardPackageNameImpl(computer);
-            mComponentResolver.fixProtectedFilterPriorities(mPmInternal.getSetupWizardPackageName());
+            mComponentResolver.fixProtectedFilterPriorities(mSetupWizardPackage);
 
-            mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
-            mSystemTextClassifierPackageName = getSystemTextClassifierPackageName();
-            mConfiguratorPackage = getDeviceConfiguratorPackageName();
-            mAppPredictionServicePackage = getAppPredictionServicePackageName();
-            mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
+            mDefaultTextClassifierPackage = ensureSystemPackageName(computer,
+                    mContext.getString(R.string.config_servicesExtensionPackage));
+            mSystemTextClassifierPackageName = ensureSystemPackageName(computer,
+                    mContext.getString(R.string.config_defaultTextClassifierPackage));
+            mConfiguratorPackage = ensureSystemPackageName(computer,
+                    mContext.getString(R.string.config_deviceConfiguratorPackageName));
+            mAppPredictionServicePackage = ensureSystemPackageName(computer,
+                    getPackageFromComponentString(R.string.config_defaultAppPredictionService));
+            mIncidentReportApproverPackage = ensureSystemPackageName(computer,
+                    mContext.getString(R.string.config_incidentReportApproverPackage));
             mRetailDemoPackage = getRetailDemoPackageName();
-            mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName();
-            mRecentsPackage = getRecentsPackageName();
-            mAmbientContextDetectionPackage = getAmbientContextDetectionPackageName();
+            mOverlayConfigSignaturePackage = ensureSystemPackageName(computer,
+                    mInjector.getSystemConfig().getOverlayConfigSignaturePackage());
+            mRecentsPackage = ensureSystemPackageName(computer,
+                    getPackageFromComponentString(R.string.config_recentsComponentName));
+            mAmbientContextDetectionPackage = ensureSystemPackageName(computer,
+                    getPackageFromComponentString(
+                            R.string.config_defaultAmbientContextDetectionService));
 
             // Now that we know all of the shared libraries, update all clients to have
             // the correct library paths.
@@ -2139,8 +2117,8 @@
 
                 mDomainVerificationManager.setProxy(domainVerificationProxy);
 
-                mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr();
-                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibrary(
+                mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr(computer);
+                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibrary(computer,
                         PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
                         SharedLibraryInfo.VERSION_UNDEFINED);
             } else {
@@ -2156,11 +2134,11 @@
             mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr(computer);
 
             mSettings.setPermissionControllerVersion(
-                    getPackageInfo(mRequiredPermissionControllerPackage, 0,
+                    computer.getPackageInfo(mRequiredPermissionControllerPackage, 0,
                             UserHandle.USER_SYSTEM).getLongVersionCode());
 
             // Resolve the sdk sandbox package
-            mRequiredSdkSandboxPackage = getRequiredSdkSandboxPackageName();
+            mRequiredSdkSandboxPackage = getRequiredSdkSandboxPackageName(computer);
 
             // Initialize InstantAppRegistry's Instant App list for all users.
             for (AndroidPackage pkg : mPackages.values()) {
@@ -2168,7 +2146,8 @@
                     continue;
                 }
                 for (int userId : userIds) {
-                    final PackageStateInternal ps = getPackageStateInternal(pkg.getPackageName());
+                    final PackageStateInternal ps =
+                            computer.getPackageStateInternal(pkg.getPackageName());
                     if (ps == null || !ps.getUserStateOrDefault(userId).isInstantApp()
                             || !ps.getUserStateOrDefault(userId).isInstalled()) {
                         continue;
@@ -2178,7 +2157,7 @@
             }
 
             mInstallerService = mInjector.getPackageInstallerService();
-            final ComponentName instantAppResolverComponent = getInstantAppResolver();
+            final ComponentName instantAppResolverComponent = getInstantAppResolver(computer);
             if (instantAppResolverComponent != null) {
                 if (DEBUG_INSTANT) {
                     Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
@@ -2204,7 +2183,8 @@
             // scanning).
             final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
             for (int userId : userIds) {
-                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
+                userPackages.put(userId, computer.getInstalledPackages(/*flags*/ 0, userId)
+                        .getList());
             }
             mDexManager.load(userPackages);
             if (mIsUpgrade) {
@@ -2214,7 +2194,7 @@
                         SystemClock.uptimeMillis() - startTime);
             }
 
-            // Rebild the live computer since some attributes have been rebuilt.
+            // Rebuild the live computer since some attributes have been rebuilt.
             mLiveComputer = createLiveComputer();
 
         } // synchronized (mLock)
@@ -2222,6 +2202,7 @@
         // CHECKSTYLE:ON IndentationCheck
 
         mModuleInfoProvider = mInjector.getModuleInfoProvider();
+
         mInjector.getSystemWrapper().enablePackageCaches();
 
         // Now after opening every single application zip, make sure they
@@ -2240,6 +2221,8 @@
 
         mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
 
+        mIntentResolverInterceptor = new IntentResolverInterceptor(mContext);
+
         Slog.i(TAG, "Fix for b/169414761 is applied");
     }
 
@@ -2255,19 +2238,16 @@
         setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
     }
 
-    @Override
     public boolean isFirstBoot() {
         // allow instant applications
         return mFirstBoot;
     }
 
-    @Override
     public boolean isOnlyCoreApps() {
         // allow instant applications
         return mOnlyCore;
     }
 
-    @Override
     public boolean isDeviceUpgrading() {
         // allow instant applications
         // The system property allows testing ota flow when upgraded to the same image.
@@ -2294,8 +2274,9 @@
     }
 
     @NonNull
-    private String getRequiredSharedLibrary(@NonNull String name, int version) {
-        SharedLibraryInfo libraryInfo = getSharedLibraryInfo(name, version);
+    private String getRequiredSharedLibrary(@NonNull Computer snapshot, @NonNull String name,
+            int version) {
+        SharedLibraryInfo libraryInfo = snapshot.getSharedLibraryInfo(name, version);
         if (libraryInfo == null) {
             throw new IllegalStateException("Missing required shared library:" + name);
         }
@@ -2307,9 +2288,9 @@
     }
 
     @NonNull
-    private String getRequiredServicesExtensionPackageLPr() {
+    private String getRequiredServicesExtensionPackageLPr(@NonNull Computer computer) {
         String servicesExtensionPackage =
-                ensureSystemPackageName(
+                ensureSystemPackageName(computer,
                         mContext.getString(R.string.config_servicesExtensionPackage));
         if (TextUtils.isEmpty(servicesExtensionPackage)) {
             throw new RuntimeException(
@@ -2388,8 +2369,9 @@
         for (int i = 0; i < N; i++) {
             final ResolveInfo cur = matches.get(i);
             final String packageName = cur.getComponentInfo().packageName;
-            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
-                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
+            if (checkPermission(
+                    android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, packageName,
+                    UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
                 continue;
             }
 
@@ -2417,15 +2399,16 @@
         for (int i = 0; i < N; i++) {
             final ResolveInfo cur = matches.get(i);
             final String packageName = cur.getComponentInfo().packageName;
-            if (checkPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT,
-                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
+            if (checkPermission(
+                    android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, packageName,
+                    UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
                 Slog.w(TAG, "Domain verification agent found but does not hold permission: "
                         + packageName);
                 continue;
             }
 
             if (best == null || cur.priority > best.priority) {
-                if (mComputer.isComponentEffectivelyEnabled(cur.getComponentInfo(),
+                if (computer.isComponentEffectivelyEnabled(cur.getComponentInfo(),
                         UserHandle.USER_SYSTEM)) {
                     best = cur;
                 } else {
@@ -2441,15 +2424,7 @@
         return null;
     }
 
-    @Override
-    public @Nullable ComponentName getInstantAppResolverComponent() {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return null;
-        }
-        return getInstantAppResolver();
-    }
-
-    private @Nullable ComponentName getInstantAppResolver() {
+    @Nullable ComponentName getInstantAppResolver(@NonNull Computer snapshot) {
         final String[] packageArray =
                 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
         if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
@@ -2465,7 +2440,7 @@
                 | MATCH_DIRECT_BOOT_UNAWARE
                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
         final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE);
-        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
+        List<ResolveInfo> resolvers = snapshot.queryIntentServicesInternal(resolverIntent, null,
                 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
         final int N = resolvers.size();
         if (N == 0) {
@@ -2569,155 +2544,6 @@
         return matches.get(0).getComponentInfo().getComponentName();
     }
 
-    @Override
-    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-            throws RemoteException {
-        try {
-            return super.onTransact(code, data, reply, flags);
-        } catch (RuntimeException e) {
-            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)
-                    && !(e instanceof ParcelableException)) {
-                Slog.wtf(TAG, "Package Manager Unexpected Exception", e);
-            }
-            throw e;
-        }
-    }
-
-    /**
-     * Returns whether or not a full application can see an instant application.
-     * <p>
-     * Currently, there are four cases in which this can occur:
-     * <ol>
-     * <li>The calling application is a "special" process. Special processes
-     *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
-     * <li>The calling application has the permission
-     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
-     * <li>The calling application is the default launcher on the
-     *     system partition.</li>
-     * <li>The calling application is the default app prediction service.</li>
-     * </ol>
-     */
-    boolean canViewInstantApps(int callingUid, int userId) {
-        return mComputer.canViewInstantApps(callingUid, userId);
-    }
-
-    private PackageInfo generatePackageInfo(@NonNull PackageStateInternal ps,
-            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
-        return mComputer.generatePackageInfo(ps, flags, userId);
-    }
-
-    @Override
-    public void checkPackageStartable(String packageName, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        if (getInstantAppPackageName(callingUid) != null) {
-            throw new SecurityException("Instant applications don't have access to this method");
-        }
-        if (!mUserManager.exists(userId)) {
-            throw new SecurityException("User doesn't exist");
-        }
-        enforceCrossUserPermission(callingUid, userId, false, false, "checkPackageStartable");
-        switch (getPackageStartability(packageName, callingUid, userId)) {
-            case PACKAGE_STARTABILITY_NOT_FOUND:
-                throw new SecurityException("Package " + packageName + " was not found!");
-            case PACKAGE_STARTABILITY_NOT_SYSTEM:
-                throw new SecurityException("Package " + packageName + " not a system app!");
-            case PACKAGE_STARTABILITY_FROZEN:
-                throw new SecurityException("Package " + packageName + " is currently frozen!");
-            case PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED:
-                throw new SecurityException("Package " + packageName + " is not encryption aware!");
-            case PACKAGE_STARTABILITY_OK:
-            default:
-        }
-    }
-
-    private @PackageStartability int getPackageStartability(String packageName,
-            int callingUid, int userId) {
-        return mComputer.getPackageStartability(mSafeMode, packageName, callingUid, userId);
-    }
-
-    @Override
-    public boolean isPackageAvailable(String packageName, int userId) {
-        return mComputer.isPackageAvailable(packageName, userId);
-    }
-
-    @Override
-    public PackageInfo getPackageInfo(String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
-        return mComputer.getPackageInfo(packageName, flags, userId);
-    }
-
-    @Override
-    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
-            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
-        return mComputer.getPackageInfoInternal(versionedPackage.getPackageName(),
-                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
-    }
-
-    /**
-     * Returns whether or not access to the application should be filtered.
-     * <p>
-     * Access may be limited based upon whether the calling or target applications
-     * are instant applications.
-     *
-     * @see #canViewInstantApps(int, int)
-     */
-    private boolean shouldFilterApplication(@Nullable PackageStateInternal ps, int callingUid,
-            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
-        return mComputer.shouldFilterApplication(ps, callingUid,
-                component, componentType, userId);
-    }
-
-    /**
-     * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int)
-     */
-    boolean shouldFilterApplication(
-            @Nullable PackageStateInternal ps, int callingUid, int userId) {
-        return mComputer.shouldFilterApplication(
-            ps, callingUid, userId);
-    }
-
-    /**
-     * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int)
-     */
-    private boolean shouldFilterApplication(@NonNull SharedUserSetting sus, int callingUid,
-            int userId) {
-        return mComputer.shouldFilterApplication(sus, callingUid, userId);
-    }
-
-    private boolean filterSharedLibPackage(@Nullable PackageStateInternal ps, int uid,
-            int userId, @PackageManager.ComponentInfoFlagsBits long flags) {
-        return mComputer.filterSharedLibPackage(ps, uid, userId, flags);
-    }
-
-    @Override
-    public String[] currentToCanonicalPackageNames(String[] names) {
-        return mComputer.currentToCanonicalPackageNames(names);
-    }
-
-    @Override
-    public String[] canonicalToCurrentPackageNames(String[] names) {
-        return mComputer.canonicalToCurrentPackageNames(names);
-    }
-
-    @Override
-    public int getPackageUid(@NonNull String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) {
-        return mComputer.getPackageUid(packageName, flags, userId);
-    }
-
-    int getPackageUidInternal(String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, int userId, int callingUid) {
-        return mComputer.getPackageUidInternal(packageName, flags, userId, callingUid);
-    }
-
-    @Override
-    public int[] getPackageGids(String packageName, @PackageManager.PackageInfoFlagsBits long flags,
-            int userId) {
-        return mComputer.getPackageGids(packageName, flags, userId);
-    }
-
-    // NOTE: Can't remove due to unsupported app usage
-    @Override
     public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
         // Because this is accessed via the package manager service AIDL,
         // go through the permission manager service AIDL
@@ -2725,86 +2551,6 @@
                 .getPermissionGroupInfo(groupName, flags);
     }
 
-    private ApplicationInfo generateApplicationInfoFromSettings(String packageName,
-            @PackageManager.ApplicationInfoFlagsBits long flags, int filterCallingUid, int userId) {
-        return mComputer.generateApplicationInfoFromSettings(packageName, flags, filterCallingUid,
-                userId);
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfo(String packageName,
-            @PackageManager.ApplicationInfoFlagsBits long flags, int userId) {
-        return mComputer.getApplicationInfo(packageName, flags, userId);
-    }
-
-    /**
-     * Important: The provided filterCallingUid is used exclusively to filter out applications
-     * that can be seen based on user state. It's typically the original caller uid prior
-     * to clearing. Because it can only be provided by trusted code, its value can be
-     * trusted and will be used as-is; unlike userId which will be validated by this method.
-     */
-    private ApplicationInfo getApplicationInfoInternal(String packageName,
-            @PackageManager.ApplicationInfoFlagsBits long flags,
-            int filterCallingUid, int userId) {
-        return mComputer.getApplicationInfoInternal(packageName, flags,
-                filterCallingUid, userId);
-    }
-
-    @Override
-    public void deletePreloadsFileCache() {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE,
-                "deletePreloadsFileCache");
-        File dir = Environment.getDataPreloadsFileCacheDirectory();
-        Slog.i(TAG, "Deleting preloaded file cache " + dir);
-        FileUtils.deleteContents(dir);
-    }
-
-    @Override
-    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
-            final @StorageManager.AllocateFlags int flags, final IPackageDataObserver observer) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.CLEAR_APP_CACHE, null);
-        mHandler.post(() -> {
-            boolean success = false;
-            try {
-                freeStorage(volumeUuid, freeStorageSize, flags);
-                success = true;
-            } catch (IOException e) {
-                Slog.w(TAG, e);
-            }
-            if (observer != null) {
-                try {
-                    observer.onRemoveCompleted(null, success);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, e);
-                }
-            }
-        });
-    }
-
-    @Override
-    public void freeStorage(final String volumeUuid, final long freeStorageSize,
-            final @StorageManager.AllocateFlags int flags, final IntentSender pi) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
-        mHandler.post(() -> {
-            boolean success = false;
-            try {
-                freeStorage(volumeUuid, freeStorageSize, flags);
-                success = true;
-            } catch (IOException e) {
-                Slog.w(TAG, e);
-            }
-            if (pi != null) {
-                try {
-                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
-                } catch (SendIntentException e) {
-                    Slog.w(TAG, e);
-                }
-            }
-        });
-    }
-
     /**
      * Blocking call to clear all cached app data above quota.
      */
@@ -2962,170 +2708,15 @@
         return recommendedInstallLocation;
     }
 
-    /**
-     * Update given flags when being used to request {@link ResolveInfo}.
-     * <p>Instant apps are resolved specially, depending upon context. Minimally,
-     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
-     * flag set. However, this flag is only honoured in three circumstances:
-     * <ul>
-     * <li>when called from a system process</li>
-     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
-     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
-     * action and a {@code android.intent.category.BROWSABLE} category</li>
-     * </ul>
-     */
-    long updateFlagsForResolve(long flags, int userId, int callingUid,
-            boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
-        return mComputer.updateFlagsForResolve(flags, userId, callingUid,
-                wantInstantApps, isImplicitImageCaptureIntentAndNotSetByDpc);
-    }
-
-    @Override
-    public int getTargetSdkVersion(@NonNull String packageName)  {
-        return mComputer.getTargetSdkVersion(packageName);
-    }
-
-    @Override
-    public ActivityInfo getActivityInfo(ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
-        return mComputer.getActivityInfo(component, flags, userId);
-    }
-
-    /**
-     * Important: The provided filterCallingUid is used exclusively to filter out activities
-     * that can be seen based on user state. It's typically the original caller uid prior
-     * to clearing. Because it can only be provided by trusted code, its value can be
-     * trusted and will be used as-is; unlike userId which will be validated by this method.
-     */
-    private ActivityInfo getActivityInfoInternal(ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags, int filterCallingUid, int userId) {
-        return mComputer.getActivityInfoInternal(component, flags,
-                filterCallingUid, userId);
-    }
-
-    @Override
-    public boolean activitySupportsIntent(ComponentName component, Intent intent,
-            String resolvedType) {
-        return mComputer.activitySupportsIntent(mResolveComponentName, component, intent,
-                resolvedType);
-    }
-
-    @Override
-    public ActivityInfo getReceiverInfo(ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
-        return mComputer.getReceiverInfo(component, flags, userId);
-    }
-
-    @Override
-    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
-            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
-        return mComputer.getSharedLibraries(packageName, flags, userId);
-    }
-
-    @Nullable
-    @Override
-    public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
-            @NonNull String packageName, @PackageManager.PackageInfoFlagsBits long flags,
-            @NonNull int userId) {
-        return mComputer.getDeclaredSharedLibraries(packageName, flags, userId);
-    }
-
-    @Nullable
-    List<VersionedPackage> getPackagesUsingSharedLibrary(
-            SharedLibraryInfo libInfo, @PackageManager.PackageInfoFlagsBits long flags,
-            int callingUid, int userId) {
-        return mComputer.getPackagesUsingSharedLibrary(libInfo, flags, callingUid, userId);
-    }
-
-    @Nullable
-    @Override
-    public ServiceInfo getServiceInfo(@NonNull ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
-        return mComputer.getServiceInfo(component, flags, userId);
-    }
-
-    @Nullable
-    @Override
-    public ProviderInfo getProviderInfo(@NonNull ComponentName component,
-            @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
-        return mComputer.getProviderInfo(component, flags, userId);
-    }
-
-    @Override
-    public ModuleInfo getModuleInfo(String packageName, @ModuleInfoFlags int flags) {
+    public ModuleInfo getModuleInfo(String packageName, @PackageManager.ModuleInfoFlags int flags) {
         return mModuleInfoProvider.getModuleInfo(packageName, flags);
     }
 
-    @Override
-    public List<ModuleInfo> getInstalledModules(int flags) {
-        return mModuleInfoProvider.getInstalledModules(flags);
-    }
-
-    @Nullable
-    @Override
-    public String[] getSystemSharedLibraryNames() {
-        return mComputer.getSystemSharedLibraryNames();
-    }
-
-    @Override
-    public @NonNull String getServicesSystemSharedLibraryPackageName() {
-        return mServicesExtensionPackageName;
-    }
-
-    @Override
-    public @NonNull String getSharedSystemSharedLibraryPackageName() {
-        return mSharedSystemSharedLibraryPackageName;
-    }
-
     @GuardedBy("mLock")
     void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
         mChangedPackagesTracker.updateSequenceNumber(pkgSetting.getPackageName(), userList);
     }
 
-    @Override
-    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        if (getInstantAppPackageName(callingUid) != null) {
-            return null;
-        }
-        if (!mUserManager.exists(userId)) {
-            return null;
-        }
-        enforceCrossUserPermission(callingUid, userId, false, false, "getChangedPackages");
-        final ChangedPackages changedPackages = mChangedPackagesTracker.getChangedPackages(
-                sequenceNumber, userId);
-
-        if (changedPackages != null) {
-            final List<String> packageNames = changedPackages.getPackageNames();
-            for (int index = packageNames.size() - 1; index >= 0; index--) {
-                // Filter out the changes if the calling package should not be able to see it.
-                final PackageSetting ps = mSettings.getPackageLPr(packageNames.get(index));
-                if (shouldFilterApplication(ps, callingUid, userId)) {
-                    packageNames.remove(index);
-                }
-            }
-        }
-
-        return changedPackages;
-    }
-
-    @Override
-    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
-        // allow instant applications
-        ArrayList<FeatureInfo> res;
-        synchronized (mAvailableFeatures) {
-            res = new ArrayList<>(mAvailableFeatures.size() + 1);
-            res.addAll(mAvailableFeatures.values());
-        }
-        final FeatureInfo fi = new FeatureInfo();
-        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
-                FeatureInfo.GL_ES_VERSION_UNDEFINED);
-        res.add(fi);
-
-        return new ParceledListSlice<>(res);
-    }
-
-    @Override
     public boolean hasSystemFeature(String name, int version) {
         // allow instant applications
         synchronized (mAvailableFeatures) {
@@ -3139,29 +2730,10 @@
     }
 
     // NOTE: Can't remove due to unsupported app usage
-    @Override
     public int checkPermission(String permName, String pkgName, int userId) {
         return mPermissionManager.checkPermission(pkgName, permName, userId);
     }
 
-    // NOTE: Can't remove without a major refactor. Keep around for now.
-    @Override
-    public int checkUidPermission(String permName, int uid) {
-        return mComputer.checkUidPermission(permName, uid);
-    }
-
-    @Override
-    public String getPermissionControllerPackageName() {
-        final int callingUid = Binder.getCallingUid();
-        if (mComputer.getPackageStateFiltered(mRequiredPermissionControllerPackage,
-                callingUid, UserHandle.getUserId(callingUid)) != null) {
-            return mRequiredPermissionControllerPackage;
-        }
-
-        throw new IllegalStateException("PermissionController is not found");
-    }
-
-    @Override
     public String getSdkSandboxPackageName() {
         return mRequiredSdkSandboxPackage;
     }
@@ -3170,172 +2742,7 @@
         return mRequiredInstallerPackage;
     }
 
-    // NOTE: Can't remove due to unsupported app usage
-    @Override
-    public boolean addPermission(PermissionInfo info) {
-        // Because this is accessed via the package manager service AIDL,
-        // go through the permission manager service AIDL
-        return mContext.getSystemService(PermissionManager.class).addPermission(info, false);
-    }
-
-    // NOTE: Can't remove due to unsupported app usage
-    @Override
-    public boolean addPermissionAsync(PermissionInfo info) {
-        // Because this is accessed via the package manager service AIDL,
-        // go through the permission manager service AIDL
-        return mContext.getSystemService(PermissionManager.class).addPermission(info, true);
-    }
-
-    // NOTE: Can't remove due to unsupported app usage
-    @Override
-    public void removePermission(String permName) {
-        // Because this is accessed via the package manager service AIDL,
-        // go through the permission manager service AIDL
-        mContext.getSystemService(PermissionManager.class).removePermission(permName);
-    }
-
-    // NOTE: Can't remove due to unsupported app usage
-    @Override
-    public void grantRuntimePermission(String packageName, String permName, final int userId) {
-        // Because this is accessed via the package manager service AIDL,
-        // go through the permission manager service AIDL
-        mContext.getSystemService(PermissionManager.class)
-                .grantRuntimePermission(packageName, permName, UserHandle.of(userId));
-    }
-
-    @Override
-    public boolean isProtectedBroadcast(String actionName) {
-        if (actionName != null) {
-            // TODO: remove these terrible hacks
-            if (actionName.startsWith("android.net.netmon.lingerExpired")
-                    || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
-                    || actionName.startsWith("com.android.internal.telephony.data-reconnect")
-                    || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
-                return true;
-            }
-        }
-         // allow instant applications
-        synchronized (mProtectedBroadcasts) {
-            return mProtectedBroadcasts.contains(actionName);
-        }
-    }
-
-    @Override
-    public int checkSignatures(@NonNull String pkg1, @NonNull String pkg2) {
-        return mComputer.checkSignatures(pkg1, pkg2);
-    }
-
-    @Override
-    public int checkUidSignatures(int uid1, int uid2) {
-        return mComputer.checkUidSignatures(uid1, uid2);
-    }
-
-    @Override
-    public boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate,
-            @PackageManager.CertificateInputType int type) {
-        return mComputer.hasSigningCertificate(packageName, certificate, type);
-    }
-
-    @Override
-    public boolean hasUidSigningCertificate(int uid, @NonNull byte[] certificate,
-            @PackageManager.CertificateInputType int type) {
-        return mComputer.hasUidSigningCertificate(uid, certificate, type);
-    }
-
-    @Override
-    public List<String> getAllPackages() {
-        return mComputer.getAllPackages();
-    }
-
-    /**
-     * <em>IMPORTANT:</em> Not all packages returned by this method may be known
-     * to the system. There are two conditions in which this may occur:
-     * <ol>
-     *   <li>The package is on adoptable storage and the device has been removed</li>
-     *   <li>The package is being removed and the internal structures are partially updated</li>
-     * </ol>
-     * The second is an artifact of the current data structures and should be fixed. See
-     * b/111075456 for one such instance.
-     * This binder API is cached.  If the algorithm in this method changes,
-     * or if the underlying objecs (as returned by getSettingLPr()) change
-     * then the logic that invalidates the cache must be revisited.  See
-     * calls to invalidateGetPackagesForUidCache() to locate the points at
-     * which the cache is invalidated.
-     */
-    @Override
-    public String[] getPackagesForUid(int uid) {
-        final int callingUid = Binder.getCallingUid();
-        final int userId = UserHandle.getUserId(uid);
-        enforceCrossUserOrProfilePermission(callingUid, userId,
-                /* requireFullPermission */ false,
-                /* checkShell */ false, "getPackagesForUid");
-        return mComputer.getPackagesForUid(uid);
-    }
-
-    @Nullable
-    @Override
-    public String getNameForUid(int uid) {
-        return mComputer.getNameForUid(uid);
-    }
-
-    @Nullable
-    @Override
-    public String[] getNamesForUids(@NonNull int[] uids) {
-        return mComputer.getNamesForUids(uids);
-    }
-
-    @Override
-    public int getUidForSharedUser(@NonNull String sharedUserName) {
-        return mComputer.getUidForSharedUser(sharedUserName);
-    }
-
-    @Override
-    public int getFlagsForUid(int uid) {
-        return mComputer.getFlagsForUid(uid);
-    }
-
-    @Override
-    public int getPrivateFlagsForUid(int uid) {
-        return mComputer.getPrivateFlagsForUid(uid);
-    }
-
-    @Override
-    public boolean isUidPrivileged(int uid) {
-        return mComputer.isUidPrivileged(uid);
-    }
-
-    // NOTE: Can't remove due to unsupported app usage
-    @NonNull
-    @Override
-    public String[] getAppOpPermissionPackages(@NonNull String permissionName) {
-        return mComputer.getAppOpPermissionPackages(permissionName);
-    }
-
-    @Override
-    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
-            @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
-        return mResolveIntentHelper.resolveIntentInternal(snapshotComputer(), intent, resolvedType,
-                flags, 0 /*privateResolveFlags*/, userId, false, Binder.getCallingUid());
-    }
-
-    @Override
-    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
-        return mPreferredActivityHelper.findPersistentPreferredActivity(intent, userId);
-    }
-
-    @Override
-    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
-            IntentFilter filter, int match, ComponentName activity) {
-        mPreferredActivityHelper.setLastChosenActivity(intent, resolvedType, flags,
-                              new WatchedIntentFilter(filter), match, activity);
-    }
-
-    @Override
-    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
-        return mPreferredActivityHelper.getLastChosenActivity(intent, resolvedType, flags);
-    }
-
-    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
+    void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
             Intent origIntent, String resolvedType, String callingPackage,
             @Nullable String callingFeatureId, boolean isRequesterInstantApp,
             Bundle verificationBundle, int userId) {
@@ -3347,31 +2754,6 @@
         mHandler.sendMessage(msg);
     }
 
-    /**
-     * From Android R, camera intents have to match system apps. The only exception to this is if
-     * the DPC has set the camera persistent preferred activity. This case was introduced
-     * because it is important that the DPC has the ability to set both system and non-system
-     * camera persistent preferred activities.
-     *
-     * @return {@code true} if the intent is a camera intent and the persistent preferred
-     * activity was not set by the DPC.
-     */
-    @GuardedBy("mLock")
-    boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags) {
-        return mComputer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
-                resolvedType, flags);
-    }
-
-    @GuardedBy("mLock")
-    ResolveInfo findPersistentPreferredActivityLP(Intent intent,
-            String resolvedType,
-            @PackageManager.ResolveInfoFlagsBits long flags, List<ResolveInfo> query, boolean debug,
-            int userId) {
-        return mComputer.findPersistentPreferredActivityLP(intent,
-                resolvedType, flags, query, debug, userId);
-    }
-
     // findPreferredActivityBody returns two items: a "things changed" flag and a
     // ResolveInfo, which is the preferred activity itself.
     static class FindPreferredActivityBodyResult {
@@ -3379,251 +2761,11 @@
         ResolveInfo mPreferredResolveInfo;
     }
 
-    FindPreferredActivityBodyResult findPreferredActivityInternal(
+    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(@NonNull Computer snapshot,
             Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
-            List<ResolveInfo> query, boolean always,
-            boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
-        return mComputer.findPreferredActivityInternal(
-            intent, resolvedType, flags,
-            query, always,
-            removeMatches, debug, userId, queryMayBeFiltered);
-    }
-
-    /*
-     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
-     */
-    @Override
-    public boolean canForwardTo(@NonNull Intent intent, @Nullable String resolvedType,
-            @UserIdInt int sourceUserId, @UserIdInt int targetUserId) {
-        return mComputer.canForwardTo(intent, resolvedType, sourceUserId, targetUserId);
-    }
-
-    private UserInfo getProfileParent(int userId) {
-        return mComputer.getProfileParent(userId);
-    }
-
-    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
-            String resolvedType, int userId) {
-        return mComputer.getMatchingCrossProfileIntentFilters(intent,
-                resolvedType, userId);
-    }
-
-    @Override
-    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
-        try {
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
-
-            return new ParceledListSlice<>(snapshotComputer().queryIntentActivitiesInternal(intent,
-                    resolvedType, flags, userId));
-        } finally {
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-        }
-    }
-
-    /**
-     * Returns the package name of the calling Uid if it's an instant app. If it isn't
-     * instant, returns {@code null}.
-     */
-    String getInstantAppPackageName(int callingUid) {
-        return mComputer.getInstantAppPackageName(callingUid);
-    }
-
-    @Override
-    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
-            Intent[] specifics, String[] specificTypes, Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
-        return new ParceledListSlice<>(mResolveIntentHelper.queryIntentActivityOptionsInternal(
-                snapshotComputer(), caller, specifics, specificTypes, intent, resolvedType, flags,
-                userId));
-    }
-
-    @Override
-    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
-        return new ParceledListSlice<>(mResolveIntentHelper.queryIntentReceiversInternal(
-                snapshotComputer(), intent, resolvedType, flags, userId, Binder.getCallingUid()));
-    }
-
-    @Override
-    public ResolveInfo resolveService(Intent intent, String resolvedType,
-            @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        return mResolveIntentHelper.resolveServiceInternal(snapshotComputer(), intent, resolvedType,
-                flags, userId, callingUid);
-    }
-
-    @Override
-    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        return new ParceledListSlice<>(queryIntentServicesInternal(
-                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
-    }
-
-    @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId,
-            int callingUid, boolean includeInstantApps) {
-        return mComputer.queryIntentServicesInternal(intent,
-                resolvedType, flags, userId, callingUid,
-                includeInstantApps);
-    }
-
-    @Override
-    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
-        return new ParceledListSlice<>(mResolveIntentHelper.queryIntentContentProvidersInternal(
-                snapshotComputer(), intent, resolvedType, flags, userId));
-    }
-
-    @Override
-    public ParceledListSlice<PackageInfo> getInstalledPackages(
-            @PackageManager.PackageInfoFlagsBits long flags, int userId) {
-        return mComputer.getInstalledPackages(flags, userId);
-    }
-
-    @Override
-    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
-            @NonNull String[] permissions, @PackageManager.PackageInfoFlagsBits long flags,
             @UserIdInt int userId) {
-        return mComputer.getPackagesHoldingPermissions(permissions, flags, userId);
-    }
-
-    @Override
-    public ParceledListSlice<ApplicationInfo> getInstalledApplications(
-            @PackageManager.ApplicationInfoFlagsBits long flags, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        return new ParceledListSlice<>(
-                mComputer.getInstalledApplications(flags, userId, callingUid));
-    }
-
-    @Override
-    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
-        if (HIDE_EPHEMERAL_APIS) {
-            return null;
-        }
-        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
-            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
-                    "getEphemeralApplications");
-        }
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
-                false /* checkShell */, "getEphemeralApplications");
-
-        Computer computer = snapshotComputer();
-        List<InstantAppInfo> instantApps = mInstantAppRegistry.getInstantApps(computer, userId);
-        if (instantApps != null) {
-            return new ParceledListSlice<>(instantApps);
-        }
-        return null;
-    }
-
-    @Override
-    public boolean isInstantApp(String packageName, int userId) {
-        return mComputer.isInstantApp(packageName, userId);
-    }
-
-    private boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
-            int callingUid) {
-        return mComputer.isInstantAppInternal(packageName, userId,
-                callingUid);
-    }
-
-    @Override
-    public byte[] getInstantAppCookie(String packageName, int userId) {
-        if (HIDE_EPHEMERAL_APIS) {
-            return null;
-        }
-
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
-                false /* checkShell */, "getInstantAppCookie");
-        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
-            return null;
-        }
-        PackageStateInternal packageState = getPackageStateInternal(packageName);
-        if (packageState == null || packageState.getPkg() == null) {
-            return null;
-        }
-        return mInstantAppRegistry.getInstantAppCookie(packageState.getPkg(), userId);
-    }
-
-    @Override
-    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
-        if (HIDE_EPHEMERAL_APIS) {
-            return true;
-        }
-
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
-                true /* checkShell */, "setInstantAppCookie");
-        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
-            return false;
-        }
-
-        PackageStateInternal packageState = getPackageStateInternal(packageName);
-        if (packageState == null || packageState.getPkg() == null) {
-            return false;
-        }
-        return mInstantAppRegistry.setInstantAppCookie(packageState.getPkg(), cookie,
-                mContext.getPackageManager().getInstantAppCookieMaxBytes(), userId);
-    }
-
-    @Override
-    public Bitmap getInstantAppIcon(String packageName, int userId) {
-        if (HIDE_EPHEMERAL_APIS) {
-            return null;
-        }
-
-        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
-            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
-                    "getInstantAppIcon");
-        }
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
-                false /* checkShell */, "getInstantAppIcon");
-
-        return mInstantAppRegistry.getInstantAppIcon(packageName, userId);
-    }
-
-    boolean isCallerSameApp(String packageName, int uid) {
-        return mComputer.isCallerSameApp(packageName, uid);
-    }
-
-    @Override
-    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return ParceledListSlice.emptyList();
-        }
-        return new ParceledListSlice<>(mComputer.getPersistentApplications(mSafeMode, flags));
-    }
-
-    @Override
-    public ProviderInfo resolveContentProvider(String name,
-            @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
-        return mComputer.resolveContentProvider(name, flags, userId, Binder.getCallingUid());
-    }
-
-    @Deprecated
-    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
-        mComputer.querySyncProviders(mSafeMode, outNames, outInfo);
-    }
-
-    @NonNull
-    @Override
-    public ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable  String processName,
-            int uid, @PackageManager.ComponentInfoFlagsBits long flags,
-            @Nullable String metaDataKey) {
-        return mComputer.queryContentProviders(processName, uid, flags, metaDataKey);
-    }
-
-    @Nullable
-    @Override
-    public InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags) {
-        return mComputer.getInstrumentationInfo(component, flags);
-    }
-
-    @NonNull
-    @Override
-    public ParceledListSlice<InstrumentationInfo> queryInstrumentation(
-            @NonNull String targetPackage, int flags) {
-        return mComputer.queryInstrumentation(targetPackage, flags);
+        return new ParceledListSlice<>(mResolveIntentHelper.queryIntentReceiversInternal(
+                snapshot, intent, resolvedType, flags, userId, Binder.getCallingUid()));
     }
 
     public static void reportSettingsProblem(int priority, String msg) {
@@ -3642,40 +2784,6 @@
         return packageName + STATIC_SHARED_LIB_DELIMITER + libraryVersion;
     }
 
-    /**
-     * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
-     * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
-     *
-     * @param checkShell whether to prevent shell from access if there's a debugging restriction
-     * @param message the message to log on security exception
-     */
-    void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
-            boolean requireFullPermission, boolean checkShell, String message) {
-        mComputer.enforceCrossUserPermission(callingUid, userId,
-                requireFullPermission, checkShell, message);
-    }
-
-    /**
-     * Checks if the request is from the system or an app that has the appropriate cross-user
-     * permissions defined as follows:
-     * <ul>
-     * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
-     * <li>INTERACT_ACROSS_USERS if the given {@code userId} is in a different profile group
-     * to the caller.</li>
-     * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@code userId} is in the same profile
-     * group as the caller.</li>
-     * </ul>
-     *
-     * @param checkShell whether to prevent shell from access if there's a debugging restriction
-     * @param message the message to log on security exception
-     */
-    private void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
-            boolean requireFullPermission, boolean checkShell, String message) {
-        mComputer.enforceCrossUserOrProfilePermission(callingUid, userId,
-                requireFullPermission, checkShell, message);
-    }
-
-    @Override
     public void performFstrimIfNeeded() {
         PackageManagerServiceUtils.enforceSystemOrRoot("Only the system can request fstrim");
 
@@ -3717,28 +2825,10 @@
         }
     }
 
-    @Override
     public void updatePackagesIfNeeded() {
         mDexOptHelper.performPackageDexOptUpgradeIfNeeded();
     }
 
-    @Override
-    public void notifyPackageUse(String packageName, int reason) {
-        final int callingUid = Binder.getCallingUid();
-        final int callingUserId = UserHandle.getUserId(callingUid);
-        Computer computer = snapshotComputer();
-        final boolean notify;
-        if (getInstantAppPackageName(callingUid) != null) {
-            notify = isCallerSameApp(packageName, callingUid);
-        } else {
-            notify = !isInstantAppInternal(packageName, callingUserId, Process.SYSTEM_UID);
-        }
-        if (!notify) {
-            return;
-        }
-
-        notifyPackageUseInternal(packageName, reason);
-    }
 
     private void notifyPackageUseInternal(String packageName, int reason) {
         long time = System.currentTimeMillis();
@@ -3747,118 +2837,10 @@
         });
     }
 
-    @Override
-    public void notifyDexLoad(String loadingPackageName, Map<String, String> classLoaderContextMap,
-            String loaderIsa) {
-        int callingUid = Binder.getCallingUid();
-        if (PLATFORM_PACKAGE_NAME.equals(loadingPackageName) && callingUid != Process.SYSTEM_UID) {
-            Slog.w(TAG, "Non System Server process reporting dex loads as system server. uid="
-                    + callingUid);
-            // Do not record dex loads from processes pretending to be system server.
-            // Only the system server should be assigned the package "android", so reject calls
-            // that don't satisfy the constraint.
-            //
-            // notifyDexLoad is a PM API callable from the app process. So in theory, apps could
-            // craft calls to this API and pretend to be system server. Doing so poses no particular
-            // danger for dex load reporting or later dexopt, however it is a sensible check to do
-            // in order to verify the expectations.
-            return;
-        }
-
-        int userId = UserHandle.getCallingUserId();
-        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
-        if (ai == null) {
-            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
-                + loadingPackageName + ", user=" + userId);
-            return;
-        }
-        mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId,
-                Process.isIsolated(callingUid));
-    }
-
-    @Override
-    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
-            IDexModuleRegisterCallback callback) {
-        int userId = UserHandle.getCallingUserId();
-        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
-        DexManager.RegisterDexModuleResult result;
-        if (ai == null) {
-            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
-                     " calling user. package=" + packageName + ", user=" + userId);
-            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
-        } else {
-            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
-        }
-
-        if (callback != null) {
-            mHandler.post(() -> {
-                try {
-                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
-                }
-            });
-        }
-    }
-
-    /**
-     * Ask the package manager to perform a dex-opt with the given compiler filter.
-     *
-     * Note: exposed only for the shell command to allow moving packages explicitly to a
-     *       definite state.
-     */
-    @Override
-    public boolean performDexOptMode(String packageName,
-            boolean checkProfiles, String targetCompilerFilter, boolean force,
-            boolean bootComplete, String splitName) {
-        return mDexOptHelper.performDexOptMode(packageName, checkProfiles, targetCompilerFilter,
-                force, bootComplete, splitName);
-    }
-
-    /**
-     * Ask the package manager to perform a dex-opt with the given compiler filter on the
-     * secondary dex files belonging to the given package.
-     *
-     * Note: exposed only for the shell command to allow moving packages explicitly to a
-     *       definite state.
-     */
-    @Override
-    public boolean performDexOptSecondary(String packageName, String compilerFilter,
-            boolean force) {
-        return mDexOptHelper.performDexOptSecondary(packageName, compilerFilter, force);
-    }
-
-    /**
-     * Reconcile the information we have about the secondary dex files belonging to
-     * {@code packageName} and the actual dex files. For all dex files that were
-     * deleted, update the internal records and delete the generated oat files.
-     */
-    @Override
-    public void reconcileSecondaryDexFiles(String packageName) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return;
-        } else if (isInstantAppInternal(
-                packageName, UserHandle.getCallingUserId(), Process.SYSTEM_UID)) {
-            return;
-        }
-        mDexManager.reconcileSecondaryDexFiles(packageName);
-    }
-
     /*package*/ DexManager getDexManager() {
         return mDexManager;
     }
 
-    @NonNull
-    List<PackageStateInternal> findSharedNonSystemLibraries(
-            @NonNull PackageStateInternal pkgSetting) {
-        return mComputer.findSharedNonSystemLibraries(pkgSetting);
-    }
-
-    @Nullable
-    SharedLibraryInfo getSharedLibraryInfo(String name, long version) {
-        return mComputer.getSharedLibraryInfo(name, version);
-    }
-
     public void shutdown() {
         mCompilerStats.writeNow();
         mDexManager.writePackageDexUsageNow();
@@ -3874,67 +2856,10 @@
         }
     }
 
-    @Override
-    public void dumpProfiles(String packageName) {
-        /* Only the shell, root, or the app user should be able to dump profiles. */
-        final int callingUid = Binder.getCallingUid();
-        final String[] callerPackageNames = getPackagesForUid(callingUid);
-        if (callingUid != Process.SHELL_UID
-                && callingUid != Process.ROOT_UID
-                && !ArrayUtils.contains(callerPackageNames, packageName)) {
-            throw new SecurityException("dumpProfiles");
-        }
-
-        AndroidPackage pkg = getPackage(packageName);
-        if (pkg == null) {
-            throw new IllegalArgumentException("Unknown package: " + packageName);
-        }
-
-        synchronized (mInstallLock) {
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
-            mArtManagerService.dumpProfiles(pkg);
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-        }
-    }
-
-    @Override
-    public void forceDexOpt(String packageName) {
-        mDexOptHelper.forceDexOpt(packageName);
-    }
-
     int[] resolveUserIds(int userId) {
         return (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] { userId };
     }
 
-    @Override
-    public Property getProperty(String propertyName, String packageName, String className) {
-        Objects.requireNonNull(propertyName);
-        Objects.requireNonNull(packageName);
-        PackageStateInternal packageState = mComputer.getPackageStateFiltered(packageName,
-                Binder.getCallingUid(), UserHandle.getCallingUserId());
-        if (packageState == null) {
-            return null;
-        }
-        return mPackageProperty.getProperty(propertyName, packageName, className);
-    }
-
-    @Override
-    public ParceledListSlice<Property> queryProperty(
-            String propertyName, @PropertyLocation int componentType) {
-        Objects.requireNonNull(propertyName);
-        final int callingUid = Binder.getCallingUid();
-        final int callingUserId = UserHandle.getCallingUserId();
-        final List<Property> result =
-                mPackageProperty.queryProperty(propertyName, componentType, packageName -> {
-                    final PackageStateInternal ps = getPackageStateInternal(packageName);
-                    return shouldFilterApplication(ps, callingUid, callingUserId);
-                });
-        if (result == null) {
-            return ParceledListSlice.emptyList();
-        }
-        return new ParceledListSlice<>(result);
-    }
-
     private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
         if (installerActivity == null) {
             if (DEBUG_INSTANT) {
@@ -4013,14 +2938,14 @@
         mPackageObserverHelper.notifyRemoved(packageName, uid);
     }
 
-    void sendPackageAddedForUser(String packageName, @NonNull PackageStateInternal packageState,
-            int userId, int dataLoaderType) {
+    void sendPackageAddedForUser(@NonNull Computer snapshot, String packageName,
+            @NonNull PackageStateInternal packageState, int userId, int dataLoaderType) {
         final PackageUserStateInternal userState = packageState.getUserStateOrDefault(userId);
         final boolean isSystem = packageState.isSystem();
         final boolean isInstantApp = userState.isInstantApp();
         final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
         final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
-        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
+        sendPackageAddedForNewUsers(snapshot, packageName, isSystem /*sendBootCompleted*/,
                 false /*startReceiver*/, packageState.getAppId(), userIds, instantUserIds,
                 dataLoaderType);
 
@@ -4032,15 +2957,15 @@
     }
 
     @Override
-    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
-            boolean includeStopped, @AppIdInt int appId, int[] userIds, int[] instantUserIds,
-            int dataLoaderType) {
+    public void sendPackageAddedForNewUsers(@NonNull Computer snapshot, String packageName,
+            boolean sendBootCompleted, boolean includeStopped, @AppIdInt int appId, int[] userIds,
+            int[] instantUserIds, int dataLoaderType) {
         if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
             return;
         }
         SparseArray<int[]> broadcastAllowList = mAppsFilter.getVisibilityAllowList(
-                getPackageStateInternal(packageName, Process.SYSTEM_UID),
-                userIds, getPackageStates());
+                snapshot.getPackageStateInternal(packageName, Process.SYSTEM_UID),
+                userIds, snapshot.getPackageStates());
         mHandler.post(() -> mBroadcastHelper.sendPackageAddedForNewUsers(
                 packageName, appId, userIds, instantUserIds, dataLoaderType, broadcastAllowList));
         if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
@@ -4054,159 +2979,6 @@
         }
     }
 
-    @Override
-    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
-            int userId) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
-        final int callingUid = Binder.getCallingUid();
-        enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
-                true /* checkShell */, "setApplicationHiddenSetting for user " + userId);
-
-        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
-            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
-            return false;
-        }
-
-        // Do not allow "android" is being disabled
-        if ("android".equals(packageName)) {
-            Slog.w(TAG, "Cannot hide package: android");
-            return false;
-        }
-
-        final long callingId = Binder.clearCallingIdentity();
-        try {
-            final PackageStateInternal packageState =
-                    mComputer.getPackageStateFiltered(packageName, callingUid, userId);
-            if (packageState == null) {
-                return false;
-            }
-
-            // Cannot hide static shared libs as they are considered
-            // a part of the using app (emulating static linking). Also
-            // static libs are installed always on internal storage.
-            AndroidPackage pkg = packageState.getPkg();
-            if (pkg != null) {
-                // Cannot hide SDK libs as they are controlled by SDK manager.
-                if (pkg.getSdkLibName() != null) {
-                    Slog.w(TAG, "Cannot hide package: " + packageName
-                            + " providing SDK library: "
-                            + pkg.getSdkLibName());
-                    return false;
-                }
-                // Cannot hide static shared libs as they are considered
-                // a part of the using app (emulating static linking). Also
-                // static libs are installed always on internal storage.
-                if (pkg.getStaticSharedLibName() != null) {
-                    Slog.w(TAG, "Cannot hide package: " + packageName
-                            + " providing static shared library: "
-                            + pkg.getStaticSharedLibName());
-                    return false;
-                }
-            }
-            // Only allow protected packages to hide themselves.
-            if (hidden && !UserHandle.isSameApp(callingUid, packageState.getAppId())
-                    && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
-                Slog.w(TAG, "Not hiding protected package: " + packageName);
-                return false;
-            }
-
-            if (packageState.getUserStateOrDefault(userId).isHidden() == hidden) {
-                return false;
-            }
-
-            commitPackageStateMutation(null, packageName, packageState1 ->
-                    packageState1.userState(userId).setHidden(hidden));
-
-            final PackageStateInternal newPackageState = getPackageStateInternal(packageName);
-
-            if (hidden) {
-                killApplication(packageName, newPackageState.getAppId(), userId, "hiding pkg");
-                sendApplicationHiddenForUser(packageName, newPackageState, userId);
-            } else {
-                sendPackageAddedForUser(packageName, newPackageState, userId, DataLoaderType.NONE);
-            }
-
-            scheduleWritePackageRestrictions(userId);
-            return true;
-        } finally {
-            Binder.restoreCallingIdentity(callingId);
-        }
-    }
-
-    @Override
-    public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
-        final int callingUid = Binder.getCallingUid();
-        final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
-                || callingUid == Process.SYSTEM_UID;
-        if (!calledFromSystemOrPhone) {
-            mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
-                    "setSystemAppHiddenUntilInstalled");
-        }
-
-        final PackageStateInternal stateRead = getPackageStateInternal(packageName);
-        if (stateRead == null || !stateRead.isSystem() || stateRead.getPkg() == null) {
-            return;
-        }
-        if (stateRead.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
-            throw new SecurityException("Only system or phone callers can modify core apps");
-        }
-
-        commitPackageStateMutation(null, mutator -> {
-            mutator.forPackage(packageName)
-                    .setHiddenUntilInstalled(hidden);
-            mutator.forDisabledSystemPackage(packageName)
-                    .setHiddenUntilInstalled(hidden);
-        });
-    }
-
-    @Override
-    public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
-                || callingUid == Process.SYSTEM_UID;
-        if (!calledFromSystemOrPhone) {
-            mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
-                    "setSystemAppHiddenUntilInstalled");
-        }
-
-        final PackageStateInternal packageState = getPackageStateInternal(packageName);
-        // The target app should always be in system
-        if (packageState == null || !packageState.isSystem() || packageState.getPkg() == null) {
-            return false;
-        }
-        if (packageState.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
-            throw new SecurityException("Only system or phone callers can modify core apps");
-        }
-        // Check if the install state is the same
-        if (packageState.getUserStateOrDefault(userId).isInstalled() == installed) {
-            return false;
-        }
-
-        final long callingId = Binder.clearCallingIdentity();
-        try {
-            if (installed) {
-                // install the app from uninstalled state
-                installExistingPackageAsUser(
-                        packageName,
-                        userId,
-                        PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
-                        PackageManager.INSTALL_REASON_DEVICE_SETUP,
-                        null);
-                return true;
-            }
-
-            // uninstall the app from installed state
-            deletePackageVersioned(
-                    new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
-                    new LegacyPackageDeleteObserver(null).getBinder(),
-                    userId,
-                    PackageManager.DELETE_SYSTEM_APP);
-            return true;
-        } finally {
-            Binder.restoreCallingIdentity(callingId);
-        }
-    }
-
     private void sendApplicationHiddenForUser(String packageName, PackageStateInternal packageState,
             int userId) {
         final PackageRemovedInfo info = new PackageRemovedInfo(this);
@@ -4218,26 +2990,6 @@
         info.sendPackageRemovedBroadcasts(true /*killApp*/, false /*removedBySystem*/);
     }
 
-    /**
-     * Returns true if application is not found or there was an error. Otherwise it returns
-     * the hidden state of the package for the given user.
-     */
-    @Override
-    public boolean getApplicationHiddenSettingAsUser(@NonNull String packageName,
-            @UserIdInt int userId) {
-        return mComputer.getApplicationHiddenSettingAsUser(packageName, userId);
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
-            int installReason, List<String> whiteListedPermissions) {
-        return mInstallPackageHelper.installExistingPackageAsUser(packageName, userId, installFlags,
-                installReason, whiteListedPermissions, null);
-    }
-
     boolean isUserRestricted(int userId, String restrictionKey) {
         Bundle restrictions = mUserManager.getUserRestrictions(userId);
         if (restrictions.getBoolean(restrictionKey, false)) {
@@ -4247,79 +2999,8 @@
         return false;
     }
 
-    @Override
-    public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames,
-            int restrictionFlags, int userId) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
-                "setDistractingPackageRestrictionsAsUser");
-
-        final int callingUid = Binder.getCallingUid();
-        if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
-                && UserHandle.getUserId(callingUid) != userId) {
-            throw new SecurityException("Calling uid " + callingUid + " cannot call for user "
-                    + userId);
-        }
-        Objects.requireNonNull(packageNames, "packageNames cannot be null");
-        if (restrictionFlags != 0
-                && !mSuspendPackageHelper.isSuspendAllowedForUser(userId, callingUid)) {
-            Slog.w(TAG, "Cannot restrict packages due to restrictions on user " + userId);
-            return packageNames;
-        }
-
-        final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
-        final IntArray changedUids = new IntArray(packageNames.length);
-        final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
-
-        ArraySet<String> changesToCommit = new ArraySet<>();
-        Computer computer = snapshotComputer();
-        final boolean[] canRestrict = (restrictionFlags != 0)
-                ? mSuspendPackageHelper.canSuspendPackageForUser(computer, packageNames, userId,
-                callingUid) : null;
-        for (int i = 0; i < packageNames.length; i++) {
-            final String packageName = packageNames[i];
-            final PackageStateInternal packageState =
-                    computer.getPackageStateInternal(packageName);
-            if (packageState == null
-                    || computer.shouldFilterApplication(packageState, callingUid, userId)) {
-                Slog.w(TAG, "Could not find package setting for package: " + packageName
-                        + ". Skipping...");
-                unactionedPackages.add(packageName);
-                continue;
-            }
-            if (canRestrict != null && !canRestrict[i]) {
-                unactionedPackages.add(packageName);
-                continue;
-            }
-            final int oldDistractionFlags = packageState.getUserStateOrDefault(userId)
-                    .getDistractionFlags();
-            if (restrictionFlags != oldDistractionFlags) {
-                changedPackagesList.add(packageName);
-                changedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
-                changesToCommit.add(packageName);
-            }
-        }
-
-        commitPackageStateMutation(null, mutator -> {
-            final int size = changesToCommit.size();
-            for (int index = 0; index < size; index++) {
-                mutator.forPackage(changesToCommit.valueAt(index))
-                        .userState(userId)
-                        .setDistractionFlags(restrictionFlags);
-            }
-        });
-
-        if (!changedPackagesList.isEmpty()) {
-            final String[] changedPackages = changedPackagesList.toArray(
-                    new String[changedPackagesList.size()]);
-            mHandler.post(() -> mBroadcastHelper.sendDistractingPackagesChanged(
-                    changedPackages, changedUids.toArray(), userId, restrictionFlags));
-            scheduleWritePackageRestrictions(userId);
-        }
-        return unactionedPackages.toArray(new String[0]);
-    }
-
-    private void enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid,
-            int userId, String callingMethod) {
+    private void enforceCanSetPackagesSuspendedAsUser(@NonNull Computer snapshot,
+            String callingPackage, int callingUid, int userId, String callingMethod) {
         if (callingUid == Process.ROOT_UID
                 // Need to compare app-id to allow system dialogs access on secondary users
                 || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
@@ -4328,7 +3009,7 @@
 
         final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
         if (ownerPackage != null) {
-            final int ownerUid = getPackageUid(ownerPackage, 0, userId);
+            final int ownerUid = snapshot.getPackageUid(ownerPackage, 0, userId);
             if (ownerUid == callingUid) {
                 return;
             }
@@ -4337,7 +3018,7 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
                 callingMethod);
 
-        final int packageUid = getPackageUid(callingPackage, 0, userId);
+        final int packageUid = snapshot.getPackageUid(callingPackage, 0, userId);
         final boolean allowedPackageUid = packageUid == callingUid;
         // TODO(b/139383163): remove special casing for shell and enforce INTERACT_ACROSS_USERS_FULL
         final boolean allowedShell = callingUid == SHELL_UID
@@ -4349,34 +3030,6 @@
         }
     }
 
-    @Override
-    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
-            PersistableBundle appExtras, PersistableBundle launcherExtras,
-            SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
-                "setPackagesSuspendedAsUser");
-        return mSuspendPackageHelper.setPackagesSuspended(snapshotComputer(), packageNames,
-                suspended, appExtras, launcherExtras, dialogInfo, callingPackage, userId,
-                callingUid);
-    }
-
-    @Override
-    public Bundle getSuspendedPackageAppExtras(String packageName, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        if (getPackageUid(packageName, 0, userId) != callingUid) {
-            throw new SecurityException("Calling package " + packageName
-                    + " does not belong to calling uid " + callingUid);
-        }
-        return mSuspendPackageHelper.getSuspendedPackageAppExtras(
-                packageName, userId, callingUid);
-    }
-
-    @Override
-    public boolean isPackageSuspendedForUser(@NonNull String packageName, @UserIdInt int userId) {
-        return mComputer.isPackageSuspendedForUser(packageName, userId);
-    }
-
     void unsuspendForSuspendingPackage(@NonNull Computer computer, String suspendingPackage,
             @UserIdInt int userId) {
         // TODO: This can be replaced by a special parameter to iterate all packages, rather than
@@ -4386,13 +3039,9 @@
                 allPackages, suspendingPackage::equals, userId);
     }
 
-    private boolean isSuspendingAnyPackages(String suspendingPackage, int userId) {
-        return mComputer.isSuspendingAnyPackages(suspendingPackage, userId);
-    }
-
-    void removeAllDistractingPackageRestrictions(int userId) {
-        final String[] allPackages = mComputer.getAllAvailablePackageNames();
-        removeDistractingPackageRestrictions(allPackages, userId);
+    void removeAllDistractingPackageRestrictions(@NonNull Computer snapshot, int userId) {
+        final String[] allPackages = snapshot.getAllAvailablePackageNames();
+        removeDistractingPackageRestrictions(snapshot, allPackages, userId);
     }
 
     /**
@@ -4404,11 +3053,12 @@
      * @param packagesToChange The packages on which restrictions are to be removed.
      * @param userId the user for which changes are taking place.
      */
-    private void removeDistractingPackageRestrictions(String[] packagesToChange, int userId) {
+    void removeDistractingPackageRestrictions(@NonNull Computer snapshot,
+            String[] packagesToChange, int userId) {
         final List<String> changedPackages = new ArrayList<>();
         final IntArray changedUids = new IntArray();
         for (String packageName : packagesToChange) {
-            final PackageStateInternal ps = getPackageStateInternal(packageName);
+            final PackageStateInternal ps = snapshot.getPackageStateInternal(packageName);
             if (ps != null && ps.getUserStateOrDefault(userId).getDistractionFlags() != 0) {
                 changedPackages.add(ps.getPackageName());
                 changedUids.add(UserHandle.getUid(userId, ps.getAppId()));
@@ -4431,291 +3081,13 @@
         }
     }
 
-    @Override
-    public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
-        Objects.requireNonNull(packageNames, "packageNames cannot be null");
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
-                "getUnsuspendablePackagesForUser");
-        final int callingUid = Binder.getCallingUid();
-        if (UserHandle.getUserId(callingUid) != userId) {
-            throw new SecurityException("Calling uid " + callingUid
-                    + " cannot query getUnsuspendablePackagesForUser for user " + userId);
-        }
-        return mSuspendPackageHelper.getUnsuspendablePackagesForUser(snapshotComputer(),
-                packageNames, userId, callingUid);
-    }
-
-    @Override
-    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
-                "Only package verification agents can verify applications");
-        final int callingUid = Binder.getCallingUid();
-
-        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
-        final PackageVerificationResponse response = new PackageVerificationResponse(
-                verificationCode, callingUid);
-        msg.arg1 = id;
-        msg.obj = response;
-        mHandler.sendMessage(msg);
-    }
-
-    @Override
-    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
-            long millisecondsToDelay) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
-                "Only package verification agents can extend verification timeouts");
-        final int callingUid = Binder.getCallingUid();
-
-        mHandler.post(() -> {
-            final PackageVerificationState state = mPendingVerification.get(id);
-            final PackageVerificationResponse response = new PackageVerificationResponse(
-                    verificationCodeAtTimeout, callingUid);
-
-            long delay = millisecondsToDelay;
-            if (delay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
-                delay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
-            }
-            if (delay < 0) {
-                delay = 0;
-            }
-
-            if ((state != null) && !state.timeoutExtended()) {
-                state.extendTimeout();
-
-                final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
-                msg.arg1 = id;
-                msg.obj = response;
-                mHandler.sendMessageDelayed(msg, delay);
-            }
-        });
-    }
-
-    private void setEnableRollbackCode(int token, int enableRollbackCode) {
+    void setEnableRollbackCode(int token, int enableRollbackCode) {
         final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS);
         msg.arg1 = token;
         msg.arg2 = enableRollbackCode;
         mHandler.sendMessage(msg);
     }
 
-    @Override
-    public void finishPackageInstall(int token, boolean didLaunch) {
-        PackageManagerServiceUtils.enforceSystemOrRoot(
-                "Only the system is allowed to finish installs");
-
-        if (DEBUG_INSTALL) {
-            Slog.v(TAG, "BM finishing package install for " + token);
-        }
-        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
-
-        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
-        mHandler.sendMessage(msg);
-    }
-
-    @Deprecated
-    @Override
-    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
-        DomainVerificationProxyV1.queueLegacyVerifyResult(mContext, mDomainVerificationConnection,
-                id, verificationCode, failedDomains, Binder.getCallingUid());
-    }
-
-    @Deprecated
-    @Override
-    public int getIntentVerificationStatus(String packageName, int userId) {
-        return mDomainVerificationManager.getLegacyState(packageName, userId);
-    }
-
-    @Deprecated
-    @Override
-    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
-        return mDomainVerificationManager.setLegacyUserState(packageName, userId, status);
-    }
-
-    @Deprecated
-    @Override
-    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
-            String packageName) {
-        return ParceledListSlice.emptyList();
-    }
-
-    @NonNull
-    @Override
-    public ParceledListSlice<IntentFilter> getAllIntentFilters(@NonNull String packageName) {
-        return mComputer.getAllIntentFilters(packageName);
-    }
-
-    @Override
-    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
-        final int callingUid = Binder.getCallingUid();
-        final int callingUserId = UserHandle.getUserId(callingUid);
-        final FunctionalUtils.ThrowingCheckedFunction<Computer, Boolean, RuntimeException>
-                implementation = computer -> {
-            if (computer.getInstantAppPackageName(callingUid) != null) {
-                return false;
-            }
-
-            PackageStateInternal targetPackageState =
-                    computer.getPackageStateInternal(targetPackage);
-            if (targetPackageState == null
-                    || computer.shouldFilterApplication(targetPackageState, callingUid,
-                    callingUserId)) {
-                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
-            }
-
-            PackageStateInternal installerPackageState = null;
-            if (installerPackageName != null) {
-                installerPackageState = computer.getPackageStateInternal(installerPackageName);
-                if (installerPackageState == null
-                        || shouldFilterApplication(
-                        installerPackageState, callingUid, callingUserId)) {
-                    throw new IllegalArgumentException("Unknown installer package: "
-                            + installerPackageName);
-                }
-            }
-
-            Signature[] callerSignature;
-            final int appId = UserHandle.getAppId(callingUid);
-            Pair<PackageStateInternal, SharedUserApi> either =
-                    computer.getPackageOrSharedUser(appId);
-            if (either != null) {
-                if (either.first != null) {
-                    callerSignature = either.first.getSigningDetails().getSignatures();
-                } else {
-                    callerSignature = either.second.getSigningDetails().getSignatures();
-                }
-            } else {
-                throw new SecurityException("Unknown calling UID: " + callingUid);
-            }
-
-            // Verify: can't set installerPackageName to a package that is
-            // not signed with the same cert as the caller.
-            if (installerPackageState != null) {
-                if (compareSignatures(callerSignature,
-                        installerPackageState.getSigningDetails().getSignatures())
-                        != PackageManager.SIGNATURE_MATCH) {
-                    throw new SecurityException(
-                            "Caller does not have same cert as new installer package "
-                                    + installerPackageName);
-                }
-            }
-
-            // Verify: if target already has an installer package, it must
-            // be signed with the same cert as the caller.
-            String targetInstallerPackageName =
-                    targetPackageState.getInstallSource().installerPackageName;
-            PackageStateInternal targetInstallerPkgSetting = targetInstallerPackageName == null
-                    ? null : computer.getPackageStateInternal(targetInstallerPackageName);
-
-            if (targetInstallerPkgSetting != null) {
-                if (compareSignatures(callerSignature,
-                        targetInstallerPkgSetting.getSigningDetails().getSignatures())
-                        != PackageManager.SIGNATURE_MATCH) {
-                    throw new SecurityException(
-                            "Caller does not have same cert as old installer package "
-                                    + targetInstallerPackageName);
-                }
-            } else if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES)
-                    != PERMISSION_GRANTED) {
-                // This is probably an attempt to exploit vulnerability b/150857253 of taking
-                // privileged installer permissions when the installer has been uninstalled or
-                // was never set.
-                EventLog.writeEvent(0x534e4554, "150857253", callingUid, "");
-
-                final long binderToken = Binder.clearCallingIdentity();
-                try {
-                    if (mInjector.getCompatibility().isChangeEnabledByUid(
-                            THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE,
-                            callingUid)) {
-                        throw new SecurityException("Neither user " + callingUid
-                                + " nor current process has "
-                                + Manifest.permission.INSTALL_PACKAGES);
-                    } else {
-                        // If change disabled, fail silently for backwards compatibility
-                        return false;
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(binderToken);
-                }
-            }
-
-            return true;
-        };
-        PackageStateMutator.InitialState initialState = recordInitialState();
-        boolean allowed = implementation.apply(snapshotComputer());
-        if (allowed) {
-            // TODO: Need to lock around here to handle mSettings.addInstallerPackageNames,
-            //  should find an alternative which avoids any race conditions
-            PackageStateInternal targetPackageState;
-            synchronized (mLock) {
-                PackageStateMutator.Result result = commitPackageStateMutation(initialState,
-                        targetPackage, state -> state.setInstaller(installerPackageName));
-                if (result.isPackagesChanged() || result.isStateChanged()) {
-                    synchronized (mPackageStateWriteLock) {
-                        allowed = implementation.apply(snapshotComputer());
-                        if (allowed) {
-                            commitPackageStateMutation(null, targetPackage,
-                                    state -> state.setInstaller(installerPackageName));
-                        } else {
-                            return;
-                        }
-                    }
-                }
-                targetPackageState = getPackageStateInternal(targetPackage);
-                mSettings.addInstallerPackageNames(targetPackageState.getInstallSource());
-            }
-            mAppsFilter.addPackage(targetPackageState);
-            scheduleWriteSettings();
-        }
-    }
-
-    @Override
-    public void setApplicationCategoryHint(String packageName, int categoryHint,
-            String callerPackageName) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            throw new SecurityException("Instant applications don't have access to this method");
-        }
-        mInjector.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
-                callerPackageName);
-
-        final PackageStateMutator.InitialState initialState = recordInitialState();
-
-        final FunctionalUtils.ThrowingFunction<Computer, PackageStateMutator.Result>
-                implementation = computer -> {
-            PackageStateInternal packageState = computer.getPackageStateFiltered(packageName,
-                    Binder.getCallingUid(), UserHandle.getCallingUserId());
-            if (packageState == null) {
-                throw new IllegalArgumentException("Unknown target package " + packageName);
-            }
-
-            if (!Objects.equals(callerPackageName,
-                    packageState.getInstallSource().installerPackageName)) {
-                throw new IllegalArgumentException("Calling package " + callerPackageName
-                        + " is not installer for " + packageName);
-            }
-
-            if (packageState.getCategoryOverride() != categoryHint) {
-                return commitPackageStateMutation(initialState,
-                        packageName, state -> state.setCategoryOverride(categoryHint));
-            } else {
-                return null;
-            }
-        };
-
-        PackageStateMutator.Result result = implementation.apply(snapshotComputer());
-        if (result != null && result.isStateChanged() && !result.isSpecificPackageNull()) {
-            // TODO: Specific return value of what state changed?
-            // The installer on record might have changed, retry with lock
-            synchronized (mPackageStateWriteLock) {
-                result = implementation.apply(snapshotComputer());
-            }
-        }
-
-        if (result != null && result.isCommitted()) {
-            scheduleWriteSettings();
-        }
-    }
-
     /**
      * Callback from PackageSettings whenever an app is first transitioned out of the
      * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
@@ -4756,7 +3128,7 @@
             if (DEBUG_BACKUP) {
                 Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
             }
-            final boolean isInstantApp = isInstantAppInternal(
+            final boolean isInstantApp = snapshotComputer().isInstantAppInternal(
                     packageName, userId, Process.SYSTEM_UID);
             final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
             final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
@@ -4794,52 +3166,34 @@
         }
     }
 
-    @Override
-    public void deletePackageAsUser(String packageName, int versionCode,
-            IPackageDeleteObserver observer, int userId, int flags) {
-        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
-                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
-    }
-
-    @Override
     public void deleteExistingPackageAsUser(VersionedPackage versionedPackage,
             final IPackageDeleteObserver2 observer, final int userId) {
         mDeletePackageHelper.deleteExistingPackageAsUser(
                 versionedPackage, observer, userId);
     }
 
-    @Override
     public void deletePackageVersioned(VersionedPackage versionedPackage,
             final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
         mDeletePackageHelper.deletePackageVersionedInternal(
                 versionedPackage, observer, userId, deleteFlags, false);
     }
 
-    private String resolveExternalPackageName(AndroidPackage pkg) {
-        return mComputer.resolveExternalPackageName(pkg);
-    }
-
-    String resolveInternalPackageName(String packageName, long versionCode) {
-        return mComputer.resolveInternalPackageName(packageName, versionCode);
-    }
-
-    boolean isCallerVerifier(int callingUid) {
+    boolean isCallerVerifier(@NonNull Computer snapshot, int callingUid) {
         final int callingUserId = UserHandle.getUserId(callingUid);
-        return mRequiredVerifierPackage != null &&
-                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
+        return mRequiredVerifierPackage != null && callingUid == snapshot.getPackageUid(
+                mRequiredVerifierPackage, 0, callingUserId);
     }
 
-    @Override
-    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
+    public boolean isPackageDeviceAdminOnAnyUser(@NonNull Computer snapshot, String packageName) {
         final int callingUid = Binder.getCallingUid();
-        if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
+        if (snapshot.checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
                 != PERMISSION_GRANTED) {
             EventLog.writeEvent(0x534e4554, "128599183", -1, "");
             throw new SecurityException(android.Manifest.permission.MANAGE_USERS
                     + " permission is required to call this API");
         }
-        if (getInstantAppPackageName(callingUid) != null
-                && !isCallerSameApp(packageName, callingUid)) {
+        if (snapshot.getInstantAppPackageName(callingUid) != null
+                && !snapshot.isCallerSameApp(packageName, callingUid)) {
             return false;
         }
         return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
@@ -4888,147 +3242,15 @@
         return mDevicePolicyManager;
     }
 
-    @Override
-    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
+    private boolean clearApplicationUserDataLIF(@NonNull Computer snapshot, String packageName,
             int userId) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.DELETE_PACKAGES, null);
-        PackageStateInternal packageState = getPackageStateInternal(packageName);
-        if (packageState != null && packageState.getPkg() != null) {
-            AndroidPackage pkg = packageState.getPkg();
-            // Cannot block uninstall SDK libs as they are controlled by SDK manager.
-            if (pkg.getSdkLibName() != null) {
-                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
-                        + " providing SDK library: " + pkg.getSdkLibName());
-                return false;
-            }
-            // Cannot block uninstall of static shared libs as they are
-            // considered a part of the using app (emulating static linking).
-            // Also static libs are installed always on internal storage.
-            if (pkg.getStaticSharedLibName() != null) {
-                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
-                        + " providing static shared library: " + pkg.getStaticSharedLibName());
-                return false;
-            }
-        }
-        synchronized (mLock) {
-            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
-        }
-
-        scheduleWritePackageRestrictions(userId);
-        return true;
-    }
-
-    @Override
-    public boolean getBlockUninstallForUser(@NonNull String packageName, @UserIdInt int userId) {
-        return mComputer.getBlockUninstallForUser(packageName, userId);
-    }
-
-    @Override
-    public boolean setRequiredForSystemUser(String packageName, boolean requiredForSystemUser) {
-        PackageManagerServiceUtils.enforceSystemOrRoot(
-                "setRequiredForSystemUser can only be run by the system or root");
-
-        PackageStateMutator.Result result = commitPackageStateMutation(null, packageName,
-                packageState -> packageState.setRequiredForSystemUser(requiredForSystemUser));
-        if (!result.isCommitted()) {
-            return false;
-        }
-
-        scheduleWriteSettings();
-        return true;
-    }
-
-    @Override
-    public void clearApplicationProfileData(String packageName) {
-        PackageManagerServiceUtils.enforceSystemOrRoot(
-                "Only the system can clear all profile data");
-
-        final AndroidPackage pkg = getPackage(packageName);
-        try (PackageFreezer ignored = freezePackage(packageName, "clearApplicationProfileData")) {
-            synchronized (mInstallLock) {
-                mAppDataHelper.clearAppProfilesLIF(pkg);
-            }
-        }
-    }
-
-    @Override
-    public void clearApplicationUserData(final String packageName,
-            final IPackageDataObserver observer, final int userId) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
-
-        final int callingUid = Binder.getCallingUid();
-        enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
-                false /* checkShell */, "clear application data");
-
-        if (mComputer.getPackageStateFiltered(packageName, callingUid, userId) == null) {
-            if (observer != null) {
-                mHandler.post(() -> {
-                    try {
-                        observer.onRemoveCompleted(packageName, false);
-                    } catch (RemoteException e) {
-                        Log.i(TAG, "Observer no longer exists.");
-                    }
-                });
-            }
-            return;
-        }
-        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
-            throw new SecurityException("Cannot clear data for a protected package: "
-                    + packageName);
-        }
-
-        // Queue up an async operation since the package deletion may take a little while.
-        mHandler.post(new Runnable() {
-            public void run() {
-                mHandler.removeCallbacks(this);
-                final boolean succeeded;
-                try (PackageFreezer freezer = freezePackage(packageName,
-                        "clearApplicationUserData")) {
-                    synchronized (mInstallLock) {
-                        succeeded = clearApplicationUserDataLIF(packageName, userId);
-                    }
-                    mInstantAppRegistry.deleteInstantApplicationMetadata(packageName, userId);
-                    synchronized (mLock) {
-                        if (succeeded) {
-                            resetComponentEnabledSettingsIfNeededLPw(packageName, userId);
-                        }
-                    }
-                }
-                if (succeeded) {
-                    // invoke DeviceStorageMonitor's update method to clear any notifications
-                    DeviceStorageMonitorInternal dsm = LocalServices
-                            .getService(DeviceStorageMonitorInternal.class);
-                    if (dsm != null) {
-                        dsm.checkMemory();
-                    }
-                    if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
-                            == PERMISSION_GRANTED) {
-                        unsuspendForSuspendingPackage(snapshotComputer(), packageName, userId);
-                        removeAllDistractingPackageRestrictions(userId);
-                        flushPackageRestrictionsAsUserInternalLocked(userId);
-                    }
-                }
-                if (observer != null) {
-                    try {
-                        observer.onRemoveCompleted(packageName, succeeded);
-                    } catch (RemoteException e) {
-                        Log.i(TAG, "Observer no longer exists.");
-                    }
-                } //end if observer
-            } //end run
-        });
-    }
-
-    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
         if (packageName == null) {
             Slog.w(TAG, "Attempt to delete null packageName.");
             return false;
         }
 
         // Try finding details about the requested package
-        AndroidPackage pkg = getPackage(packageName);
+        AndroidPackage pkg = snapshot.getPackage(packageName);
         if (pkg == null) {
             Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
             return false;
@@ -5051,8 +3273,8 @@
         } else {
             flags = 0;
         }
-        mAppDataHelper.prepareAppDataContentsLIF(pkg, getPackageStateInternal(packageName), userId,
-                flags);
+        mAppDataHelper.prepareAppDataContentsLIF(pkg, snapshot.getPackageStateInternal(packageName),
+                userId, flags);
 
         return true;
     }
@@ -5103,106 +3325,10 @@
         }
     }
 
-    @Override
-    public void deleteApplicationCacheFiles(final String packageName,
-            final IPackageDataObserver observer) {
-        final int userId = UserHandle.getCallingUserId();
-        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
-    }
-
-    @Override
-    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
-            final IPackageDataObserver observer) {
-        final int callingUid = Binder.getCallingUid();
-        if (mContext.checkCallingOrSelfPermission(
-                android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
-                != PackageManager.PERMISSION_GRANTED) {
-            // If the caller has the old delete cache permission, silently ignore.  Else throw.
-            if (mContext.checkCallingOrSelfPermission(
-                    android.Manifest.permission.DELETE_CACHE_FILES)
-                    == PackageManager.PERMISSION_GRANTED) {
-                Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
-                        android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
-                        ", silently ignoring");
-                return;
-            }
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
-        }
-        enforceCrossUserPermission(callingUid, userId, /* requireFullPermission= */ true,
-                /* checkShell= */ false, "delete application cache files");
-        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
-                android.Manifest.permission.ACCESS_INSTANT_APPS);
-
-        final AndroidPackage pkg = getPackage(packageName);
-
-        // Queue up an async operation since the package deletion may take a little while.
-        mHandler.post(() -> {
-            final PackageStateInternal ps =
-                    pkg == null ? null : getPackageStateInternal(pkg.getPackageName());
-            boolean doClearData = true;
-            if (ps != null) {
-                final boolean targetIsInstantApp =
-                        ps.getUserStateOrDefault(UserHandle.getUserId(callingUid)).isInstantApp();
-                doClearData = !targetIsInstantApp
-                        || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
-            }
-            if (doClearData) {
-                synchronized (mInstallLock) {
-                    final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
-                    // We're only clearing cache files, so we don't care if the
-                    // app is unfrozen and still able to run
-                    mAppDataHelper.clearAppDataLIF(pkg, userId,
-                            flags | Installer.FLAG_CLEAR_CACHE_ONLY);
-                    mAppDataHelper.clearAppDataLIF(pkg, userId,
-                            flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
-                }
-            }
-            if (observer != null) {
-                try {
-                    observer.onRemoveCompleted(packageName, true);
-                } catch (RemoteException e) {
-                    Log.i(TAG, "Observer no longer exists.");
-                }
-            }
-        });
-    }
-
-    @Override
-    public void getPackageSizeInfo(final String packageName, int userId,
-            final IPackageStatsObserver observer) {
-        throw new UnsupportedOperationException(
-                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
-    }
-
-    int getUidTargetSdkVersion(int uid) {
-        return mComputer.getUidTargetSdkVersion(uid);
-    }
-
-    @Override
-    public void addPreferredActivity(IntentFilter filter, int match,
-            ComponentName[] set, ComponentName activity, int userId, boolean removeExisting) {
-        mPreferredActivityHelper.addPreferredActivity(
-                new WatchedIntentFilter(filter), match, set, activity, true, userId,
-                "Adding preferred", removeExisting);
-    }
-
     void postPreferredActivityChangedBroadcast(int userId) {
         mHandler.post(() -> mBroadcastHelper.sendPreferredActivityChangedBroadcast(userId));
     }
 
-    @Override
-    public void replacePreferredActivity(IntentFilter filter, int match,
-            ComponentName[] set, ComponentName activity, int userId) {
-        mPreferredActivityHelper.replacePreferredActivity(new WatchedIntentFilter(filter), match,
-                                 set, activity, userId);
-    }
-
-    @Override
-    public void clearPackagePreferredActivities(String packageName) {
-        mPreferredActivityHelper.clearPackagePreferredActivities(packageName);
-    }
-
 
     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
     @GuardedBy("mLock")
@@ -5219,121 +3345,19 @@
 
         // Persistent preferred activity might have came into effect due to this
         // install.
-        mPreferredActivityHelper.updateDefaultHomeNotLocked(userId);
-    }
-
-    @Override
-    public void resetApplicationPreferences(int userId) {
-        mPreferredActivityHelper.resetApplicationPreferences(userId);
-    }
-
-    @Override
-    public int getPreferredActivities(List<IntentFilter> outFilters,
-            List<ComponentName> outActivities, String packageName) {
-        return mPreferredActivityHelper.getPreferredActivities(outFilters, outActivities,
-                packageName, mComputer);
-    }
-
-    @Override
-    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
-            int userId) {
-        mPreferredActivityHelper.addPersistentPreferredActivity(new WatchedIntentFilter(filter),
-                activity, userId);
-    }
-
-    @Override
-    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
-        mPreferredActivityHelper.clearPackagePersistentPreferredActivities(packageName, userId);
-    }
-
-    /**
-     * Non-Binder method, support for the backup/restore mechanism: write the
-     * full set of preferred activities in its canonical XML format.  Returns the
-     * XML output as a byte array, or null if there is none.
-     */
-    @Override
-    public byte[] getPreferredActivityBackup(int userId) {
-        return mPreferredActivityHelper.getPreferredActivityBackup(userId);
-    }
-
-    @Override
-    public void restorePreferredActivities(byte[] backup, int userId) {
-        mPreferredActivityHelper.restorePreferredActivities(backup, userId);
-    }
-
-    /**
-     * Non-Binder method, support for the backup/restore mechanism: write the
-     * default browser (etc) settings in its canonical XML format.  Returns the default
-     * browser XML representation as a byte array, or null if there is none.
-     */
-    @Override
-    public byte[] getDefaultAppsBackup(int userId) {
-        return mPreferredActivityHelper.getDefaultAppsBackup(userId);
-    }
-
-    @Override
-    public void restoreDefaultApps(byte[] backup, int userId) {
-        mPreferredActivityHelper.restoreDefaultApps(backup, userId);
-    }
-
-    @Override
-    public byte[] getDomainVerificationBackup(int userId) {
-        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            throw new SecurityException("Only the system may call getDomainVerificationBackup()");
-        }
-
-        try {
-            try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
-                TypedXmlSerializer serializer = Xml.resolveSerializer(output);
-                mDomainVerificationManager.writeSettings(snapshotComputer(), serializer, true,
-                        userId);
-                return output.toByteArray();
-            }
-        } catch (Exception e) {
-            if (DEBUG_BACKUP) {
-                Slog.e(TAG, "Unable to write domain verification for backup", e);
-            }
-            return null;
-        }
-    }
-
-    @Override
-    public void restoreDomainVerification(byte[] backup, int userId) {
-        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            throw new SecurityException("Only the system may call restorePreferredActivities()");
-        }
-
-        try {
-            ByteArrayInputStream input = new ByteArrayInputStream(backup);
-            TypedXmlPullParser parser = Xml.resolvePullParser(input);
-
-            // User ID input isn't necessary here as it assumes the user integers match and that
-            // the only states inside the backup XML are for the target user.
-            mDomainVerificationManager.restoreSettings(snapshotComputer(), parser);
-            input.close();
-        } catch (Exception e) {
-            if (DEBUG_BACKUP) {
-                Slog.e(TAG, "Exception restoring domain verification: " + e.getMessage());
-            }
-        }
-    }
-
-    @Override
-    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
-            int sourceUserId, int targetUserId, int flags) {
-        addCrossProfileIntentFilter(new WatchedIntentFilter(intentFilter), ownerPackage,
-                                    sourceUserId, targetUserId, flags);
+        mPreferredActivityHelper.updateDefaultHomeNotLocked(snapshotComputer(), userId);
     }
 
     /**
      * Variant that takes a {@link WatchedIntentFilter}
      */
-    public void addCrossProfileIntentFilter(WatchedIntentFilter intentFilter, String ownerPackage,
-            int sourceUserId, int targetUserId, int flags) {
+    public void addCrossProfileIntentFilter(@NonNull Computer snapshot,
+            WatchedIntentFilter intentFilter, String ownerPackage, int sourceUserId,
+            int targetUserId, int flags) {
         mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
         int callingUid = Binder.getCallingUid();
-        enforceOwnerRights(ownerPackage, callingUid);
+        enforceOwnerRights(snapshot, ownerPackage, callingUid);
         PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
                 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
         if (intentFilter.countActions() == 0) {
@@ -5360,55 +3384,25 @@
         scheduleWritePackageRestrictions(sourceUserId);
     }
 
-    @Override
-    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
-        mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
-        final int callingUid = Binder.getCallingUid();
-        enforceOwnerRights(ownerPackage, callingUid);
-        PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
-                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
-        synchronized (mLock) {
-            CrossProfileIntentResolver resolver =
-                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
-            ArraySet<CrossProfileIntentFilter> set =
-                    new ArraySet<>(resolver.filterSet());
-            for (CrossProfileIntentFilter filter : set) {
-                if (filter.getOwnerPackage().equals(ownerPackage)) {
-                    resolver.removeFilter(filter);
-                }
-            }
-        }
-        scheduleWritePackageRestrictions(sourceUserId);
-    }
-
     // Enforcing that callingUid is owning pkg on userId
-    private void enforceOwnerRights(String pkg, int callingUid) {
+    private void enforceOwnerRights(@NonNull Computer snapshot, String pkg, int callingUid) {
         // The system owns everything.
         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
             return;
         }
-        final String[] callerPackageNames = getPackagesForUid(callingUid);
+        final String[] callerPackageNames = snapshot.getPackagesForUid(callingUid);
         if (!ArrayUtils.contains(callerPackageNames, pkg)) {
             throw new SecurityException("Calling uid " + callingUid
                     + " does not own package " + pkg);
         }
         final int callingUserId = UserHandle.getUserId(callingUid);
-        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
+        PackageInfo pi = snapshot.getPackageInfo(pkg, 0, callingUserId);
         if (pi == null) {
             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
                     + callingUserId);
         }
     }
 
-    @Override
-    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return null;
-        }
-        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
-    }
-
     public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
         UserManagerService ums = UserManagerService.getInstance();
         if (ums == null || sessionInfo.isStaged()) {
@@ -5416,34 +3410,13 @@
         }
         final UserInfo parent = ums.getProfileParent(userId);
         final int launcherUid = (parent != null) ? parent.id : userId;
-        final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
+        // TODO: Should this snapshot be moved further up?
+        final ComponentName launcherComponent = snapshotComputer()
+                .getDefaultHomeActivity(launcherUid);
         mBroadcastHelper.sendSessionCommitBroadcast(sessionInfo, userId, launcherUid,
                 launcherComponent, mAppPredictionServicePackage);
     }
 
-    /**
-     * Report the 'Home' activity which is currently set as "always use this one". If non is set
-     * then reports the most likely home activity or null if there are more than one.
-     */
-    private ComponentName getDefaultHomeActivity(int userId) {
-        return mComputer.getDefaultHomeActivity(userId);
-    }
-
-    Intent getHomeIntent() {
-        return mComputer.getHomeIntent();
-    }
-
-    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
-            int userId) {
-        return mComputer.getHomeActivitiesAsUser(allHomeCandidates,
-                userId);
-    }
-
-    @Override
-    public void setHomeActivity(ComponentName comp, int userId) {
-        mPreferredActivityHelper.setHomeActivity(comp, userId);
-    }
-
     private @Nullable String getSetupWizardPackageNameImpl(@NonNull Computer computer) {
         final Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
@@ -5477,10 +3450,11 @@
         }
     }
 
-    private @NonNull String getRequiredSdkSandboxPackageName() {
+    @NonNull
+    private static String getRequiredSdkSandboxPackageName(@NonNull Computer computer) {
         final Intent intent = new Intent(SdkSandboxManagerLocal.SERVICE_INTERFACE);
 
-        final List<ResolveInfo> matches = queryIntentServicesInternal(
+        final List<ResolveInfo> matches = computer.queryIntentServicesInternal(
                 intent,
                 /* resolvedType= */ null,
                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
@@ -5495,89 +3469,6 @@
         }
     }
 
-    @Override
-    public String getDefaultTextClassifierPackageName() {
-        return ensureSystemPackageName(
-                mContext.getString(R.string.config_servicesExtensionPackage));
-    }
-
-    @Override
-    public String getSystemTextClassifierPackageName() {
-        return ensureSystemPackageName(
-                mContext.getString(R.string.config_defaultTextClassifierPackage));
-    }
-
-    @Override
-    public @Nullable String getAttentionServicePackageName() {
-        return ensureSystemPackageName(
-                getPackageFromComponentString(R.string.config_defaultAttentionService));
-    }
-
-    @Override
-    public @Nullable String getRotationResolverPackageName() {
-        return ensureSystemPackageName(
-                getPackageFromComponentString(R.string.config_defaultRotationResolverService));
-    }
-
-    @Nullable
-    private String getDeviceConfiguratorPackageName() {
-        return ensureSystemPackageName(mContext.getString(
-                R.string.config_deviceConfiguratorPackageName));
-    }
-
-    @Override
-    public String getWellbeingPackageName() {
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            return CollectionUtils.firstOrNull(
-                    mContext.getSystemService(RoleManager.class).getRoleHolders(
-                            RoleManager.ROLE_SYSTEM_WELLBEING));
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @Override
-    public String getAppPredictionServicePackageName() {
-        return ensureSystemPackageName(
-                getPackageFromComponentString(R.string.config_defaultAppPredictionService));
-    }
-
-    @Override
-    public String getSystemCaptionsServicePackageName() {
-        return ensureSystemPackageName(
-                getPackageFromComponentString(R.string.config_defaultSystemCaptionsService));
-    }
-
-    @Override
-    public String getSetupWizardPackageName() {
-        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            throw new SecurityException("Non-system caller");
-        }
-        return mPmInternal.getSetupWizardPackageName();
-    }
-
-    public @Nullable String getAmbientContextDetectionPackageName() {
-        return ensureSystemPackageName(getPackageFromComponentString(
-                        R.string.config_defaultAmbientContextDetectionService));
-    }
-
-    public String getIncidentReportApproverPackageName() {
-        return ensureSystemPackageName(mContext.getString(
-                R.string.config_incidentReportApproverPackage));
-    }
-
-    @Override
-    public String getContentCaptureServicePackageName() {
-        return ensureSystemPackageName(
-                getPackageFromComponentString(R.string.config_defaultContentCaptureService));
-    }
-
-    public String getOverlayConfigSignaturePackageName() {
-        return ensureSystemPackageName(mInjector.getSystemConfig()
-                .getOverlayConfigSignaturePackage());
-    }
-
     @Nullable
     private String getRetailDemoPackageName() {
         final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage);
@@ -5614,14 +3505,7 @@
     }
 
     @Nullable
-    private String getRecentsPackageName() {
-        return ensureSystemPackageName(
-                getPackageFromComponentString(R.string.config_recentsComponentName));
-
-    }
-
-    @Nullable
-    private String getPackageFromComponentString(@StringRes int stringResId) {
+    String getPackageFromComponentString(@StringRes int stringResId) {
         final String componentString = mContext.getString(stringResId);
         if (TextUtils.isEmpty(componentString)) {
             return null;
@@ -5634,14 +3518,17 @@
     }
 
     @Nullable
-    private String ensureSystemPackageName(@Nullable String packageName) {
+    String ensureSystemPackageName(@NonNull Computer snapshot,
+            @Nullable String packageName) {
         if (packageName == null) {
             return null;
         }
         final long token = Binder.clearCallingIdentity();
         try {
-            if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
-                PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM);
+            if (snapshot.getPackageInfo(packageName, MATCH_FACTORY_ONLY,
+                    UserHandle.USER_SYSTEM) == null) {
+                PackageInfo packageInfo =
+                        snapshot.getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM);
                 if (packageInfo != null) {
                     EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid,
                             "");
@@ -5654,39 +3541,6 @@
         return packageName;
     }
 
-    @Override
-    public void setApplicationEnabledSetting(String appPackageName,
-            int newState, int flags, int userId, String callingPackage) {
-        if (!mUserManager.exists(userId)) return;
-        if (callingPackage == null) {
-            callingPackage = Integer.toString(Binder.getCallingUid());
-        }
-
-        setEnabledSettings(List.of(new ComponentEnabledSetting(appPackageName, newState, flags)),
-                userId, callingPackage);
-    }
-
-    @Override
-    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
-        commitPackageStateMutation(null, packageName, state ->
-                state.setUpdateAvailable(updateAvailable));
-    }
-
-    @Override
-    public void overrideLabelAndIcon(@NonNull ComponentName componentName,
-            @NonNull String nonLocalizedLabel, int icon, int userId) {
-        if (TextUtils.isEmpty(nonLocalizedLabel)) {
-            throw new IllegalArgumentException("Override label should be a valid String");
-        }
-        updateComponentLabelIcon(componentName, nonLocalizedLabel, icon, userId);
-    }
-
-    @Override
-    public void restoreLabelAndIcon(@NonNull ComponentName componentName, int userId) {
-        updateComponentLabelIcon(componentName, null, null, userId);
-    }
-
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     public void updateComponentLabelIcon(/*@NonNull*/ ComponentName componentName,
             @Nullable String nonLocalizedLabel, @Nullable Integer icon, int userId) {
@@ -5753,30 +3607,13 @@
         }
     }
 
-    @Override
-    public void setComponentEnabledSetting(ComponentName componentName,
-            int newState, int flags, int userId) {
-        if (!mUserManager.exists(userId)) return;
-
-        setEnabledSettings(List.of(new ComponentEnabledSetting(componentName, newState, flags)),
-                userId, null /* callingPackage */);
-    }
-
-    @Override
-    public void setComponentEnabledSettings(List<ComponentEnabledSetting> settings, int userId) {
-        if (!mUserManager.exists(userId)) return;
-        if (settings == null || settings.isEmpty()) {
-            throw new IllegalArgumentException("The list of enabled settings is empty");
-        }
-
-        setEnabledSettings(settings, userId, null /* callingPackage */);
-    }
-
     private void setEnabledSettings(List<ComponentEnabledSetting> settings, int userId,
             String callingPackage) {
         final int callingUid = Binder.getCallingUid();
-        enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
-                true /* checkShell */, "set enabled");
+        // TODO: This method is not properly snapshotified beyond this call
+        final Computer preLockSnapshot = snapshotComputer();
+        preLockSnapshot.enforceCrossUserPermission(callingUid, userId,
+                false /* requireFullPermission */, true /* checkShell */, "set enabled");
 
         final int targetSize = settings.size();
         for (int i = 0; i < targetSize; i++) {
@@ -5832,6 +3669,7 @@
         final Map<String, PackageSetting> pkgSettings = new ArrayMap<>(targetSize);
         // reader
         synchronized (mLock) {
+            final Computer snapshot = snapshotComputer();
             // Checks for target packages
             for (int i = 0; i < targetSize; i++) {
                 final ComponentEnabledSetting setting = settings.get(i);
@@ -5841,13 +3679,13 @@
                     continue;
                 }
                 final boolean isCallerTargetApp = ArrayUtils.contains(
-                        getPackagesForUid(callingUid), packageName);
+                        snapshot.getPackagesForUid(callingUid), packageName);
                 final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
                 // Limit who can change which apps
                 if (!isCallerTargetApp) {
                     // Don't allow apps that don't have permission to modify other apps
                     if (!allowedByPermission
-                            || shouldFilterApplication(pkgSetting, callingUid, userId)) {
+                            || snapshot.shouldFilterApplication(pkgSetting, callingUid, userId)) {
                         throw new SecurityException("Attempt to change component state; "
                                 + "pid=" + Binder.getCallingPid()
                                 + ", uid=" + callingUid
@@ -6020,12 +3858,13 @@
 
         final long callingId = Binder.clearCallingIdentity();
         try {
+            final Computer newSnapshot = snapshotComputer();
             for (int i = 0; i < sendNowBroadcasts.size(); i++) {
                 final String packageName = sendNowBroadcasts.keyAt(i);
                 final ArrayList<String> components = sendNowBroadcasts.valueAt(i);
                 final int packageUid = UserHandle.getUid(
                         userId, pkgSettings.get(packageName).getAppId());
-                sendPackageChangedBroadcast(packageName, false /* dontKillApp */,
+                sendPackageChangedBroadcast(newSnapshot, packageName, false /* dontKillApp */,
                         components, packageUid, null /* reason */);
             }
         } finally {
@@ -6055,7 +3894,7 @@
                 // if it ever does, we don't want to end up with some of the user's apps
                 // permanently suspended.
                 unsuspendForSuspendingPackage(computer, packageName, userId);
-                removeAllDistractingPackageRestrictions(userId);
+                removeAllDistractingPackageRestrictions(computer, userId);
             }
             success = true;
         } else {
@@ -6093,22 +3932,6 @@
         return true;
     }
 
-    @WorkerThread
-    @Override
-    public void flushPackageRestrictionsAsUser(int userId) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return;
-        }
-        if (!mUserManager.exists(userId)) {
-            return;
-        }
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
-                false /* checkShell */, "flushPackageRestrictions");
-        synchronized (mLock) {
-            flushPackageRestrictionsAsUserInternalLocked(userId);
-        }
-    }
-
     @GuardedBy("mLock")
     private void flushPackageRestrictionsAsUserInternalLocked(int userId) {
         // NOTE: this invokes synchronous disk access, so callers using this
@@ -6122,119 +3945,31 @@
         }
     }
 
-    void sendPackageChangedBroadcast(String packageName,
+    void sendPackageChangedBroadcast(@NonNull Computer snapshot, String packageName,
             boolean dontKillApp, ArrayList<String> componentNames, int packageUid, String reason) {
         final int userId = UserHandle.getUserId(packageUid);
-        final boolean isInstantApp = isInstantAppInternal(packageName, userId, Process.SYSTEM_UID);
+        final boolean isInstantApp =
+                snapshot.isInstantAppInternal(packageName, userId, Process.SYSTEM_UID);
         final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
         final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
-        final SparseArray<int[]> broadcastAllowList = getBroadcastAllowList(
+        final SparseArray<int[]> broadcastAllowList = snapshot.getBroadcastAllowList(
                 packageName, userIds, isInstantApp);
         mHandler.post(() -> mBroadcastHelper.sendPackageChangedBroadcast(
                 packageName, dontKillApp, componentNames, packageUid, reason, userIds,
                 instantUserIds, broadcastAllowList));
     }
 
-    @Nullable
-    private SparseArray<int[]> getBroadcastAllowList(@NonNull String packageName,
-            @UserIdInt int[] userIds, boolean isInstantApp) {
-        return mComputer.getBroadcastAllowList(packageName, userIds, isInstantApp);
-    }
-
-    @Override
-    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
-        if (!mUserManager.exists(userId)) return;
-        final int callingUid = Binder.getCallingUid();
-        final Computer computer = snapshotComputer();
-        if (computer.getInstantAppPackageName(callingUid) == null) {
-            final int permission = mContext.checkCallingOrSelfPermission(
-                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
-            final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
-            if (!allowedByPermission
-                    && !ArrayUtils.contains(computer.getPackagesForUid(callingUid), packageName)) {
-                throw new SecurityException(
-                        "Permission Denial: attempt to change stopped state from pid="
-                                + Binder.getCallingPid()
-                                + ", uid=" + callingUid + ", package=" + packageName);
-            }
-            computer.enforceCrossUserPermission(callingUid, userId,
-                    true /* requireFullPermission */, true /* checkShell */, "stop package");
-
-            final PackageStateInternal packageState = computer.getPackageStateInternal(packageName);
-            final PackageUserState packageUserState = packageState == null
-                    ? null : packageState.getUserStateOrDefault(userId);
-            if (packageState != null
-                    && !computer.shouldFilterApplication(packageState, callingUid, userId)
-                    && packageUserState.isStopped() != stopped) {
-                boolean wasNotLaunched = packageUserState.isNotLaunched();
-                commitPackageStateMutation(null, packageName, state -> {
-                    PackageUserStateWrite userState = state.userState(userId);
-                    userState.setStopped(stopped);
-                    if (wasNotLaunched) {
-                        userState.setNotLaunched(false);
-                    }
-                });
-
-                if (wasNotLaunched) {
-                    final String installerPackageName =
-                            packageState.getInstallSource().installerPackageName;
-                    if (installerPackageName != null) {
-                        notifyFirstLaunch(packageName, installerPackageName, userId);
-                    }
-                }
-
-                scheduleWritePackageRestrictions(userId);
-            }
+    /**
+     * Used by SystemServer
+     */
+    public void waitForAppDataPrepared() {
+        if (mPrepareAppDataFuture == null) {
+            return;
         }
-
-        // If this would cause the app to leave force-stop, then also make sure to unhibernate the
-        // app if needed.
-        if (!stopped) {
-            mHandler.post(() -> {
-                AppHibernationManagerInternal ah =
-                        mInjector.getLocalService(AppHibernationManagerInternal.class);
-                if (ah != null && ah.isHibernatingForUser(packageName, userId)) {
-                    ah.setHibernatingForUser(packageName, userId, false);
-                    ah.setHibernatingGlobally(packageName, false);
-                }
-            });
-        }
+        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
+        mPrepareAppDataFuture = null;
     }
 
-    @Nullable
-    @Override
-    public String getInstallerPackageName(@NonNull String packageName) {
-        return mComputer.getInstallerPackageName(packageName);
-    }
-
-    @Override
-    @Nullable
-    public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName) {
-        return mComputer.getInstallSourceInfo(packageName);
-    }
-
-    @PackageManager.EnabledState
-    @Override
-    public int getApplicationEnabledSetting(@NonNull String packageName, @UserIdInt int userId) {
-        return mComputer.getApplicationEnabledSetting(packageName, userId);
-    }
-
-    @Override
-    public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
-        return mComputer.getComponentEnabledSetting(component, Binder.getCallingUid(), userId);
-    }
-
-    @Override
-    public void enterSafeMode() {
-        PackageManagerServiceUtils.enforceSystemOrRoot(
-                "Only the system can request entering safe mode");
-
-        if (!mSystemReady) {
-            mSafeMode = true;
-        }
-    }
-
-    @Override
     public void systemReady() {
         PackageManagerServiceUtils.enforceSystemOrRoot(
                 "Only the system can claim the system is ready");
@@ -6265,7 +4000,7 @@
                         .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
                 false, co, UserHandle.USER_ALL);
         mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
-                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
+                .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
         co.onChange(true);
 
         mAppsFilter.onSystemReady();
@@ -6307,7 +4042,7 @@
 
         // Now that we're mostly running, clean up stale users and apps
         mUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
-        storageEventHelper.reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
+        storageEventHelper.reconcileApps(snapshotComputer(), StorageManager.UUID_PRIVATE_INTERNAL);
 
         mPermissionManager.onSystemReady();
 
@@ -6319,7 +4054,7 @@
         final int livingUserCount = livingUsers.size();
         for (int i = 0; i < livingUserCount; i++) {
             final int userId = livingUsers.get(i).id;
-            if (mPmInternal.isPermissionUpgradeNeeded(userId)) {
+            if (mSettings.isPermissionUpgradeNeeded(userId)) {
                 grantPermissionsUserIds = ArrayUtils.appendInt(
                         grantPermissionsUserIds, userId);
             }
@@ -6361,11 +4096,12 @@
                 if (packageName == null) {
                     return;
                 }
-                AndroidPackage pkg = mPackages.get(packageName);
+                final Computer snapshot = snapshotComputer();
+                AndroidPackage pkg = snapshot.getPackage(packageName);
                 if (pkg == null) {
                     return;
                 }
-                sendPackageChangedBroadcast(pkg.getPackageName(),
+                sendPackageChangedBroadcast(snapshot, pkg.getPackageName(),
                         true /* dontKillApp */,
                         new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
                         pkg.getUid(),
@@ -6397,44 +4133,11 @@
 
         // Prune unused static shared libraries which have been cached a period of time
         schedulePruneUnusedStaticSharedLibraries(false /* delay */);
-    }
 
-    /**
-     * Used by SystemServer
-     */
-    public void waitForAppDataPrepared() {
-        if (mPrepareAppDataFuture == null) {
-            return;
+        // TODO(b/222706900): Remove this intent interceptor before T launch
+        if (mIntentResolverInterceptor != null) {
+            mIntentResolverInterceptor.registerListeners();
         }
-        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
-        mPrepareAppDataFuture = null;
-    }
-
-    @Override
-    public boolean isSafeMode() {
-        // allow instant applications
-        return mSafeMode;
-    }
-
-    @Override
-    public boolean hasSystemUidErrors() {
-        // allow instant applications
-        return false;
-    }
-
-    @Override
-    public void onShellCommand(FileDescriptor in, FileDescriptor out,
-            FileDescriptor err, String[] args, ShellCallback callback,
-            ResultReceiver resultReceiver) {
-        (new PackageManagerShellCommand(this, mContext,mDomainVerificationManager.getShell()))
-                .exec(this, in, out, err, args, callback, resultReceiver);
-    }
-
-    @SuppressWarnings("resource")
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
-        new DumpHelper(this).doDump(fd, pw, args);
     }
 
     void dumpSnapshotStats(PrintWriter pw, boolean isBrief) {
@@ -6451,14 +4154,6 @@
         mSnapshotStatistics.dump(pw, "  ", now, hits, -1, isBrief);
     }
 
-    /**
-     * Dump package manager states to the file according to a given dumping type of
-     * {@link DumpState}.
-     */
-    void dumpComputer(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
-        mComputer.dump(type, fd, pw, dumpState);
-    }
-
     //TODO: b/111402650
     private void disableSkuSpecificApps() {
         String[] apkList = mContext.getResources().getStringArray(
@@ -6472,10 +4167,11 @@
         if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) {
             return;
         }
+        final Computer snapshot = snapshotComputer();
         for (String packageName : apkList) {
-            setSystemAppHiddenUntilInstalled(packageName, true);
+            setSystemAppHiddenUntilInstalled(snapshot, packageName, true);
             for (UserInfo user : mInjector.getUserManagerInternal().getUsers(false)) {
-                setSystemAppInstallState(packageName, false, user.id);
+                setSystemAppInstallState(snapshot, packageName, false, user.id);
             }
         }
     }
@@ -6513,98 +4209,6 @@
         }
     }
 
-    @Override
-    public int movePackage(final String packageName, final String volumeUuid) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
-
-        final int callingUid = Binder.getCallingUid();
-        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
-        final int moveId = mNextMoveId.getAndIncrement();
-        mHandler.post(() -> {
-            try {
-                MovePackageHelper movePackageHelper = new MovePackageHelper(this);
-                movePackageHelper.movePackageInternal(
-                        packageName, volumeUuid, moveId, callingUid, user);
-            } catch (PackageManagerException e) {
-                Slog.w(TAG, "Failed to move " + packageName, e);
-                mMoveCallbacks.notifyStatusChanged(moveId, e.error);
-            }
-        });
-        return moveId;
-    }
-
-    @Override
-    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
-
-        final int realMoveId = mNextMoveId.getAndIncrement();
-        final Bundle extras = new Bundle();
-        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
-        mMoveCallbacks.notifyCreated(realMoveId, extras);
-
-        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
-            @Override
-            public void onCreated(int moveId, Bundle extras) {
-                // Ignored
-            }
-
-            @Override
-            public void onStatusChanged(int moveId, int status, long estMillis) {
-                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
-            }
-        };
-
-        final StorageManager storage = mInjector.getSystemService(StorageManager.class);
-        storage.setPrimaryStorageUuid(volumeUuid, callback);
-        return realMoveId;
-    }
-
-    @Override
-    public int getMoveStatus(int moveId) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
-        return mMoveCallbacks.mLastStatus.get(moveId);
-    }
-
-    @Override
-    public void registerMoveCallback(IPackageMoveObserver callback) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
-        mMoveCallbacks.register(callback);
-    }
-
-    @Override
-    public void unregisterMoveCallback(IPackageMoveObserver callback) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
-        mMoveCallbacks.unregister(callback);
-    }
-
-    @Override
-    public boolean setInstallLocation(int loc) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
-                null);
-        if (getInstallLocation() == loc) {
-            return true;
-        }
-        if (loc == InstallLocationUtils.APP_INSTALL_AUTO
-                || loc == InstallLocationUtils.APP_INSTALL_INTERNAL
-                || loc == InstallLocationUtils.APP_INSTALL_EXTERNAL) {
-            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
-                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
-            return true;
-        }
-        return false;
-   }
-
-    @Override
-    public int getInstallLocation() {
-        // allow instant app access
-        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
-                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
-                InstallLocationUtils.APP_INSTALL_AUTO);
-    }
-
     /** Called by UserManagerService */
     void cleanUpUser(UserManagerService userManager, @UserIdInt int userId) {
         synchronized (mLock) {
@@ -6660,22 +4264,10 @@
             mPermissionManager.writeLegacyPermissionStateTEMP();
             mSettings.readPermissionStateForUserSyncLPr(userId);
             mPermissionManager.readLegacyPermissionStateTEMP();
-            return mPmInternal.isPermissionUpgradeNeeded(userId);
+            return mSettings.isPermissionUpgradeNeeded(userId);
         }
     }
 
-    @Override
-    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
-                "Only package verification agents can read the verifier device identity");
-
-        synchronized (mLock) {
-            return mSettings.getVerifierDeviceIdentityLPw(mLiveComputer);
-        }
-    }
-
-    @Override
     public boolean isStorageLow() {
         // allow instant applications
         final long token = Binder.clearCallingIdentity();
@@ -6692,52 +4284,8 @@
         }
     }
 
-    @Override
-    public IPackageInstaller getPackageInstaller() {
-        // Return installer service for internal calls.
-        if (PackageManagerServiceUtils.isSystemOrRoot()) {
-            return mInstallerService;
-        }
-        // Return null for InstantApps.
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return null;
-        }
-        return mInstallerService;
-    }
-
-    @Override
-    public IArtManager getArtManager() {
-        return mArtManagerService;
-    }
-
-    boolean userNeedsBadging(int userId) {
-        return mUserNeedsBadging.get(userId);
-    }
-
-    @Nullable
-    @Override
-    public KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias) {
-        return mComputer.getKeySetByAlias(packageName, alias);
-    }
-
-    @Nullable
-    @Override
-    public KeySet getSigningKeySet(@NonNull String packageName) {
-        return mComputer.getSigningKeySet(packageName);
-    }
-
-    @Override
-    public boolean isPackageSignedByKeySet(@NonNull String packageName, @NonNull KeySet ks) {
-        return mComputer.isPackageSignedByKeySet(packageName, ks);
-    }
-
-    @Override
-    public boolean isPackageSignedByKeySetExactly(@NonNull String packageName, @NonNull KeySet ks) {
-        return mComputer.isPackageSignedByKeySetExactly(packageName, ks);
-    }
-
-    private void deletePackageIfUnused(final String packageName) {
-        PackageStateInternal ps = getPackageStateInternal(packageName);
+    private void deletePackageIfUnused(@NonNull Computer snapshot, final String packageName) {
+        PackageStateInternal ps = snapshot.getPackageStateInternal(packageName);
         if (ps == null) {
             return;
         }
@@ -6755,57 +4303,1812 @@
                 0, PackageManager.DELETE_ALL_USERS, true /*removedBySystem*/));
     }
 
-    private AndroidPackage getPackage(String packageName) {
-        return mComputer.getPackage(packageName);
+    void deletePreloadsFileCache() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE,
+                "deletePreloadsFileCache");
+        File dir = Environment.getDataPreloadsFileCacheDirectory();
+        Slog.i(PackageManagerService.TAG, "Deleting preloaded file cache " + dir);
+        FileUtils.deleteContents(dir);
     }
 
-    private AndroidPackage getPackage(int uid) {
-        return mComputer.getPackage(uid);
+    void setSystemAppHiddenUntilInstalled(@NonNull Computer snapshot, String packageName,
+            boolean hidden) {
+        final int callingUid = Binder.getCallingUid();
+        final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
+                || callingUid == Process.SYSTEM_UID;
+        if (!calledFromSystemOrPhone) {
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
+                    "setSystemAppHiddenUntilInstalled");
+        }
+
+        final PackageStateInternal stateRead = snapshot.getPackageStateInternal(packageName);
+        if (stateRead == null || !stateRead.isSystem() || stateRead.getPkg() == null) {
+            return;
+        }
+        if (stateRead.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
+            throw new SecurityException("Only system or phone callers can modify core apps");
+        }
+
+        commitPackageStateMutation(null, mutator -> {
+            mutator.forPackage(packageName)
+                    .setHiddenUntilInstalled(hidden);
+            mutator.forDisabledSystemPackage(packageName)
+                    .setHiddenUntilInstalled(hidden);
+        });
     }
 
-    private SigningDetails getSigningDetails(@NonNull String packageName) {
-        return mComputer.getSigningDetails(packageName);
+    boolean setSystemAppInstallState(@NonNull Computer snapshot, String packageName,
+            boolean installed, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
+                || callingUid == Process.SYSTEM_UID;
+        if (!calledFromSystemOrPhone) {
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
+                    "setSystemAppHiddenUntilInstalled");
+        }
+
+        final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
+        // The target app should always be in system
+        if (packageState == null || !packageState.isSystem() || packageState.getPkg() == null) {
+            return false;
+        }
+        if (packageState.getPkg().isCoreApp() && !calledFromSystemOrPhone) {
+            throw new SecurityException("Only system or phone callers can modify core apps");
+        }
+        // Check if the install state is the same
+        if (packageState.getUserStateOrDefault(userId).isInstalled() == installed) {
+            return false;
+        }
+
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            if (installed) {
+                // install the app from uninstalled state
+                mInstallPackageHelper.installExistingPackageAsUser(
+                        packageName,
+                        userId,
+                        PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+                        PackageManager.INSTALL_REASON_DEVICE_SETUP,
+                        null,
+                        null);
+                return true;
+            }
+
+            // uninstall the app from installed state
+            deletePackageVersioned(
+                    new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
+                    new PackageManager.LegacyPackageDeleteObserver(null).getBinder(),
+                    userId,
+                    PackageManager.DELETE_SYSTEM_APP);
+            return true;
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
     }
 
-    private SigningDetails getSigningDetails(int uid) {
-        return mComputer.getSigningDetails(uid);
+    void finishPackageInstall(int token, boolean didLaunch) {
+        PackageManagerServiceUtils.enforceSystemOrRoot(
+                "Only the system is allowed to finish installs");
+
+        if (PackageManagerService.DEBUG_INSTALL) {
+            Slog.v(PackageManagerService.TAG, "BM finishing package install for " + token);
+        }
+        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
+
+        final Message msg = mHandler.obtainMessage(PackageManagerService.POST_INSTALL, token,
+                didLaunch ? 1 : 0);
+        mHandler.sendMessage(msg);
     }
 
-    private boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
-        return mComputer.filterAppAccess(pkg, callingUid, userId);
+    void checkPackageStartable(@NonNull Computer snapshot, @NonNull String packageName,
+            @UserIdInt int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (snapshot.getInstantAppPackageName(callingUid) != null) {
+            throw new SecurityException("Instant applications don't have access to this method");
+        }
+        if (!mUserManager.exists(userId)) {
+            throw new SecurityException("User doesn't exist");
+        }
+        snapshot.enforceCrossUserPermission(callingUid, userId, false, false,
+                "checkPackageStartable");
+        switch (snapshot.getPackageStartability(mSafeMode, packageName, callingUid, userId)) {
+            case PACKAGE_STARTABILITY_NOT_FOUND:
+                throw new SecurityException("Package " + packageName + " was not found!");
+            case PACKAGE_STARTABILITY_NOT_SYSTEM:
+                throw new SecurityException("Package " + packageName + " not a system app!");
+            case PACKAGE_STARTABILITY_FROZEN:
+                throw new SecurityException("Package " + packageName + " is currently frozen!");
+            case PACKAGE_STARTABILITY_DIRECT_BOOT_UNSUPPORTED:
+                throw new SecurityException("Package " + packageName + " is not encryption aware!");
+            case PACKAGE_STARTABILITY_OK:
+            default:
+        }
     }
 
-    private boolean filterAppAccess(String packageName, int callingUid, int userId) {
-        return mComputer.filterAppAccess(packageName, callingUid, userId);
+    void setPackageStoppedState(@NonNull Computer snapshot, @NonNull String packageName,
+            boolean stopped, @UserIdInt int userId) {
+        if (!mUserManager.exists(userId)) return;
+        final int callingUid = Binder.getCallingUid();
+        if (snapshot.getInstantAppPackageName(callingUid) == null) {
+            final int permission = mContext.checkCallingOrSelfPermission(
+                    Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
+            final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
+            if (!allowedByPermission
+                    && !ArrayUtils.contains(snapshot.getPackagesForUid(callingUid), packageName)) {
+                throw new SecurityException(
+                        "Permission Denial: attempt to change stopped state from pid="
+                                + Binder.getCallingPid()
+                                + ", uid=" + callingUid + ", package=" + packageName);
+            }
+            snapshot.enforceCrossUserPermission(callingUid, userId,
+                    true /* requireFullPermission */, true /* checkShell */, "stop package");
+
+            final PackageStateInternal packageState =
+                    snapshot.getPackageStateInternal(packageName);
+            final PackageUserState packageUserState = packageState == null
+                    ? null : packageState.getUserStateOrDefault(userId);
+            if (packageState != null
+                    && !snapshot.shouldFilterApplication(packageState, callingUid, userId)
+                    && packageUserState.isStopped() != stopped) {
+                boolean wasNotLaunched = packageUserState.isNotLaunched();
+                commitPackageStateMutation(null, packageName, state -> {
+                    PackageUserStateWrite userState = state.userState(userId);
+                    userState.setStopped(stopped);
+                    if (wasNotLaunched) {
+                        userState.setNotLaunched(false);
+                    }
+                });
+
+                if (wasNotLaunched) {
+                    final String installerPackageName =
+                            packageState.getInstallSource().installerPackageName;
+                    if (installerPackageName != null) {
+                        notifyFirstLaunch(packageName, installerPackageName, userId);
+                    }
+                }
+
+                scheduleWritePackageRestrictions(userId);
+            }
+        }
+
+        // If this would cause the app to leave force-stop, then also make sure to unhibernate the
+        // app if needed.
+        if (!stopped) {
+            mHandler.post(() -> {
+                AppHibernationManagerInternal ah =
+                        mInjector.getLocalService(AppHibernationManagerInternal.class);
+                if (ah != null && ah.isHibernatingForUser(packageName, userId)) {
+                    ah.setHibernatingForUser(packageName, userId, false);
+                    ah.setHibernatingGlobally(packageName, false);
+                }
+            });
+        }
     }
 
-    private boolean filterAppAccess(int uid, int callingUid) {
-        return mComputer.filterAppAccess(uid, callingUid);
-    }
+    public class IPackageManagerImpl extends IPackageManagerBase {
 
-    @Nullable
-    private int[] getVisibilityAllowList(@NonNull String packageName, @UserIdInt int userId) {
-        return mComputer.getVisibilityAllowList(packageName, userId);
-    }
+        public IPackageManagerImpl() {
+            super(PackageManagerService.this, mContext, mDexOptHelper, mModuleInfoProvider,
+                    mPreferredActivityHelper, mResolveIntentHelper, mDomainVerificationManager,
+                    mDomainVerificationConnection, mInstallerService, mPackageProperty,
+                    mResolveComponentName, mInstantAppResolverSettingsComponent,
+                    mRequiredSdkSandboxPackage, mServicesExtensionPackageName,
+                    mSharedSystemSharedLibraryPackageName);
+        }
 
-    boolean canQueryPackage(int callingUid, @Nullable String targetPackageName) {
-        return mComputer.canQueryPackage(callingUid, targetPackageName);
+        @Override
+        public void checkPackageStartable(String packageName, int userId) {
+            PackageManagerService.this
+                    .checkPackageStartable(snapshotComputer(), packageName, userId);
+        }
+
+        @Override
+        public void clearApplicationProfileData(String packageName) {
+            PackageManagerServiceUtils.enforceSystemOrRoot(
+                    "Only the system can clear all profile data");
+
+            final Computer snapshot = snapshotComputer();
+            final AndroidPackage pkg = snapshot.getPackage(packageName);
+            try (PackageFreezer ignored = freezePackage(packageName, "clearApplicationProfileData")) {
+                synchronized (mInstallLock) {
+                    mAppDataHelper.clearAppProfilesLIF(pkg);
+                }
+            }
+        }
+
+        @Override
+        public void clearApplicationUserData(final String packageName,
+                final IPackageDataObserver observer, final int userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.CLEAR_APP_USER_DATA, null);
+
+            final int callingUid = Binder.getCallingUid();
+            final Computer snapshot = snapshotComputer();
+            snapshot.enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
+                    false /* checkShell */, "clear application data");
+
+            if (snapshot.getPackageStateFiltered(packageName, callingUid, userId) == null) {
+                if (observer != null) {
+                    mHandler.post(() -> {
+                        try {
+                            observer.onRemoveCompleted(packageName, false);
+                        } catch (RemoteException e) {
+                            Log.i(TAG, "Observer no longer exists.");
+                        }
+                    });
+                }
+                return;
+            }
+            if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
+                throw new SecurityException("Cannot clear data for a protected package: "
+                        + packageName);
+            }
+
+            // Queue up an async operation since the package deletion may take a little while.
+            mHandler.post(new Runnable() {
+                public void run() {
+                    mHandler.removeCallbacks(this);
+                    final boolean succeeded;
+                    try (PackageFreezer freezer = freezePackage(packageName,
+                            "clearApplicationUserData")) {
+                        synchronized (mInstallLock) {
+                            succeeded = clearApplicationUserDataLIF(snapshotComputer(), packageName,
+                                    userId);
+                        }
+                        mInstantAppRegistry.deleteInstantApplicationMetadata(packageName, userId);
+                        synchronized (mLock) {
+                            if (succeeded) {
+                                resetComponentEnabledSettingsIfNeededLPw(packageName, userId);
+                            }
+                        }
+                    }
+                    if (succeeded) {
+                        // invoke DeviceStorageMonitor's update method to clear any notifications
+                        DeviceStorageMonitorInternal dsm = LocalServices
+                                .getService(DeviceStorageMonitorInternal.class);
+                        if (dsm != null) {
+                            dsm.checkMemory();
+                        }
+                        if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
+                                == PERMISSION_GRANTED) {
+                            final Computer snapshot = snapshotComputer();
+                            unsuspendForSuspendingPackage(snapshot, packageName, userId);
+                            removeAllDistractingPackageRestrictions(snapshot, userId);
+                            flushPackageRestrictionsAsUserInternalLocked(userId);
+                        }
+                    }
+                    if (observer != null) {
+                        try {
+                            observer.onRemoveCompleted(packageName, succeeded);
+                        } catch (RemoteException e) {
+                            Log.i(TAG, "Observer no longer exists.");
+                        }
+                    } //end if observer
+                } //end run
+            });
+        }
+
+        @Override
+        public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+            final int callingUid = Binder.getCallingUid();
+            final Computer snapshot = snapshotComputer();
+            enforceOwnerRights(snapshot, ownerPackage, callingUid);
+            PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
+                    UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
+            synchronized (mLock) {
+                CrossProfileIntentResolver resolver =
+                        mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
+                ArraySet<CrossProfileIntentFilter> set =
+                        new ArraySet<>(resolver.filterSet());
+                for (CrossProfileIntentFilter filter : set) {
+                    if (filter.getOwnerPackage().equals(ownerPackage)) {
+                        resolver.removeFilter(filter);
+                    }
+                }
+            }
+            scheduleWritePackageRestrictions(sourceUserId);
+        }
+
+        @Override
+        public final void deleteApplicationCacheFiles(final String packageName,
+                final IPackageDataObserver observer) {
+            final int userId = UserHandle.getCallingUserId();
+            deleteApplicationCacheFilesAsUser(packageName, userId, observer);
+        }
+
+        @Override
+        public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
+                final IPackageDataObserver observer) {
+            final int callingUid = Binder.getCallingUid();
+            if (mContext.checkCallingOrSelfPermission(
+                    android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
+                    != PackageManager.PERMISSION_GRANTED) {
+                // If the caller has the old delete cache permission, silently ignore.  Else throw.
+                if (mContext.checkCallingOrSelfPermission(
+                        android.Manifest.permission.DELETE_CACHE_FILES)
+                        == PackageManager.PERMISSION_GRANTED) {
+                    Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
+                            android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
+                            ", silently ignoring");
+                    return;
+                }
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
+            }
+            final Computer snapshot = snapshotComputer();
+            snapshot.enforceCrossUserPermission(callingUid, userId, /* requireFullPermission= */ true,
+                    /* checkShell= */ false, "delete application cache files");
+            final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
+                    android.Manifest.permission.ACCESS_INSTANT_APPS);
+
+            // Queue up an async operation since the package deletion may take a little while.
+            mHandler.post(() -> {
+                // Snapshot in the Handler Runnable since this may be deferred quite a bit
+                // TODO: Is this and the later mInstallLock re-snapshot necessary?
+                final Computer newSnapshot = snapshotComputer();
+                final PackageStateInternal ps = newSnapshot.getPackageStateInternal(packageName);
+                boolean doClearData = true;
+                if (ps != null) {
+                    final boolean targetIsInstantApp =
+                            ps.getUserStateOrDefault(UserHandle.getUserId(callingUid)).isInstantApp();
+                    doClearData = !targetIsInstantApp
+                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
+                }
+                if (doClearData) {
+                    synchronized (mInstallLock) {
+                        final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
+                        // Snapshot again after mInstallLock?
+                        final AndroidPackage pkg = snapshotComputer().getPackage(packageName);
+                        // We're only clearing cache files, so we don't care if the
+                        // app is unfrozen and still able to run
+                        mAppDataHelper.clearAppDataLIF(pkg, userId,
+                                flags | Installer.FLAG_CLEAR_CACHE_ONLY);
+                        mAppDataHelper.clearAppDataLIF(pkg, userId,
+                                flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+                    }
+                }
+                if (observer != null) {
+                    try {
+                        observer.onRemoveCompleted(packageName, true);
+                    } catch (RemoteException e) {
+                        Log.i(TAG, "Observer no longer exists.");
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void dumpProfiles(String packageName) {
+            /* Only the shell, root, or the app user should be able to dump profiles. */
+            final int callingUid = Binder.getCallingUid();
+            final Computer snapshot = snapshotComputer();
+            final String[] callerPackageNames = snapshot.getPackagesForUid(callingUid);
+            if (callingUid != Process.SHELL_UID
+                    && callingUid != Process.ROOT_UID
+                    && !ArrayUtils.contains(callerPackageNames, packageName)) {
+                throw new SecurityException("dumpProfiles");
+            }
+
+            AndroidPackage pkg = snapshot.getPackage(packageName);
+            if (pkg == null) {
+                throw new IllegalArgumentException("Unknown package: " + packageName);
+            }
+
+            synchronized (mInstallLock) {
+                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
+                mArtManagerService.dumpProfiles(pkg);
+                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+            }
+        }
+
+        @Override
+        public void enterSafeMode() {
+            PackageManagerServiceUtils.enforceSystemOrRoot(
+                    "Only the system can request entering safe mode");
+
+            if (!mSystemReady) {
+                mSafeMode = true;
+            }
+        }
+
+        @Override
+        public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
+                long millisecondsToDelay) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.PACKAGE_VERIFICATION_AGENT,
+                    "Only package verification agents can extend verification timeouts");
+            final int callingUid = Binder.getCallingUid();
+
+            mHandler.post(() -> {
+                final PackageVerificationState state = mPendingVerification.get(id);
+                final PackageVerificationResponse response = new PackageVerificationResponse(
+                        verificationCodeAtTimeout, callingUid);
+
+                long delay = millisecondsToDelay;
+                if (delay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
+                    delay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
+                }
+                if (delay < 0) {
+                    delay = 0;
+                }
+
+                if ((state != null) && !state.timeoutExtended()) {
+                    state.extendTimeout();
+
+                    final Message msg = mHandler.obtainMessage(PackageManagerService.PACKAGE_VERIFIED);
+                    msg.arg1 = id;
+                    msg.obj = response;
+                    mHandler.sendMessageDelayed(msg, delay);
+                }
+            });
+        }
+
+        @WorkerThread
+        @Override
+        public void flushPackageRestrictionsAsUser(int userId) {
+            final Computer snapshot = snapshotComputer();
+            final int callingUid = Binder.getCallingUid();
+            if (snapshot.getInstantAppPackageName(callingUid) != null) {
+                return;
+            }
+            if (!mUserManager.exists(userId)) {
+                return;
+            }
+            snapshot.enforceCrossUserPermission(callingUid, userId,
+                    false /* requireFullPermission*/, false /* checkShell */,
+                    "flushPackageRestrictions");
+            synchronized (mLock) {
+                flushPackageRestrictionsAsUserInternalLocked(userId);
+            }
+        }
+
+
+        @Override
+        public void freeStorage(final String volumeUuid, final long freeStorageSize,
+                final @StorageManager.AllocateFlags int flags, final IntentSender pi) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.CLEAR_APP_CACHE, TAG);
+            mHandler.post(() -> {
+                boolean success = false;
+                try {
+                    PackageManagerService.this.freeStorage(volumeUuid, freeStorageSize, flags);
+                    success = true;
+                } catch (IOException e) {
+                    Slog.w(TAG, e);
+                }
+                if (pi != null) {
+                    try {
+                        pi.sendIntent(null, success ? 1 : 0, null, null, null);
+                    } catch (SendIntentException e) {
+                        Slog.w(TAG, e);
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
+                final @StorageManager.AllocateFlags int flags, final IPackageDataObserver observer) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.CLEAR_APP_CACHE, null);
+            mHandler.post(() -> {
+                boolean success = false;
+                try {
+                    PackageManagerService.this.freeStorage(volumeUuid, freeStorageSize, flags);
+                    success = true;
+                } catch (IOException e) {
+                    Slog.w(PackageManagerService.TAG, e);
+                }
+                if (observer != null) {
+                    try {
+                        observer.onRemoveCompleted(null, success);
+                    } catch (RemoteException e) {
+                        Slog.w(PackageManagerService.TAG, e);
+                    }
+                }
+            });
+        }
+
+        @Override
+        public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            final Computer snapshot = snapshotComputer();
+            if (snapshot.getInstantAppPackageName(callingUid) != null) {
+                return null;
+            }
+            if (!mUserManager.exists(userId)) {
+                return null;
+            }
+            snapshot.enforceCrossUserPermission(callingUid, userId, false, false,
+                    "getChangedPackages");
+            final ChangedPackages changedPackages = mChangedPackagesTracker.getChangedPackages(
+                    sequenceNumber, userId);
+
+            if (changedPackages != null) {
+                final List<String> packageNames = changedPackages.getPackageNames();
+                for (int index = packageNames.size() - 1; index >= 0; index--) {
+                    // Filter out the changes if the calling package should not be able to see it.
+                    final PackageStateInternal packageState =
+                            snapshot.getPackageStateInternal(packageNames.get(index));
+                    if (snapshot.shouldFilterApplication(packageState, callingUid, userId)) {
+                        packageNames.remove(index);
+                    }
+                }
+            }
+
+            return changedPackages;
+        }
+
+        @Override
+        public byte[] getDomainVerificationBackup(int userId) {
+            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+                throw new SecurityException("Only the system may call getDomainVerificationBackup()");
+            }
+
+            try {
+                try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
+                    TypedXmlSerializer serializer = Xml.resolveSerializer(output);
+                    mDomainVerificationManager.writeSettings(snapshotComputer(), serializer, true,
+                            userId);
+                    return output.toByteArray();
+                }
+            } catch (Exception e) {
+                if (PackageManagerService.DEBUG_BACKUP) {
+                    Slog.e(PackageManagerService.TAG, "Unable to write domain verification for backup", e);
+                }
+                return null;
+            }
+        }
+
+        @Override
+        public IBinder getHoldLockToken() {
+            if (!Build.IS_DEBUGGABLE) {
+                throw new SecurityException("getHoldLockToken requires a debuggable build");
+            }
+
+            mContext.enforceCallingPermission(
+                    Manifest.permission.INJECT_EVENTS,
+                    "getHoldLockToken requires INJECT_EVENTS permission");
+
+            final Binder token = new Binder();
+            token.attachInterface(this, "holdLock:" + Binder.getCallingUid());
+            return token;
+        }
+
+        @Override
+        public String getInstantAppAndroidId(String packageName, int userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.ACCESS_INSTANT_APPS, "getInstantAppAndroidId");
+            final Computer snapshot = snapshotComputer();
+            snapshot.enforceCrossUserPermission(Binder.getCallingUid(), userId,
+                    true /* requireFullPermission */, false /* checkShell */,
+                    "getInstantAppAndroidId");
+            // Make sure the target is an Instant App.
+            if (!snapshot.isInstantApp(packageName, userId)) {
+                return null;
+            }
+            return mInstantAppRegistry.getInstantAppAndroidId(packageName, userId);
+        }
+
+        @Override
+        public byte[] getInstantAppCookie(String packageName, int userId) {
+            if (HIDE_EPHEMERAL_APIS) {
+                return null;
+            }
+
+            final Computer snapshot = snapshotComputer();
+            snapshot.enforceCrossUserPermission(Binder.getCallingUid(), userId,
+                    true /* requireFullPermission */, false /* checkShell */,
+                    "getInstantAppCookie");
+            if (!snapshot.isCallerSameApp(packageName, Binder.getCallingUid())) {
+                return null;
+            }
+            PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
+            if (packageState == null || packageState.getPkg() == null) {
+                return null;
+            }
+            return mInstantAppRegistry.getInstantAppCookie(packageState.getPkg(), userId);
+        }
+
+        @Override
+        public Bitmap getInstantAppIcon(String packageName, int userId) {
+            if (HIDE_EPHEMERAL_APIS) {
+                return null;
+            }
+
+            final Computer snapshot = snapshotComputer();
+            if (!snapshot.canViewInstantApps(Binder.getCallingUid(), userId)) {
+                mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
+                        "getInstantAppIcon");
+            }
+            snapshot.enforceCrossUserPermission(Binder.getCallingUid(), userId,
+                    true /* requireFullPermission */, false /* checkShell */,
+                    "getInstantAppIcon");
+
+            return mInstantAppRegistry.getInstantAppIcon(packageName, userId);
+        }
+
+        @Override
+        public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
+            if (HIDE_EPHEMERAL_APIS) {
+                return null;
+            }
+
+            final Computer snapshot = snapshotComputer();
+            if (!snapshot.canViewInstantApps(Binder.getCallingUid(), userId)) {
+                mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
+                        "getEphemeralApplications");
+            }
+            snapshot.enforceCrossUserPermission(Binder.getCallingUid(), userId,
+                    true /* requireFullPermission */, false /* checkShell */,
+                    "getEphemeralApplications");
+
+            List<InstantAppInfo> instantApps = mInstantAppRegistry.getInstantApps(snapshot, userId);
+            if (instantApps != null) {
+                return new ParceledListSlice<>(instantApps);
+            }
+            return null;
+        }
+
+        @Override
+        public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
+            return mPreferredActivityHelper.getLastChosenActivity(snapshotComputer(), intent,
+                    resolvedType, flags);
+        }
+
+        @Override
+        public IntentSender getLaunchIntentSenderForPackage(String packageName, String callingPackage,
+                String featureId, int userId) throws RemoteException {
+            return mResolveIntentHelper.getLaunchIntentSenderForPackage(snapshotComputer(),
+                    packageName, callingPackage, featureId, userId);
+        }
+
+        @Override
+        public List<String> getMimeGroup(String packageName, String mimeGroup) {
+            final Computer snapshot = snapshotComputer();
+            enforceOwnerRights(snapshot, packageName, Binder.getCallingUid());
+            return getMimeGroupInternal(snapshot, packageName, mimeGroup);
+        }
+
+        @Override
+        public int getMoveStatus(int moveId) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+            return mMoveCallbacks.mLastStatus.get(moveId);
+        }
+
+        @Override
+        public String getPermissionControllerPackageName() {
+            final int callingUid = Binder.getCallingUid();
+            final Computer snapshot = snapshotComputer();
+            if (snapshot.getPackageStateFiltered(mRequiredPermissionControllerPackage,
+                    callingUid, UserHandle.getUserId(callingUid)) != null) {
+                return mRequiredPermissionControllerPackage;
+            }
+
+            throw new IllegalStateException("PermissionController is not found");
+        }
+
+        @Override
+        public int getRuntimePermissionsVersion(@UserIdInt int userId) {
+            Preconditions.checkArgumentNonnegative(userId);
+            enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
+                    "getRuntimePermissionVersion");
+            return mSettings.getDefaultRuntimePermissionsVersion(userId);
+        }
+
+        @Override
+        public String getSplashScreenTheme(@NonNull String packageName, int userId) {
+            final Computer snapshot = snapshotComputer();
+            PackageStateInternal packageState = filterPackageStateForInstalledAndFiltered(snapshot,
+                    packageName, Binder.getCallingUid(), userId);
+            return packageState == null ? null
+                    : packageState.getUserStateOrDefault(userId).getSplashScreenTheme();
+        }
+
+        @Override
+        public Bundle getSuspendedPackageAppExtras(String packageName, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            final Computer snapshot = snapshot();
+            if (snapshot.getPackageUid(packageName, 0, userId) != callingUid) {
+                throw new SecurityException("Calling package " + packageName
+                        + " does not belong to calling uid " + callingUid);
+            }
+            return mSuspendPackageHelper
+                    .getSuspendedPackageAppExtras(snapshot, packageName, userId, callingUid);
+        }
+
+        @Override
+        public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
+            // allow instant applications
+            ArrayList<FeatureInfo> res;
+            synchronized (mAvailableFeatures) {
+                res = new ArrayList<>(mAvailableFeatures.size() + 1);
+                res.addAll(mAvailableFeatures.values());
+            }
+            final FeatureInfo fi = new FeatureInfo();
+            fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
+                    FeatureInfo.GL_ES_VERSION_UNDEFINED);
+            res.add(fi);
+
+            return new ParceledListSlice<>(res);
+        }
+
+        @Override
+        public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
+            Objects.requireNonNull(packageNames, "packageNames cannot be null");
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
+                    "getUnsuspendablePackagesForUser");
+            final int callingUid = Binder.getCallingUid();
+            if (UserHandle.getUserId(callingUid) != userId) {
+                throw new SecurityException("Calling uid " + callingUid
+                        + " cannot query getUnsuspendablePackagesForUser for user " + userId);
+            }
+            return mSuspendPackageHelper.getUnsuspendablePackagesForUser(snapshotComputer(),
+                    packageNames, userId, callingUid);
+        }
+
+        @Override
+        public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.PACKAGE_VERIFICATION_AGENT,
+                    "Only package verification agents can read the verifier device identity");
+
+            synchronized (mLock) {
+                return mSettings.getVerifierDeviceIdentityLPw(mLiveComputer);
+            }
+        }
+
+        @Override
+        public void makeProviderVisible(int recipientUid, @NonNull String visibleAuthority) {
+            final Computer snapshot = snapshotComputer();
+            final int recipientUserId = UserHandle.getUserId(recipientUid);
+            final ProviderInfo providerInfo =
+                    snapshot.getGrantImplicitAccessProviderInfo(recipientUid, visibleAuthority);
+            if (providerInfo == null) {
+                return;
+            }
+            int visibleUid = providerInfo.applicationInfo.uid;
+            PackageManagerService.this.grantImplicitAccess(snapshot, recipientUserId,
+                    null /*Intent*/, UserHandle.getAppId(recipientUid), visibleUid,
+                    false /*direct*/, false /* retainOnUpdate */);
+        }
+
+        @Override
+        public void makeUidVisible(int recipientUid, int visibleUid) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.MAKE_UID_VISIBLE, "makeUidVisible");
+            final int callingUid = Binder.getCallingUid();
+            final int recipientUserId = UserHandle.getUserId(recipientUid);
+            final int visibleUserId = UserHandle.getUserId(visibleUid);
+            final Computer snapshot = snapshotComputer();
+            snapshot.enforceCrossUserPermission(callingUid, recipientUserId,
+                    false /* requireFullPermission */, false /* checkShell */, "makeUidVisible");
+            snapshot.enforceCrossUserPermission(callingUid, visibleUserId,
+                    false /* requireFullPermission */, false /* checkShell */, "makeUidVisible");
+            snapshot.enforceCrossUserPermission(recipientUid, visibleUserId,
+                    false /* requireFullPermission */, false /* checkShell */, "makeUidVisible");
+
+            PackageManagerService.this.grantImplicitAccess(snapshot, recipientUserId,
+                    null /*Intent*/, UserHandle.getAppId(recipientUid), visibleUid,
+                    false /*direct*/, false /* retainOnUpdate */);
+        }
+
+        @Override
+        public void holdLock(IBinder token, int durationMs) {
+            mTestUtilityService.verifyHoldLockToken(token);
+
+            synchronized (mLock) {
+                SystemClock.sleep(durationMs);
+            }
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
+                int installReason, List<String> whiteListedPermissions) {
+            return mInstallPackageHelper.installExistingPackageAsUser(packageName, userId, installFlags,
+                    installReason, whiteListedPermissions, null);
+        }
+
+        @Override
+        public boolean isAutoRevokeWhitelisted(String packageName) {
+            int mode = mInjector.getSystemService(AppOpsManager.class).checkOpNoThrow(
+                    AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
+                    Binder.getCallingUid(), packageName);
+            return mode == MODE_IGNORED;
+        }
+
+        @Override
+        public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
+            final int callingUid = Binder.getCallingUid();
+            final int callingAppId = UserHandle.getAppId(callingUid);
+
+            final Computer snapshot = snapshotComputer();
+            snapshot.enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
+                    true /*checkShell*/, "isPackageStateProtected");
+
+            if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
+                    && snapshot.checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid)
+                    != PERMISSION_GRANTED) {
+                throw new SecurityException("Caller must have the "
+                        + MANAGE_DEVICE_ADMINS + " permission.");
+            }
+
+            return mProtectedPackages.isPackageStateProtected(userId, packageName);
+        }
+
+        @Override
+        public boolean isProtectedBroadcast(String actionName) {
+            if (actionName != null) {
+                // TODO: remove these terrible hacks
+                if (actionName.startsWith("android.net.netmon.lingerExpired")
+                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
+                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
+                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
+                    return true;
+                }
+            }
+            // allow instant applications
+            synchronized (mProtectedBroadcasts) {
+                return mProtectedBroadcasts.contains(actionName);
+            }
+        }
+
+        /**
+         * Logs process start information (including base APK hash) to the security log.
+         * @hide
+         */
+        @Override
+        public void logAppProcessStartIfNeeded(String packageName, String processName, int uid,
+                String seinfo, String apkFile, int pid) {
+            final Computer snapshot = snapshotComputer();
+            if (snapshot.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+                return;
+            }
+            if (!SecurityLog.isLoggingEnabled()) {
+                return;
+            }
+            mProcessLoggingHandler.logAppProcessStart(mContext,
+                    LocalServices.getService(PackageManagerInternal.class), apkFile, packageName,
+                    processName, uid, seinfo, pid);
+        }
+
+        @Override
+        public int movePackage(final String packageName, final String volumeUuid) {
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.MOVE_PACKAGE, null);
+
+            final int callingUid = Binder.getCallingUid();
+            final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
+            final int moveId = mNextMoveId.getAndIncrement();
+            mHandler.post(() -> {
+                try {
+                    MovePackageHelper movePackageHelper =
+                            new MovePackageHelper(PackageManagerService.this);
+                    movePackageHelper.movePackageInternal(
+                            packageName, volumeUuid, moveId, callingUid, user);
+                } catch (PackageManagerException e) {
+                    Slog.w(PackageManagerService.TAG, "Failed to move " + packageName, e);
+                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
+                }
+            });
+            return moveId;
+        }
+
+        @Override
+        public int movePrimaryStorage(String volumeUuid) throws RemoteException {
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.MOVE_PACKAGE, null);
+
+            final int realMoveId = mNextMoveId.getAndIncrement();
+            final Bundle extras = new Bundle();
+            extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
+            mMoveCallbacks.notifyCreated(realMoveId, extras);
+
+            final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
+                @Override
+                public void onCreated(int moveId, Bundle extras) {
+                    // Ignored
+                }
+
+                @Override
+                public void onStatusChanged(int moveId, int status, long estMillis) {
+                    mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
+                }
+            };
+
+            final StorageManager storage = mInjector.getSystemService(StorageManager.class);
+            storage.setPrimaryStorageUuid(volumeUuid, callback);
+            return realMoveId;
+        }
+
+        @Override
+        public void notifyDexLoad(String loadingPackageName,
+                Map<String, String> classLoaderContextMap,
+                String loaderIsa) {
+            int callingUid = Binder.getCallingUid();
+            if (PackageManagerService.PLATFORM_PACKAGE_NAME.equals(loadingPackageName)
+                    && callingUid != Process.SYSTEM_UID) {
+                Slog.w(PackageManagerService.TAG,
+                        "Non System Server process reporting dex loads as system server. uid="
+                                + callingUid);
+                // Do not record dex loads from processes pretending to be system server.
+                // Only the system server should be assigned the package "android", so reject calls
+                // that don't satisfy the constraint.
+                //
+                // notifyDexLoad is a PM API callable from the app process. So in theory, apps could
+                // craft calls to this API and pretend to be system server. Doing so poses no
+                // particular danger for dex load reporting or later dexopt, however it is a
+                // sensible check to do in order to verify the expectations.
+                return;
+            }
+
+            int userId = UserHandle.getCallingUserId();
+            ApplicationInfo ai = snapshot().getApplicationInfo(loadingPackageName, /*flags*/ 0,
+                    userId);
+            if (ai == null) {
+                Slog.w(PackageManagerService.TAG, "Loading a package that does not exist for the calling user. package="
+                        + loadingPackageName + ", user=" + userId);
+                return;
+            }
+            mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId,
+                    Process.isIsolated(callingUid));
+        }
+
+        @Override
+        public void notifyPackageUse(String packageName, int reason) {
+            final int callingUid = Binder.getCallingUid();
+            final int callingUserId = UserHandle.getUserId(callingUid);
+            Computer snapshot = snapshotComputer();
+            final boolean notify;
+            if (snapshot.getInstantAppPackageName(callingUid) != null) {
+                notify = snapshot.isCallerSameApp(packageName, callingUid);
+            } else {
+                notify = !snapshot.isInstantAppInternal(packageName, callingUserId,
+                        Process.SYSTEM_UID);
+            }
+            if (!notify) {
+                return;
+            }
+
+            notifyPackageUseInternal(packageName, reason);
+        }
+
+        @Override
+        public void overrideLabelAndIcon(@NonNull ComponentName componentName,
+                @NonNull String nonLocalizedLabel, int icon, int userId) {
+            if (TextUtils.isEmpty(nonLocalizedLabel)) {
+                throw new IllegalArgumentException("Override label should be a valid String");
+            }
+            updateComponentLabelIcon(componentName, nonLocalizedLabel, icon, userId);
+        }
+
+        @Override
+        public ParceledListSlice<PackageManager.Property> queryProperty(
+                String propertyName, @PackageManager.PropertyLocation int componentType) {
+            Objects.requireNonNull(propertyName);
+            final int callingUid = Binder.getCallingUid();
+            final int callingUserId = UserHandle.getCallingUserId();
+            final Computer snapshot = snapshotComputer();
+            final List<PackageManager.Property> result =
+                    mPackageProperty.queryProperty(propertyName, componentType, packageName -> {
+                        final PackageStateInternal ps =
+                                snapshot.getPackageStateInternal(packageName);
+                        return snapshot.shouldFilterApplication(ps, callingUid, callingUserId);
+                    });
+            if (result == null) {
+                return ParceledListSlice.emptyList();
+            }
+            return new ParceledListSlice<>(result);
+        }
+
+        /**
+         * Reconcile the information we have about the secondary dex files belonging to
+         * {@code packageName} and the actual dex files. For all dex files that were
+         * deleted, update the internal records and delete the generated oat files.
+         */
+        @Override
+        public void reconcileSecondaryDexFiles(String packageName) {
+            final Computer snapshot = snapshotComputer();
+            if (snapshot.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+                return;
+            } else if (snapshot.isInstantAppInternal(
+                    packageName, UserHandle.getCallingUserId(), Process.SYSTEM_UID)) {
+                return;
+            }
+            mDexManager.reconcileSecondaryDexFiles(packageName);
+        }
+
+        @Override
+        public void registerDexModule(String packageName, String dexModulePath,
+                boolean isSharedModule,
+                IDexModuleRegisterCallback callback) {
+            int userId = UserHandle.getCallingUserId();
+            ApplicationInfo ai = snapshot().getApplicationInfo(packageName, /*flags*/ 0, userId);
+            DexManager.RegisterDexModuleResult result;
+            if (ai == null) {
+                Slog.w(PackageManagerService.TAG,
+                        "Registering a dex module for a package that does not exist for the" +
+                                " calling user. package=" + packageName + ", user=" + userId);
+                result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
+            } else {
+                result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
+            }
+
+            if (callback != null) {
+                mHandler.post(() -> {
+                    try {
+                        callback.onDexModuleRegistered(dexModulePath, result.success,
+                                result.message);
+                    } catch (RemoteException e) {
+                        Slog.w(PackageManagerService.TAG,
+                                "Failed to callback after module registration " + dexModulePath, e);
+                    }
+                });
+            }
+        }
+
+        @Override
+        public void registerMoveCallback(IPackageMoveObserver callback) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+            mMoveCallbacks.register(callback);
+        }
+
+        @Override
+        public void restoreDomainVerification(byte[] backup, int userId) {
+            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+                throw new SecurityException("Only the system may call restorePreferredActivities()");
+            }
+
+            try {
+                ByteArrayInputStream input = new ByteArrayInputStream(backup);
+                TypedXmlPullParser parser = Xml.resolvePullParser(input);
+
+                // User ID input isn't necessary here as it assumes the user integers match and that
+                // the only states inside the backup XML are for the target user.
+                mDomainVerificationManager.restoreSettings(snapshotComputer(), parser);
+                input.close();
+            } catch (Exception e) {
+                if (PackageManagerService.DEBUG_BACKUP) {
+                    Slog.e(PackageManagerService.TAG, "Exception restoring domain verification: " + e.getMessage());
+                }
+            }
+        }
+
+        @Override
+        public void restoreLabelAndIcon(@NonNull ComponentName componentName, int userId) {
+            updateComponentLabelIcon(componentName, null, null, userId);
+        }
+
+        @Override
+        public void sendDeviceCustomizationReadyBroadcast() {
+            mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY,
+                    "sendDeviceCustomizationReadyBroadcast");
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                BroadcastHelper.sendDeviceCustomizationReadyBroadcast();
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
+        public void setApplicationCategoryHint(String packageName, int categoryHint,
+                String callerPackageName) {
+            final PackageStateMutator.InitialState initialState = recordInitialState();
+
+            final FunctionalUtils.ThrowingFunction<Computer, PackageStateMutator.Result>
+                    implementation = computer -> {
+                if (computer.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+                    throw new SecurityException(
+                            "Instant applications don't have access to this method");
+                }
+                mInjector.getSystemService(AppOpsManager.class)
+                        .checkPackage(Binder.getCallingUid(), callerPackageName);
+
+                PackageStateInternal packageState = computer.getPackageStateFiltered(packageName,
+                        Binder.getCallingUid(), UserHandle.getCallingUserId());
+                if (packageState == null) {
+                    throw new IllegalArgumentException("Unknown target package " + packageName);
+                }
+
+                if (!Objects.equals(callerPackageName,
+                        packageState.getInstallSource().installerPackageName)) {
+                    throw new IllegalArgumentException("Calling package " + callerPackageName
+                            + " is not installer for " + packageName);
+                }
+
+                if (packageState.getCategoryOverride() != categoryHint) {
+                    return commitPackageStateMutation(initialState,
+                            packageName, state -> state.setCategoryOverride(categoryHint));
+                } else {
+                    return null;
+                }
+            };
+
+            PackageStateMutator.Result result = implementation.apply(snapshotComputer());
+            if (result != null && result.isStateChanged() && !result.isSpecificPackageNull()) {
+                // TODO: Specific return value of what state changed?
+                // The installer on record might have changed, retry with lock
+                synchronized (mPackageStateWriteLock) {
+                    result = implementation.apply(snapshotComputer());
+                }
+            }
+
+            if (result != null && result.isCommitted()) {
+                scheduleWriteSettings();
+            }
+        }
+
+        @Override
+        public void setApplicationEnabledSetting(String appPackageName,
+                int newState, int flags, int userId, String callingPackage) {
+            if (!mUserManager.exists(userId)) return;
+            if (callingPackage == null) {
+                callingPackage = Integer.toString(Binder.getCallingUid());
+            }
+
+            setEnabledSettings(List.of(new PackageManager.ComponentEnabledSetting(appPackageName, newState, flags)),
+                    userId, callingPackage);
+        }
+
+        @Override
+        public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
+                int userId) {
+            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
+            final int callingUid = Binder.getCallingUid();
+            final Computer snapshot = snapshotComputer();
+            snapshot.enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
+                    true /* checkShell */, "setApplicationHiddenSetting for user " + userId);
+
+            if (hidden && isPackageDeviceAdmin(packageName, userId)) {
+                Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
+                return false;
+            }
+
+            // Do not allow "android" is being disabled
+            if ("android".equals(packageName)) {
+                Slog.w(TAG, "Cannot hide package: android");
+                return false;
+            }
+
+            final long callingId = Binder.clearCallingIdentity();
+            try {
+                final PackageStateInternal packageState =
+                        snapshot.getPackageStateFiltered(packageName, callingUid, userId);
+                if (packageState == null) {
+                    return false;
+                }
+
+                // Cannot hide static shared libs as they are considered
+                // a part of the using app (emulating static linking). Also
+                // static libs are installed always on internal storage.
+                AndroidPackage pkg = packageState.getPkg();
+                if (pkg != null) {
+                    // Cannot hide SDK libs as they are controlled by SDK manager.
+                    if (pkg.getSdkLibName() != null) {
+                        Slog.w(TAG, "Cannot hide package: " + packageName
+                                + " providing SDK library: "
+                                + pkg.getSdkLibName());
+                        return false;
+                    }
+                    // Cannot hide static shared libs as they are considered
+                    // a part of the using app (emulating static linking). Also
+                    // static libs are installed always on internal storage.
+                    if (pkg.getStaticSharedLibName() != null) {
+                        Slog.w(TAG, "Cannot hide package: " + packageName
+                                + " providing static shared library: "
+                                + pkg.getStaticSharedLibName());
+                        return false;
+                    }
+                }
+                // Only allow protected packages to hide themselves.
+                if (hidden && !UserHandle.isSameApp(callingUid, packageState.getAppId())
+                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
+                    Slog.w(TAG, "Not hiding protected package: " + packageName);
+                    return false;
+                }
+
+                if (packageState.getUserStateOrDefault(userId).isHidden() == hidden) {
+                    return false;
+                }
+
+                commitPackageStateMutation(null, packageName, packageState1 ->
+                        packageState1.userState(userId).setHidden(hidden));
+
+                final Computer newSnapshot = snapshotComputer();
+                final PackageStateInternal newPackageState =
+                        newSnapshot.getPackageStateInternal(packageName);
+
+                if (hidden) {
+                    killApplication(packageName, newPackageState.getAppId(), userId, "hiding pkg");
+                    sendApplicationHiddenForUser(packageName, newPackageState, userId);
+                } else {
+                    sendPackageAddedForUser(newSnapshot, packageName, newPackageState, userId,
+                            DataLoaderType.NONE);
+                }
+
+                scheduleWritePackageRestrictions(userId);
+                return true;
+            } finally {
+                Binder.restoreCallingIdentity(callingId);
+            }
+        }
+
+        @Override
+        public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
+                int userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.DELETE_PACKAGES, null);
+            final Computer snapshot = snapshotComputer();
+            PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
+            if (packageState != null && packageState.getPkg() != null) {
+                AndroidPackage pkg = packageState.getPkg();
+                // Cannot block uninstall SDK libs as they are controlled by SDK manager.
+                if (pkg.getSdkLibName() != null) {
+                    Slog.w(PackageManagerService.TAG, "Cannot block uninstall of package: " + packageName
+                            + " providing SDK library: " + pkg.getSdkLibName());
+                    return false;
+                }
+                // Cannot block uninstall of static shared libs as they are
+                // considered a part of the using app (emulating static linking).
+                // Also static libs are installed always on internal storage.
+                if (pkg.getStaticSharedLibName() != null) {
+                    Slog.w(PackageManagerService.TAG, "Cannot block uninstall of package: " + packageName
+                            + " providing static shared library: " + pkg.getStaticSharedLibName());
+                    return false;
+                }
+            }
+            synchronized (mLock) {
+                mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
+            }
+
+            scheduleWritePackageRestrictions(userId);
+            return true;
+        }
+
+        @Override
+        public void setComponentEnabledSetting(ComponentName componentName,
+                int newState, int flags, int userId) {
+            if (!mUserManager.exists(userId)) return;
+
+            setEnabledSettings(List.of(new PackageManager.ComponentEnabledSetting(componentName, newState, flags)),
+                    userId, null /* callingPackage */);
+        }
+
+        @Override
+        public void setComponentEnabledSettings(List<PackageManager.ComponentEnabledSetting> settings, int userId) {
+            if (!mUserManager.exists(userId)) return;
+            if (settings == null || settings.isEmpty()) {
+                throw new IllegalArgumentException("The list of enabled settings is empty");
+            }
+
+            setEnabledSettings(settings, userId, null /* callingPackage */);
+        }
+
+        @Override
+        public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames,
+                int restrictionFlags, int userId) {
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
+                    "setDistractingPackageRestrictionsAsUser");
+
+            final int callingUid = Binder.getCallingUid();
+            if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
+                    && UserHandle.getUserId(callingUid) != userId) {
+                throw new SecurityException("Calling uid " + callingUid + " cannot call for user "
+                        + userId);
+            }
+            Objects.requireNonNull(packageNames, "packageNames cannot be null");
+            final Computer snapshot = snapshotComputer();
+            if (restrictionFlags != 0
+                    && !mSuspendPackageHelper.isSuspendAllowedForUser(snapshot, userId,
+                    callingUid)) {
+                Slog.w(PackageManagerService.TAG, "Cannot restrict packages due to restrictions on user " + userId);
+                return packageNames;
+            }
+
+            final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
+            final IntArray changedUids = new IntArray(packageNames.length);
+            final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
+
+            ArraySet<String> changesToCommit = new ArraySet<>();
+            final boolean[] canRestrict = (restrictionFlags != 0)
+                    ? mSuspendPackageHelper.canSuspendPackageForUser(snapshot, packageNames, userId,
+                    callingUid) : null;
+            for (int i = 0; i < packageNames.length; i++) {
+                final String packageName = packageNames[i];
+                final PackageStateInternal packageState =
+                        snapshot.getPackageStateInternal(packageName);
+                if (packageState == null
+                        || snapshot.shouldFilterApplication(packageState, callingUid, userId)) {
+                    Slog.w(PackageManagerService.TAG, "Could not find package setting for package: " + packageName
+                            + ". Skipping...");
+                    unactionedPackages.add(packageName);
+                    continue;
+                }
+                if (canRestrict != null && !canRestrict[i]) {
+                    unactionedPackages.add(packageName);
+                    continue;
+                }
+                final int oldDistractionFlags = packageState.getUserStateOrDefault(userId)
+                        .getDistractionFlags();
+                if (restrictionFlags != oldDistractionFlags) {
+                    changedPackagesList.add(packageName);
+                    changedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
+                    changesToCommit.add(packageName);
+                }
+            }
+
+            commitPackageStateMutation(null, mutator -> {
+                final int size = changesToCommit.size();
+                for (int index = 0; index < size; index++) {
+                    mutator.forPackage(changesToCommit.valueAt(index))
+                            .userState(userId)
+                            .setDistractionFlags(restrictionFlags);
+                }
+            });
+
+            if (!changedPackagesList.isEmpty()) {
+                final String[] changedPackages = changedPackagesList.toArray(
+                        new String[changedPackagesList.size()]);
+                mHandler.post(() -> mBroadcastHelper.sendDistractingPackagesChanged(
+                        changedPackages, changedUids.toArray(), userId, restrictionFlags));
+                scheduleWritePackageRestrictions(userId);
+            }
+            return unactionedPackages.toArray(new String[0]);
+        }
+
+        @Override
+        public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
+                int userId) {
+            final int callingUid = Binder.getCallingUid();
+            final int callingAppId = UserHandle.getAppId(callingUid);
+
+            final Computer snapshot = snapshotComputer();
+            snapshot.enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/,
+                    true /*checkShell*/, "setHarmfulAppInfo");
+
+            if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
+                    snapshot.checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid)
+                            != PERMISSION_GRANTED) {
+                throw new SecurityException("Caller must have the "
+                        + SET_HARMFUL_APP_WARNINGS + " permission.");
+            }
+
+            PackageStateMutator.Result result = commitPackageStateMutation(null, packageName,
+                    packageState -> packageState.userState(userId)
+                            .setHarmfulAppWarning(warning == null ? null : warning.toString()));
+            if (result.isSpecificPackageNull()) {
+                throw new IllegalArgumentException("Unknown package: " + packageName);
+            }
+            scheduleWritePackageRestrictions(userId);
+        }
+
+        @Override
+        public boolean setInstallLocation(int loc) {
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS,
+                    null);
+            if (getInstallLocation() == loc) {
+                return true;
+            }
+            if (loc == InstallLocationUtils.APP_INSTALL_AUTO
+                    || loc == InstallLocationUtils.APP_INSTALL_INTERNAL
+                    || loc == InstallLocationUtils.APP_INSTALL_EXTERNAL) {
+                android.provider.Settings.Global.putInt(mContext.getContentResolver(),
+                        android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void setInstallerPackageName(String targetPackage, String installerPackageName) {
+            final int callingUid = Binder.getCallingUid();
+            final int callingUserId = UserHandle.getUserId(callingUid);
+            final FunctionalUtils.ThrowingCheckedFunction<Computer, Boolean, RuntimeException>
+                    implementation = snapshot -> {
+                if (snapshot.getInstantAppPackageName(callingUid) != null) {
+                    return false;
+                }
+
+                PackageStateInternal targetPackageState =
+                        snapshot.getPackageStateInternal(targetPackage);
+                if (targetPackageState == null
+                        || snapshot.shouldFilterApplication(targetPackageState, callingUid,
+                        callingUserId)) {
+                    throw new IllegalArgumentException("Unknown target package: " + targetPackage);
+                }
+
+                PackageStateInternal installerPackageState = null;
+                if (installerPackageName != null) {
+                    installerPackageState = snapshot.getPackageStateInternal(installerPackageName);
+                    if (installerPackageState == null
+                            || snapshot.shouldFilterApplication(
+                            installerPackageState, callingUid, callingUserId)) {
+                        throw new IllegalArgumentException("Unknown installer package: "
+                                + installerPackageName);
+                    }
+                }
+
+                Signature[] callerSignature;
+                final int appId = UserHandle.getAppId(callingUid);
+                Pair<PackageStateInternal, SharedUserApi> either =
+                        snapshot.getPackageOrSharedUser(appId);
+                if (either != null) {
+                    if (either.first != null) {
+                        callerSignature = either.first.getSigningDetails().getSignatures();
+                    } else {
+                        callerSignature = either.second.getSigningDetails().getSignatures();
+                    }
+                } else {
+                    throw new SecurityException("Unknown calling UID: " + callingUid);
+                }
+
+                // Verify: can't set installerPackageName to a package that is
+                // not signed with the same cert as the caller.
+                if (installerPackageState != null) {
+                    if (compareSignatures(callerSignature,
+                            installerPackageState.getSigningDetails().getSignatures())
+                            != PackageManager.SIGNATURE_MATCH) {
+                        throw new SecurityException(
+                                "Caller does not have same cert as new installer package "
+                                        + installerPackageName);
+                    }
+                }
+
+                // Verify: if target already has an installer package, it must
+                // be signed with the same cert as the caller.
+                String targetInstallerPackageName =
+                        targetPackageState.getInstallSource().installerPackageName;
+                PackageStateInternal targetInstallerPkgSetting = targetInstallerPackageName == null
+                        ? null : snapshot.getPackageStateInternal(targetInstallerPackageName);
+
+                if (targetInstallerPkgSetting != null) {
+                    if (compareSignatures(callerSignature,
+                            targetInstallerPkgSetting.getSigningDetails().getSignatures())
+                            != PackageManager.SIGNATURE_MATCH) {
+                        throw new SecurityException(
+                                "Caller does not have same cert as old installer package "
+                                        + targetInstallerPackageName);
+                    }
+                } else if (mContext.checkCallingOrSelfPermission(
+                        Manifest.permission.INSTALL_PACKAGES) != PERMISSION_GRANTED) {
+                    // This is probably an attempt to exploit vulnerability b/150857253 of taking
+                    // privileged installer permissions when the installer has been uninstalled or
+                    // was never set.
+                    EventLog.writeEvent(0x534e4554, "150857253", callingUid, "");
+
+                    final long binderToken = Binder.clearCallingIdentity();
+                    try {
+                        if (mInjector.getCompatibility().isChangeEnabledByUid(
+                                PackageManagerService.THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE,
+                                callingUid)) {
+                            throw new SecurityException("Neither user " + callingUid
+                                    + " nor current process has "
+                                    + Manifest.permission.INSTALL_PACKAGES);
+                        } else {
+                            // If change disabled, fail silently for backwards compatibility
+                            return false;
+                        }
+                    } finally {
+                        Binder.restoreCallingIdentity(binderToken);
+                    }
+                }
+
+                return true;
+            };
+            PackageStateMutator.InitialState initialState = recordInitialState();
+            boolean allowed = implementation.apply(snapshotComputer());
+            if (allowed) {
+                // TODO: Need to lock around here to handle mSettings.addInstallerPackageNames,
+                //  should find an alternative which avoids any race conditions
+                PackageStateInternal targetPackageState;
+                synchronized (mLock) {
+                    PackageStateMutator.Result result = commitPackageStateMutation(initialState,
+                            targetPackage, state -> state.setInstaller(installerPackageName));
+                    if (result.isPackagesChanged() || result.isStateChanged()) {
+                        synchronized (mPackageStateWriteLock) {
+                            allowed = implementation.apply(snapshotComputer());
+                            if (allowed) {
+                                commitPackageStateMutation(null, targetPackage,
+                                        state -> state.setInstaller(installerPackageName));
+                            } else {
+                                return;
+                            }
+                        }
+                    }
+                    targetPackageState = snapshotComputer().getPackageStateInternal(targetPackage);
+                    mSettings.addInstallerPackageNames(targetPackageState.getInstallSource());
+                }
+                mAppsFilter.addPackage(targetPackageState);
+                scheduleWriteSettings();
+            }
+        }
+
+        @Override
+        public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
+            if (HIDE_EPHEMERAL_APIS) {
+                return true;
+            }
+
+            final Computer snapshot = snapshotComputer();
+            snapshot.enforceCrossUserPermission(Binder.getCallingUid(), userId,
+                    true /* requireFullPermission */, true /* checkShell */,
+                    "setInstantAppCookie");
+            if (!snapshot.isCallerSameApp(packageName, Binder.getCallingUid())) {
+                return false;
+            }
+
+            PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
+            if (packageState == null || packageState.getPkg() == null) {
+                return false;
+            }
+            return mInstantAppRegistry.setInstantAppCookie(packageState.getPkg(), cookie,
+                    mContext.getPackageManager().getInstantAppCookieMaxBytes(), userId);
+        }
+
+        @Override
+        public void setKeepUninstalledPackages(List<String> packageList) {
+            mContext.enforceCallingPermission(
+                    Manifest.permission.KEEP_UNINSTALLED_PACKAGES,
+                    "setKeepUninstalledPackages requires KEEP_UNINSTALLED_PACKAGES permission");
+            Objects.requireNonNull(packageList);
+
+            setKeepUninstalledPackagesInternal(snapshot(), packageList);
+        }
+
+        @Override
+        public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
+            final Computer snapshot = snapshotComputer();
+            enforceOwnerRights(snapshot, packageName, Binder.getCallingUid());
+            mimeTypes = CollectionUtils.emptyIfNull(mimeTypes);
+            final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
+            Set<String> existingMimeTypes = packageState.getMimeGroups().get(mimeGroup);
+            if (existingMimeTypes == null) {
+                throw new IllegalArgumentException("Unknown MIME group " + mimeGroup
+                        + " for package " + packageName);
+            }
+            if (existingMimeTypes.size() == mimeTypes.size()
+                    && existingMimeTypes.containsAll(mimeTypes)) {
+                return;
+            }
+
+            ArraySet<String> mimeTypesSet = new ArraySet<>(mimeTypes);
+            commitPackageStateMutation(null, packageName, packageStateWrite -> {
+                packageStateWrite.setMimeGroup(mimeGroup, mimeTypesSet);
+            });
+            if (mComponentResolver.updateMimeGroup(snapshotComputer(), packageName, mimeGroup)) {
+                Binder.withCleanCallingIdentity(() ->
+                        mPreferredActivityHelper.clearPackagePreferredActivities(packageName,
+                                UserHandle.USER_ALL));
+            }
+
+            scheduleWriteSettings();
+        }
+
+        @Override
+        public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
+            PackageManagerService.this
+                    .setPackageStoppedState(snapshotComputer(), packageName, stopped, userId);
+        }
+
+        @Override
+        public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
+                PersistableBundle appExtras, PersistableBundle launcherExtras,
+                SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            final Computer snapshot = snapshotComputer();
+            enforceCanSetPackagesSuspendedAsUser(snapshot, callingPackage, callingUid, userId,
+                    "setPackagesSuspendedAsUser");
+            return mSuspendPackageHelper.setPackagesSuspended(snapshot, packageNames, suspended,
+                    appExtras, launcherExtras, dialogInfo, callingPackage, userId, callingUid);
+        }
+
+        @Override
+        public boolean setRequiredForSystemUser(String packageName, boolean requiredForSystemUser) {
+            PackageManagerServiceUtils.enforceSystemOrRoot(
+                    "setRequiredForSystemUser can only be run by the system or root");
+
+            PackageStateMutator.Result result = commitPackageStateMutation(null, packageName,
+                    packageState -> packageState.setRequiredForSystemUser(requiredForSystemUser));
+            if (!result.isCommitted()) {
+                return false;
+            }
+
+            scheduleWriteSettings();
+            return true;
+        }
+
+        @Override
+        public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
+            Preconditions.checkArgumentNonnegative(version);
+            Preconditions.checkArgumentNonnegative(userId);
+            enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
+                    "setRuntimePermissionVersion");
+            mSettings.setDefaultRuntimePermissionsVersion(version, userId);
+        }
+
+        @Override
+        public void setSplashScreenTheme(@NonNull String packageName, @Nullable String themeId,
+                int userId) {
+            final int callingUid = Binder.getCallingUid();
+            final Computer snapshot = snapshotComputer();
+            snapshot.enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
+                    false /* checkShell */, "setSplashScreenTheme");
+            enforceOwnerRights(snapshot, packageName, callingUid);
+
+            PackageStateInternal packageState = filterPackageStateForInstalledAndFiltered(snapshot,
+                    packageName, callingUid, userId);
+            if (packageState == null) {
+                return;
+            }
+
+            commitPackageStateMutation(null, packageName, state ->
+                    state.userState(userId).setSplashScreenTheme(themeId));
+        }
+
+        @Override
+        public void setUpdateAvailable(String packageName, boolean updateAvailable) {
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null);
+            commitPackageStateMutation(null, packageName, state ->
+                    state.setUpdateAvailable(updateAvailable));
+        }
+
+        @Override
+        public void unregisterMoveCallback(IPackageMoveObserver callback) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+            mMoveCallbacks.unregister(callback);
+        }
+
+        @Override
+        public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.PACKAGE_VERIFICATION_AGENT,
+                    "Only package verification agents can verify applications");
+            final int callingUid = Binder.getCallingUid();
+
+            final Message msg = mHandler.obtainMessage(PackageManagerService.PACKAGE_VERIFIED);
+            final PackageVerificationResponse response = new PackageVerificationResponse(
+                    verificationCode, callingUid);
+            msg.arg1 = id;
+            msg.obj = response;
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void requestPackageChecksums(@NonNull String packageName, boolean includeSplits,
+                @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
+                @Nullable List trustedInstallers,
+                @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId) {
+            requestChecksumsInternal(snapshotComputer(), packageName, includeSplits, optional,
+                    required, trustedInstallers, onChecksumsReadyListener, userId,
+                    mInjector.getBackgroundExecutor(), mInjector.getBackgroundHandler());
+        }
+
+        @Override
+        public void notifyPackagesReplacedReceived(String[] packages) {
+            Computer computer = snapshotComputer();
+            ArraySet<String> packagesToNotify = computer.getNotifyPackagesForReplacedReceived(packages);
+            for (int index = 0; index < packagesToNotify.size(); index++) {
+                notifyInstallObserver(packagesToNotify.valueAt(index), false /* killApp */);
+            }
+        }
+
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                throws RemoteException {
+            try {
+                return super.onTransact(code, data, reply, flags);
+            } catch (RuntimeException e) {
+                if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)
+                        && !(e instanceof ParcelableException)) {
+                    Slog.wtf(TAG, "Package Manager Unexpected Exception", e);
+                }
+                throw e;
+            }
+        }
+
+        @Override
+        public void onShellCommand(FileDescriptor in, FileDescriptor out,
+                FileDescriptor err, String[] args, ShellCallback callback,
+                ResultReceiver resultReceiver) {
+            (new PackageManagerShellCommand(this, mContext,
+                    mDomainVerificationManager.getShell()))
+                    .exec(this, in, out, err, args, callback, resultReceiver);
+        }
+
+        @SuppressWarnings("resource")
+        @Override
+        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
+            new DumpHelper(PackageManagerService.this).doDump(fd, pw, args);
+        }
     }
 
     private class PackageManagerLocalImpl implements PackageManagerLocal {
     }
 
-    private class PackageManagerInternalImpl extends PackageManagerInternal {
+    private class PackageManagerInternalImpl extends PackageManagerInternalBase {
+
+        public PackageManagerInternalImpl() {
+            super(PackageManagerService.this);
+        }
+
+        @NonNull
         @Override
-        public List<ApplicationInfo> getInstalledApplications(
-                @PackageManager.ApplicationInfoFlagsBits long flags, int userId, int callingUid) {
-            return PackageManagerService.this.mComputer.getInstalledApplications(flags, userId,
-                    callingUid);
+        protected Context getContext() {
+            return mContext;
+        }
+
+        @NonNull
+        @Override
+        protected PermissionManagerServiceInternal getPermissionManager() {
+            return mPermissionManager;
+        }
+
+        @NonNull
+        @Override
+        protected AppDataHelper getAppDataHelper() {
+            return mAppDataHelper;
+        }
+
+        @NonNull
+        @Override
+        protected PackageObserverHelper getPackageObserverHelper() {
+            return mPackageObserverHelper;
+        }
+
+        @NonNull
+        @Override
+        protected ResolveIntentHelper getResolveIntentHelper() {
+            return mResolveIntentHelper;
+        }
+
+        @NonNull
+        @Override
+        protected SuspendPackageHelper getSuspendPackageHelper() {
+            return mSuspendPackageHelper;
+        }
+
+        @NonNull
+        @Override
+        protected ProtectedPackages getProtectedPackages() {
+            return mProtectedPackages;
+        }
+
+        @NonNull
+        @Override
+        protected UserNeedsBadgingCache getUserNeedsBadging() {
+            return mUserNeedsBadging;
+        }
+
+        @NonNull
+        @Override
+        protected InstantAppRegistry getInstantAppRegistry() {
+            return mInstantAppRegistry;
+        }
+
+        @NonNull
+        @Override
+        protected ApexManager getApexManager() {
+            return mApexManager;
+        }
+
+        @NonNull
+        @Override
+        protected DexManager getDexManager() {
+            return mDexManager;
         }
 
         @Override
         public boolean isPlatformSigned(String packageName) {
-            PackageStateInternal packageState = getPackageStateInternal(packageName);
+            PackageStateInternal packageState = snapshot().getPackageStateInternal(packageName);
             if (packageState == null) {
                 return false;
             }
@@ -6817,7 +6120,8 @@
 
         @Override
         public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
-            SigningDetails sd = getSigningDetails(packageName);
+            final Computer snapshot = snapshot();
+            SigningDetails sd = snapshot.getSigningDetails(packageName);
             if (sd == null) {
                 return false;
             }
@@ -6827,7 +6131,8 @@
 
         @Override
         public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
-            SigningDetails sd = getSigningDetails(packageName);
+            final Computer snapshot = snapshot();
+            SigningDetails sd = snapshot.getSigningDetails(packageName);
             if (sd == null) {
                 return false;
             }
@@ -6838,100 +6143,17 @@
         @Override
         public boolean hasSignatureCapability(int serverUid, int clientUid,
                 @SigningDetails.CertCapabilities int capability) {
-            SigningDetails serverSigningDetails = getSigningDetails(serverUid);
-            SigningDetails clientSigningDetails = getSigningDetails(clientUid);
+            final Computer snapshot = snapshot();
+            SigningDetails serverSigningDetails = snapshot.getSigningDetails(serverUid);
+            SigningDetails clientSigningDetails = snapshot.getSigningDetails(clientUid);
             return serverSigningDetails.checkCapability(clientSigningDetails, capability)
                     || clientSigningDetails.hasAncestorOrSelf(serverSigningDetails);
-
-        }
-
-        private SigningDetails getSigningDetails(@NonNull String packageName) {
-            return PackageManagerService.this.getSigningDetails(packageName);
-        }
-
-        private SigningDetails getSigningDetails(int uid) {
-            return PackageManagerService.this.getSigningDetails(uid);
-        }
-
-        @Override
-        public boolean isInstantApp(String packageName, int userId) {
-            return PackageManagerService.this.isInstantApp(packageName, userId);
-        }
-
-        @Override
-        public String getInstantAppPackageName(int uid) {
-            return PackageManagerService.this.getInstantAppPackageName(uid);
-        }
-
-        @Override
-        public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
-            return PackageManagerService.this.filterAppAccess(pkg, callingUid, userId);
-        }
-
-        @Override
-        public boolean filterAppAccess(String packageName, int callingUid, int userId) {
-            return PackageManagerService.this.filterAppAccess(packageName, callingUid, userId);
-        }
-
-        @Override
-        public boolean filterAppAccess(int uid, int callingUid) {
-            return PackageManagerService.this.filterAppAccess(uid, callingUid);
-        }
-
-        @Nullable
-        @Override
-        public int[] getVisibilityAllowList(@NonNull String packageName, int userId) {
-            return PackageManagerService.this.getVisibilityAllowList(packageName, userId);
-        }
-
-        @Override
-        public boolean canQueryPackage(int callingUid, @Nullable String packageName) {
-            return PackageManagerService.this.canQueryPackage(callingUid, packageName);
-        }
-
-        @Override
-        public AndroidPackage getPackage(String packageName) {
-            return PackageManagerService.this.getPackage(packageName);
-        }
-
-        @Nullable
-        @Override
-        public AndroidPackageApi getAndroidPackage(@NonNull String packageName) {
-            return PackageManagerService.this.getPackage(packageName);
-        }
-
-        @Override
-        public AndroidPackage getPackage(int uid) {
-            return PackageManagerService.this.getPackage(uid);
-        }
-
-        @Override
-        public List<AndroidPackage> getPackagesForAppId(int appId) {
-            return mComputer.getPackagesForAppId(appId);
-        }
-
-        @Nullable
-        @Override
-        public PackageStateInternal getPackageStateInternal(String packageName) {
-            return PackageManagerService.this.getPackageStateInternal(packageName);
-        }
-
-        @Nullable
-        @Override
-        public PackageState getPackageState(@NonNull String packageName) {
-            return PackageManagerService.this.getPackageState(packageName);
-        }
-
-        @NonNull
-        @Override
-        public ArrayMap<String, ? extends PackageStateInternal> getPackageStates() {
-            return PackageManagerService.this.getPackageStates();
         }
 
         @Override
         public PackageList getPackageList(@Nullable PackageListObserver observer) {
             final ArrayList<String> list = new ArrayList<>();
-            forEachPackageState(packageState -> {
+            PackageManagerService.this.forEachPackageState(snapshot(), packageState -> {
                 AndroidPackage pkg = packageState.getPkg();
                 if (pkg != null) {
                     list.add(pkg.getPackageName());
@@ -6945,19 +6167,9 @@
         }
 
         @Override
-        public void removePackageListObserver(PackageListObserver observer) {
-            mPackageObserverHelper.removeObserver(observer);
-        }
-
-        @Override
-        public PackageStateInternal getDisabledSystemPackage(@NonNull String packageName) {
-            return snapshotComputer().getDisabledSystemPackage(packageName);
-        }
-
-        @Override
         public @Nullable
         String getDisabledSystemPackageName(@NonNull String packageName) {
-            PackageStateInternal disabledPkgSetting = getDisabledSystemPackage(
+            PackageStateInternal disabledPkgSetting = snapshot().getDisabledSystemPackage(
                     packageName);
             AndroidPackage disabledPkg = disabledPkgSetting == null
                     ? null : disabledPkgSetting.getPkg();
@@ -6965,51 +6177,15 @@
         }
 
         @Override
-        public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
-            return PackageManagerService.this.getKnownPackageNamesInternal(knownPackage, userId);
-        }
-
-        @Override
-        public boolean isSameApp(@Nullable String packageName, int callingUid, int userId) {
-            if (packageName == null) {
-                return false;
-            }
-
-            if (Process.isSdkSandboxUid(callingUid)) {
-                return packageName.equals(getSdkSandboxPackageName());
-            }
-            int uid = getPackageUid(packageName, 0, userId);
-            return UserHandle.isSameApp(uid, callingUid);
-        }
-
-        @Override
         public boolean isResolveActivityComponent(ComponentInfo component) {
             return mResolveActivity.packageName.equals(component.packageName)
                     && mResolveActivity.name.equals(component.name);
         }
 
         @Override
-        public void setKeepUninstalledPackages(final List<String> packageList) {
-            PackageManagerService.this.setKeepUninstalledPackagesInternal(packageList);
-        }
-
-        @Override
-        public boolean isPermissionsReviewRequired(String packageName, int userId) {
-            return mPermissionManager.isPermissionsReviewRequired(packageName, userId);
-        }
-
-        @Override
-        public PackageInfo getPackageInfo(
-                String packageName, @PackageManager.PackageInfoFlagsBits long flags,
-                int filterCallingUid, int userId) {
-            return PackageManagerService.this.mComputer
-                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
-                            flags, filterCallingUid, userId);
-        }
-
-        @Override
         public long getCeDataInode(String packageName, int userId) {
-            final PackageStateInternal packageState = getPackageStateInternal(packageName);
+            final PackageStateInternal packageState =
+                    snapshot().getPackageStateInternal(packageName);
             if (packageState == null) {
                 return 0;
             } else {
@@ -7018,18 +6194,6 @@
         }
 
         @Override
-        public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
-            return mSuspendPackageHelper.getSuspendedPackageLauncherExtras(
-                    packageName, userId, Binder.getCallingUid());
-        }
-
-        @Override
-        public boolean isPackageSuspended(String packageName, int userId) {
-            return mSuspendPackageHelper.isPackageSuspended(
-                    packageName, userId, Binder.getCallingUid());
-        }
-
-        @Override
         public void removeAllNonSystemPackageSuspensions(int userId) {
             final Computer computer = snapshotComputer();
             final String[] allPackages = computer.getAllAvailablePackageNames();
@@ -7039,14 +6203,6 @@
         }
 
         @Override
-        public void removeNonSystemPackageSuspensions(String packageName, int userId) {
-            mSuspendPackageHelper.removeSuspensionsBySuspendingPackage(snapshotComputer(),
-                    new String[]{packageName},
-                    (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
-                    userId);
-        }
-
-        @Override
         public void flushPackageRestrictions(int userId) {
             synchronized (mLock) {
                 PackageManagerService.this.flushPackageRestrictionsAsUserInternalLocked(userId);
@@ -7054,103 +6210,6 @@
         }
 
         @Override
-        public void removeDistractingPackageRestrictions(String packageName, int userId) {
-            PackageManagerService.this.removeDistractingPackageRestrictions(
-                    new String[]{packageName}, userId);
-        }
-
-        @Override
-        public void removeAllDistractingPackageRestrictions(int userId) {
-            PackageManagerService.this.removeAllDistractingPackageRestrictions(userId);
-        }
-
-        @Override
-        public String getSuspendingPackage(String suspendedPackage, int userId) {
-            return mSuspendPackageHelper.getSuspendingPackage(
-                    suspendedPackage, userId, Binder.getCallingUid());
-        }
-
-        @Override
-        public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage,
-                String suspendingPackage, int userId) {
-            return mSuspendPackageHelper.getSuspendedDialogInfo(
-                    suspendedPackage, suspendingPackage, userId, Binder.getCallingUid());
-        }
-
-        @Override
-        public int getDistractingPackageRestrictions(String packageName, int userId) {
-            final PackageStateInternal packageState = getPackageStateInternal(packageName);
-            return (packageState == null) ? RESTRICTION_NONE
-                    : packageState.getUserStateOrDefault(userId).getDistractionFlags();
-        }
-
-        @Override
-        public int getPackageUid(String packageName,
-                @PackageManager.PackageInfoFlagsBits long flags, int userId) {
-            return PackageManagerService.this
-                    .getPackageUidInternal(packageName, flags, userId, Process.SYSTEM_UID);
-        }
-
-        @Override
-        public ApplicationInfo getApplicationInfo(
-                String packageName, @PackageManager.ApplicationInfoFlagsBits long flags,
-                int filterCallingUid, int userId) {
-            return PackageManagerService.this
-                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
-        }
-
-        @Override
-        public ActivityInfo getActivityInfo(
-                ComponentName component, @PackageManager.ComponentInfoFlagsBits long flags,
-                int filterCallingUid, int userId) {
-            return PackageManagerService.this
-                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
-        }
-
-        @Override
-        public List<ResolveInfo> queryIntentActivities(
-                Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
-                int filterCallingUid, int userId) {
-            return snapshotComputer().queryIntentActivitiesInternal(intent, resolvedType, flags,
-                    userId);
-        }
-
-        @Override
-        public List<ResolveInfo> queryIntentReceivers(Intent intent,
-                String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
-                int filterCallingUid, int userId) {
-            return PackageManagerService.this.mResolveIntentHelper.queryIntentReceiversInternal(
-                    snapshotComputer(), intent, resolvedType, flags, userId, filterCallingUid);
-        }
-
-        @Override
-        public List<ResolveInfo> queryIntentServices(
-                Intent intent, @PackageManager.ResolveInfoFlagsBits long flags, int callingUid,
-                int userId) {
-            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
-            return PackageManagerService.this
-                    .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
-                            false);
-        }
-
-        @Override
-        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
-                int userId) {
-            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
-        }
-
-        @Override
-        public ComponentName getDefaultHomeActivity(int userId) {
-            return PackageManagerService.this.getDefaultHomeActivity(userId);
-        }
-
-        @Override
-        public ComponentName getSystemUiServiceComponent() {
-            return ComponentName.unflattenFromString(mContext.getResources().getString(
-                    com.android.internal.R.string.config_systemUIServiceComponent));
-        }
-
-        @Override
         public void setDeviceAndProfileOwnerPackages(
                 int deviceOwnerUserId, String deviceOwnerPackage,
                 SparseArray<String> profileOwnerPackages) {
@@ -7169,118 +6228,6 @@
         }
 
         @Override
-        public void setDeviceOwnerProtectedPackages(
-                String deviceOwnerPackageName, List<String> packageNames) {
-            mProtectedPackages.setDeviceOwnerProtectedPackages(
-                    deviceOwnerPackageName, packageNames);
-        }
-
-        @Override
-        public boolean isPackageDataProtected(int userId, String packageName) {
-            return mProtectedPackages.isPackageDataProtected(userId, packageName);
-        }
-
-        @Override
-        public boolean isPackageStateProtected(String packageName, int userId) {
-            return mProtectedPackages.isPackageStateProtected(userId, packageName);
-        }
-
-        @Override
-        public boolean isPackageEphemeral(int userId, String packageName) {
-            final PackageStateInternal packageState = getPackageStateInternal(packageName);
-            return packageState != null
-                    && packageState.getUserStateOrDefault(userId).isInstantApp();
-        }
-
-        @Override
-        public boolean wasPackageEverLaunched(String packageName, int userId) {
-            final PackageStateInternal packageState = getPackageStateInternal(packageName);
-            if (packageState == null) {
-                throw new IllegalArgumentException("Unknown package: " + packageName);
-            }
-            return !packageState.getUserStateOrDefault(userId).isNotLaunched();
-        }
-
-        @Override
-        public boolean isEnabledAndMatches(ParsedMainComponent component, long flags, int userId) {
-            return PackageStateUtils.isEnabledAndMatches(
-                    getPackageStateInternal(component.getPackageName()), component, flags, userId);
-        }
-
-        @Override
-        public boolean userNeedsBadging(int userId) {
-            synchronized (mLock) {
-                return PackageManagerService.this.userNeedsBadging(userId);
-            }
-        }
-
-        @Override
-        public String getNameForUid(int uid) {
-            return PackageManagerService.this.getNameForUid(uid);
-        }
-
-        @Override
-        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
-                Intent origIntent, String resolvedType, String callingPackage,
-                @Nullable String callingFeatureId, boolean isRequesterInstantApp,
-                Bundle verificationBundle, int userId) {
-            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(responseObj, origIntent,
-                    resolvedType, callingPackage, callingFeatureId, isRequesterInstantApp,
-                    verificationBundle, userId);
-        }
-
-        @Override
-        public void grantImplicitAccess(int userId, Intent intent,
-                int recipientAppId, int visibleUid, boolean direct) {
-            grantImplicitAccess(userId, intent, recipientAppId, visibleUid, direct,
-                    false /* retainOnUpdate */);
-        }
-
-        @Override
-        public void grantImplicitAccess(int userId, Intent intent,
-                int recipientAppId, int visibleUid, boolean direct, boolean retainOnUpdate) {
-            Computer computer = snapshotComputer();
-            final AndroidPackage visiblePackage = computer.getPackage(visibleUid);
-            final int recipientUid = UserHandle.getUid(userId, recipientAppId);
-            if (visiblePackage == null || computer.getPackage(recipientUid) == null) {
-                return;
-            }
-
-            final boolean instantApp = computer.isInstantAppInternal(
-                    visiblePackage.getPackageName(), userId, visibleUid);
-            final boolean accessGranted;
-            if (instantApp) {
-                if (!direct) {
-                    // if the interaction that lead to this granting access to an instant app
-                    // was indirect (i.e.: URI permission grant), do not actually execute the
-                    // grant.
-                    return;
-                }
-                accessGranted = mInstantAppRegistry.grantInstantAccess(userId, intent,
-                        recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/);
-            } else {
-                accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid,
-                        retainOnUpdate);
-            }
-
-            if (accessGranted) {
-                ApplicationPackageManager.invalidateGetPackagesForUidCache();
-            }
-        }
-
-        @Override
-        public boolean isInstantAppInstallerComponent(ComponentName component) {
-            final ActivityInfo instantAppInstallerActivity = mInstantAppInstallerActivity;
-            return instantAppInstallerActivity != null
-                    && instantAppInstallerActivity.getComponentName().equals(component);
-        }
-
-        @Override
-        public void pruneInstantApps() {
-            mInstantAppRegistry.pruneInstantApps(snapshotComputer());
-        }
-
-        @Override
         public void pruneCachedApksInApex(@NonNull List<PackageInfo> apexPackages) {
             if (mCacheDir == null) {
                 return;
@@ -7288,11 +6235,12 @@
 
             final PackageCacher cacher = new PackageCacher(mCacheDir);
             synchronized (mLock) {
+                final Computer snapshot = snapshot();
                 for (int i = 0, size = apexPackages.size(); i < size; i++) {
                     final List<String> apkNames =
                             mApexManager.getApksInApex(apexPackages.get(i).packageName);
                     for (int j = 0, apksInApex = apkNames.size(); j < apksInApex; j++) {
-                        final AndroidPackage pkg = getPackage(apkNames.get(j));
+                        final AndroidPackage pkg = snapshot.getPackage(apkNames.get(j));
                         cacher.cleanCachedResult(new File(pkg.getPath()));
                     }
                 }
@@ -7300,10 +6248,6 @@
         }
 
         @Override
-        public String getSetupWizardPackageName() {
-            return mSetupWizardPackage;
-        }
-
         public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
             if (policy != null) {
                 mExternalSourcesPolicy = policy;
@@ -7312,7 +6256,8 @@
 
         @Override
         public boolean isPackagePersistent(String packageName) {
-            final PackageStateInternal packageState = getPackageStateInternal(packageName);
+            final PackageStateInternal packageState =
+                    snapshot().getPackageStateInternal(packageName);
             if (packageState == null) {
                 return false;
             }
@@ -7323,16 +6268,20 @@
 
         @Override
         public List<PackageInfo> getOverlayPackages(int userId) {
+            final Computer snapshot = snapshotComputer();
             final ArrayList<PackageInfo> overlayPackages = new ArrayList<>();
-            forEachPackageState(packageState -> {
+            final ArrayMap<String, ? extends PackageStateInternal> packageStates =
+                    snapshot.getPackageStates();
+            for (int index = 0; index < packageStates.size(); index++) {
+                final PackageStateInternal packageState = packageStates.valueAt(index);
                 final AndroidPackage pkg = packageState.getPkg();
                 if (pkg != null && pkg.getOverlayTarget() != null) {
-                    PackageInfo pkgInfo = generatePackageInfo(packageState, 0, userId);
+                    PackageInfo pkgInfo = snapshot.generatePackageInfo(packageState, 0, userId);
                     if (pkgInfo != null) {
                         overlayPackages.add(pkgInfo);
                     }
                 }
-            });
+            }
 
             return overlayPackages;
         }
@@ -7340,7 +6289,7 @@
         @Override
         public List<String> getTargetPackageNames(int userId) {
             List<String> targetPackages = new ArrayList<>();
-            forEachPackageState(packageState -> {
+            PackageManagerService.this.forEachPackageState(snapshot(), packageState -> {
                 final AndroidPackage pkg = packageState.getPkg();
                 if (pkg != null && !pkg.isOverlay()) {
                     targetPackages.add(pkg.getPackageName());
@@ -7358,30 +6307,6 @@
         }
 
         @Override
-        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
-                @PackageManager.ResolveInfoFlagsBits long flags,
-                @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
-                boolean resolveForStart, int filterCallingUid) {
-            return mResolveIntentHelper.resolveIntentInternal(snapshotComputer(),
-                    intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
-                    filterCallingUid);
-        }
-
-        @Override
-        public ResolveInfo resolveService(Intent intent, String resolvedType,
-                @PackageManager.ResolveInfoFlagsBits long flags, int userId, int callingUid) {
-            return mResolveIntentHelper.resolveServiceInternal(snapshotComputer(), intent,
-                    resolvedType, flags, userId, callingUid);
-        }
-
-        @Override
-        public ProviderInfo resolveContentProvider(String name,
-                @PackageManager.ResolveInfoFlagsBits long flags, int userId, int callingUid) {
-            return PackageManagerService.this.mComputer
-                    .resolveContentProvider(name, flags, userId,callingUid);
-        }
-
-        @Override
         public void addIsolatedUid(int isolatedUid, int ownerUid) {
             synchronized (mLock) {
                 mIsolatedOwners.put(isolatedUid, ownerUid);
@@ -7396,141 +6321,12 @@
         }
 
         @Override
-        public int getUidTargetSdkVersion(int uid) {
-            return PackageManagerService.this.getUidTargetSdkVersion(uid);
-        }
-
-        @Override
-        public int getPackageTargetSdkVersion(String packageName) {
-            final PackageStateInternal packageState = getPackageStateInternal(packageName);
-            if (packageState != null && packageState.getPkg() != null) {
-                return packageState.getPkg().getTargetSdkVersion();
-            }
-            return Build.VERSION_CODES.CUR_DEVELOPMENT;
-        }
-
-        @Override
-        public boolean canAccessInstantApps(int callingUid, int userId) {
-            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
-        }
-
-        @Override
-        public boolean canAccessComponent(int callingUid, @NonNull ComponentName component,
-                @UserIdInt int userId) {
-            return mComputer.canAccessComponent(callingUid, component, userId);
-        }
-
-        @Override
-        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
-            return mInstantAppRegistry.hasInstantApplicationMetadata(packageName, userId);
-        }
-
-        @Override
         public void notifyPackageUse(String packageName, int reason) {
             synchronized (mLock) {
                 PackageManagerService.this.notifyPackageUseInternal(packageName, reason);
             }
         }
 
-        @Override
-        public void onPackageProcessKilledForUninstall(String packageName) {
-            mHandler.post(() -> PackageManagerService.this.notifyInstallObserver(packageName,
-                    true /* killApp */));
-        }
-
-        @Override
-        public SparseArray<String> getAppsWithSharedUserIds() {
-            return mComputer.getAppsWithSharedUserIds();
-        }
-
-        @Override
-        @NonNull
-        public String[] getSharedUserPackagesForPackage(String packageName, int userId) {
-            return mComputer.getSharedUserPackagesForPackage(packageName, userId);
-        }
-
-        @Override
-        public ArrayMap<String, ProcessInfo> getProcessesForUid(int uid) {
-            return mComputer.getProcessesForUid(uid);
-        }
-
-        @Override
-        public int[] getPermissionGids(String permissionName, int userId) {
-            return mPermissionManager.getPermissionGids(permissionName, userId);
-        }
-
-        @Override
-        public boolean isOnlyCoreApps() {
-            return PackageManagerService.this.isOnlyCoreApps();
-        }
-
-        @Override
-        public void freeStorage(String volumeUuid, long bytes,
-                @StorageManager.AllocateFlags int flags) throws IOException {
-            PackageManagerService.this.freeStorage(volumeUuid, bytes, flags);
-        }
-
-        @Override
-        public void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
-            PackageManagerService.this.forEachPackageSetting(actionLocked);
-        }
-
-        @Override
-        public void forEachPackageState(Consumer<PackageStateInternal> action) {
-            PackageManagerService.this.forEachPackageState(action);
-        }
-
-        @Override
-        public void forEachPackage(Consumer<AndroidPackage> action) {
-            PackageManagerService.this.forEachPackage(action);
-        }
-
-        @Override
-        public void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> action,
-                @UserIdInt int userId) {
-            PackageManagerService.this.forEachInstalledPackage(action, userId);
-        }
-
-        @Override
-        public ArraySet<String> getEnabledComponents(String packageName, int userId) {
-            final PackageStateInternal packageState = getPackageStateInternal(packageName);
-            if (packageState == null) {
-                return new ArraySet<>();
-            }
-            return packageState.getUserStateOrDefault(userId).getEnabledComponents();
-        }
-
-        @Override
-        public ArraySet<String> getDisabledComponents(String packageName, int userId) {
-            final PackageStateInternal packageState = getPackageStateInternal(packageName);
-            if (packageState == null) {
-                return new ArraySet<>();
-            }
-            return packageState.getUserStateOrDefault(userId).getDisabledComponents();
-        }
-
-        @Override
-        public @PackageManager.EnabledState int getApplicationEnabledState(
-                String packageName, int userId) {
-            final PackageStateInternal packageState = getPackageStateInternal(packageName);
-            if (packageState == null) {
-                return COMPONENT_ENABLED_STATE_DEFAULT;
-            }
-            return packageState.getUserStateOrDefault(userId).getEnabledState();
-        }
-
-        @Override
-        public @PackageManager.EnabledState int getComponentEnabledSetting(
-                @NonNull ComponentName componentName, int callingUid, int userId) {
-            return PackageManagerService.this.mComputer.getComponentEnabledSettingInternal(
-                    componentName, callingUid, userId);
-        }
-
-        @Override
-        public void setEnableRollbackCode(int token, int enableRollbackCode) {
-            PackageManagerService.this.setEnableRollbackCode(token, enableRollbackCode);
-        }
-
         /**
          * Ask the package manager to compile layouts in the given package.
          */
@@ -7546,11 +6342,6 @@
             return mArtManagerService.compileLayouts(pkg);
         }
 
-        @Override
-        public void finishPackageInstall(int token, boolean didLaunch) {
-            PackageManagerService.this.finishPackageInstall(token, didLaunch);
-        }
-
         @Nullable
         @Override
         public String removeLegacyDefaultBrowserPackageName(int userId) {
@@ -7560,16 +6351,6 @@
         }
 
         @Override
-        public boolean isApexPackage(String packageName) {
-            return PackageManagerService.this.mApexManager.isApexPackage(packageName);
-        }
-
-        @Override
-        public List<String> getApksInApex(String apexPackageName) {
-            return PackageManagerService.this.mApexManager.getApksInApex(apexPackageName);
-        }
-
-        @Override
         public void uninstallApex(String packageName, long versionCode, int userId,
                 IntentSender intentSender, int flags) {
             final int callerUid = Binder.getCallingUid();
@@ -7644,11 +6425,6 @@
         }
 
         @Override
-        public boolean isCallerInstallerOfRecord(@NonNull AndroidPackage pkg, int callingUid) {
-            return mComputer.isCallerInstallerOfRecord(pkg, callingUid);
-        }
-
-        @Override
         public boolean isPermissionUpgradeNeeded(int userId) {
             return mSettings.isPermissionUpgradeNeeded(userId);
         }
@@ -7662,13 +6438,9 @@
         }
 
         @Override
-        public List<String> getMimeGroup(String packageName, String mimeGroup) {
-            return PackageManagerService.this.getMimeGroupInternal(packageName, mimeGroup);
-        }
-
-        @Override
         public void setVisibilityLogging(String packageName, boolean enable) {
-            final PackageStateInternal packageState = getPackageStateInternal(packageName);
+            final PackageStateInternal packageState =
+                    snapshot().getPackageStateInternal(packageName);
             if (packageState == null) {
                 throw new IllegalStateException("No package found for " + packageName);
             }
@@ -7676,12 +6448,6 @@
         }
 
         @Override
-        public boolean isSystemPackage(@NonNull String packageName) {
-            return packageName.equals(
-                    PackageManagerService.this.ensureSystemPackageName(packageName));
-        }
-
-        @Override
         public void clearBlockUninstallForUser(@UserIdInt int userId) {
             synchronized (mLock) {
                 mSettings.clearBlockUninstallLPw(userId);
@@ -7690,21 +6456,11 @@
         }
 
         @Override
-        public void unsuspendForSuspendingPackage(final String packageName, int affectedUser) {
-            PackageManagerService.this.unsuspendForSuspendingPackage(snapshotComputer(),
-                    packageName, affectedUser);
-        }
-
-        @Override
-        public boolean isSuspendingAnyPackages(String suspendingPackage, int userId) {
-            return PackageManagerService.this.isSuspendingAnyPackages(suspendingPackage, userId);
-        }
-
-        @Override
         public boolean registerInstalledLoadingProgressCallback(String packageName,
                 PackageManagerInternal.InstalledLoadingProgressCallback callback, int userId) {
-            final PackageStateInternal ps =
-                    getPackageStateInstalledFiltered(packageName, Binder.getCallingUid(), userId);
+            final Computer snapshot = snapshotComputer();
+            final PackageStateInternal ps = filterPackageStateForInstalledAndFiltered(snapshot,
+                    packageName, Binder.getCallingUid(), userId);
             if (ps == null) {
                 return false;
             }
@@ -7725,8 +6481,9 @@
         @Override
         public IncrementalStatesInfo getIncrementalStatesInfo(
                 @NonNull String packageName, int filterCallingUid, int userId) {
-            final PackageStateInternal ps =
-                    getPackageStateInstalledFiltered(packageName, filterCallingUid, userId);
+            final Computer snapshot = snapshotComputer();
+            final PackageStateInternal ps = filterPackageStateForInstalledAndFiltered(snapshot,
+                    packageName, filterCallingUid, userId);
             if (ps == null) {
                 return null;
             }
@@ -7734,64 +6491,23 @@
         }
 
         @Override
-        public void requestChecksums(@NonNull String packageName, boolean includeSplits,
-                @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
-                @Nullable List trustedInstallers,
-                @NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId,
-                @NonNull Executor executor, @NonNull Handler handler) {
-            requestChecksumsInternal(packageName, includeSplits, optional, required,
-                    trustedInstallers, onChecksumsReadyListener, userId, executor, handler);
+        public boolean isSameApp(@Nullable String packageName, int callingUid, int userId) {
+            if (packageName == null) {
+                return false;
+            }
+
+            if (Process.isSdkSandboxUid(callingUid)) {
+                return packageName.equals(mRequiredSdkSandboxPackage);
+            }
+            Computer snapshot = snapshot();
+            int uid = snapshot.getPackageUid(packageName, 0, userId);
+            return UserHandle.isSameApp(uid, callingUid);
         }
 
         @Override
-        public boolean isPackageFrozen(@NonNull String packageName,
-                int callingUid, int userId) {
-            return PackageManagerService.this.getPackageStartability(
-                    packageName, callingUid, userId) == PACKAGE_STARTABILITY_FROZEN;
-        }
-
-        @Override
-        public long deleteOatArtifactsOfPackage(String packageName) {
-            return PackageManagerService.this.deleteOatArtifactsOfPackage(packageName);
-        }
-
-        @Override
-        public void reconcileAppsData(int userId, @StorageManager.StorageFlags int flags,
-                boolean migrateAppsData) {
-            PackageManagerService.this.mAppDataHelper.reconcileAppsData(userId, flags,
-                    migrateAppsData);
-        }
-
-        @Override
-        @NonNull
-        public ArraySet<PackageStateInternal> getSharedUserPackages(int sharedUserAppId) {
-            return PackageManagerService.this.mComputer.getSharedUserPackages(sharedUserAppId);
-        }
-
-        @Override
-        @Nullable
-        public SharedUserApi getSharedUserApi(int sharedUserAppId) {
-            return mComputer.getSharedUser(sharedUserAppId);
-        }
-
-        @NonNull
-        @Override
-        public PackageStateMutator.InitialState recordInitialState() {
-            return PackageManagerService.this.recordInitialState();
-        }
-
-        @Nullable
-        @Override
-        public PackageStateMutator.Result commitPackageStateMutation(
-                @Nullable PackageStateMutator.InitialState state,
-                @NonNull Consumer<PackageStateMutator> consumer) {
-            return PackageManagerService.this.commitPackageStateMutation(state, consumer);
-        }
-
-        @NonNull
-        @Override
-        public Computer snapshot() {
-            return snapshotComputer();
+        public void onPackageProcessKilledForUninstall(String packageName) {
+            mHandler.post(() -> PackageManagerService.this.notifyInstallObserver(packageName,
+                    true /* killApp */));
         }
     }
 
@@ -7876,23 +6592,6 @@
         return true;
     }
 
-    @Override
-    public int getRuntimePermissionsVersion(@UserIdInt int userId) {
-        Preconditions.checkArgumentNonnegative(userId);
-        enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
-                "getRuntimePermissionVersion");
-        return mSettings.getDefaultRuntimePermissionsVersion(userId);
-    }
-
-    @Override
-    public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
-        Preconditions.checkArgumentNonnegative(version);
-        Preconditions.checkArgumentNonnegative(userId);
-        enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
-                "setRuntimePermissionVersion");
-        mSettings.setDefaultRuntimePermissionsVersion(version, userId);
-    }
-
     private void enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
             @NonNull String message) {
         if (mContext.checkCallingOrSelfPermission(
@@ -7923,24 +6622,6 @@
         return mSettings.getDisabledSystemPkgLPr(packageName);
     }
 
-    @VisibleForTesting(visibility = Visibility.PRIVATE)
-    @Nullable
-    PackageStateInternal getPackageStateInternal(String packageName) {
-        return mComputer.getPackageStateInternal(packageName);
-    }
-
-    @Nullable
-    PackageStateInternal getPackageStateInternal(String packageName, int callingUid) {
-        return mComputer.getPackageStateInternal(packageName, callingUid);
-    }
-
-    @Nullable
-    PackageStateInternal getPackageStateInstalledFiltered(@NonNull String packageName,
-            int callingUid, @UserIdInt int userId) {
-        return filterPackageStateForInstalledAndFiltered(mComputer, packageName, callingUid,
-                userId);
-    }
-
     @Nullable
     private PackageStateInternal filterPackageStateForInstalledAndFiltered(
             @NonNull Computer computer, @NonNull String packageName, int callingUid,
@@ -7956,22 +6637,8 @@
         }
     }
 
-    @Nullable
-    private PackageState getPackageState(String packageName) {
-        return mComputer.getPackageStateCopied(packageName);
-    }
-
-    @NonNull
-    ArrayMap<String, ? extends PackageStateInternal> getPackageStates() {
-        Computer computer = snapshotComputer();
-        if (computer == mLiveComputer) {
-            return new ArrayMap<>(computer.getPackageStates());
-        } else {
-            return computer.getPackageStates();
-        }
-    }
-
-    private void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
+    @Deprecated
+    void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
         synchronized (mLock) {
             int size = mSettings.getPackagesLocked().size();
             for (int index = 0; index < size; index++) {
@@ -7980,13 +6647,13 @@
         }
     }
 
-    void forEachPackageState(Consumer<PackageStateInternal> consumer) {
-        forEachPackageState(mComputer.getPackageStates(), consumer);
+    void forEachPackageState(@NonNull Computer snapshot, Consumer<PackageStateInternal> consumer) {
+        forEachPackageState(snapshot.getPackageStates(), consumer);
     }
 
-    void forEachPackage(Consumer<AndroidPackage> consumer) {
+    void forEachPackage(@NonNull Computer snapshot, Consumer<AndroidPackage> consumer) {
         final ArrayMap<String, ? extends PackageStateInternal> packageStates =
-                mComputer.getPackageStates();
+                snapshot.getPackageStates();
         int size = packageStates.size();
         for (int index = 0; index < size; index++) {
             PackageStateInternal packageState = packageStates.valueAt(index);
@@ -8006,7 +6673,7 @@
         }
     }
 
-    void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> action,
+    void forEachInstalledPackage(@NonNull Computer snapshot, @NonNull Consumer<AndroidPackage> action,
             @UserIdInt int userId) {
         Consumer<PackageStateInternal> actionWrapped = packageState -> {
             if (packageState.getPkg() != null
@@ -8014,30 +6681,13 @@
                 action.accept(packageState.getPkg());
             }
         };
-        forEachPackageState(mComputer.getPackageStates(), actionWrapped);
+        forEachPackageState(snapshot.getPackageStates(), actionWrapped);
     }
 
     boolean isHistoricalPackageUsageAvailable() {
         return mPackageUsage.isHistoricalPackageUsageAvailable();
     }
 
-    /**
-     * Logs process start information (including base APK hash) to the security log.
-     * @hide
-     */
-    @Override
-    public void logAppProcessStartIfNeeded(String packageName, String processName, int uid,
-            String seinfo, String apkFile, int pid) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return;
-        }
-        if (!SecurityLog.isLoggingEnabled()) {
-            return;
-        }
-        mProcessLoggingHandler.logAppProcessStart(mContext, mPmInternal, apkFile, packageName,
-                processName, uid, seinfo, pid);
-    }
-
     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(AndroidPackage pkg) {
         return getOrCreateCompilerPackageStats(pkg.getPackageName());
     }
@@ -8046,77 +6696,39 @@
         return mCompilerStats.getOrCreatePackageStats(pkgName);
     }
 
-    @Override
-    public boolean isAutoRevokeWhitelisted(String packageName) {
-        int mode = mInjector.getSystemService(AppOpsManager.class).checkOpNoThrow(
-                AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
-                Binder.getCallingUid(), packageName);
-        return mode == MODE_IGNORED;
-    }
-
-    @PackageManager.InstallReason
-    @Override
-    public int getInstallReason(@NonNull String packageName, @UserIdInt int userId) {
-        return mComputer.getInstallReason(packageName, userId);
-    }
-
-    @Override
-    public boolean canRequestPackageInstalls(String packageName, int userId) {
-        return mComputer.canRequestPackageInstalls(packageName, Binder.getCallingUid(), userId,
-                true /* throwIfPermNotDeclared*/);
-    }
-
-    /**
-     * Returns true if the system or user is explicitly preventing an otherwise valid installer to
-     * complete an install. This includes checks like unknown sources and user restrictions.
-     */
-    public boolean isInstallDisabledForPackage(String packageName, int uid, int userId) {
-        return mComputer.isInstallDisabledForPackage(packageName, uid, userId);
-    }
-
-    @Override
-    public ComponentName getInstantAppResolverSettingsComponent() {
-        return mInstantAppResolverSettingsComponent;
-    }
-
-    @Override
-    public ComponentName getInstantAppInstallerComponent() {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return null;
-        }
-        return mInstantAppInstallerActivity == null
-                ? null : mInstantAppInstallerActivity.getComponentName();
-    }
-
-    @Override
-    public String getInstantAppAndroidId(String packageName, int userId) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
-                "getInstantAppAndroidId");
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
-                false /* checkShell */, "getInstantAppAndroidId");
-        // Make sure the target is an Instant App.
-        if (!isInstantApp(packageName, userId)) {
-            return null;
-        }
-        return mInstantAppRegistry.getInstantAppAndroidId(packageName, userId);
-    }
-
-    @Override
-    public void grantImplicitAccess(int recipientUid, @NonNull String visibleAuthority) {
-        final int callingUid = Binder.getCallingUid();
-        final int recipientUserId = UserHandle.getUserId(recipientUid);
-        final ProviderInfo providerInfo =
-                mComputer.getGrantImplicitAccessProviderInfo(recipientUid, visibleAuthority);
-        if (providerInfo == null) {
+    void grantImplicitAccess(@NonNull Computer snapshot, @UserIdInt int userId,
+            Intent intent, @AppIdInt int recipientAppId, int visibleUid, boolean direct,
+            boolean retainOnUpdate) {
+        final AndroidPackage visiblePackage = snapshot.getPackage(visibleUid);
+        final int recipientUid = UserHandle.getUid(userId, recipientAppId);
+        if (visiblePackage == null || snapshot.getPackage(recipientUid) == null) {
             return;
         }
-        int visibleUid = providerInfo.applicationInfo.uid;
-        mPmInternal.grantImplicitAccess(recipientUserId, null /*Intent*/,
-                UserHandle.getAppId(recipientUid), visibleUid, false /*direct*/);
+
+        final boolean instantApp = snapshot.isInstantAppInternal(
+                visiblePackage.getPackageName(), userId, visibleUid);
+        final boolean accessGranted;
+        if (instantApp) {
+            if (!direct) {
+                // if the interaction that lead to this granting access to an instant app
+                // was indirect (i.e.: URI permission grant), do not actually execute the
+                // grant.
+                return;
+            }
+            accessGranted = mInstantAppRegistry.grantInstantAccess(userId, intent,
+                    recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/);
+        } else {
+            accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid,
+                    retainOnUpdate);
+        }
+
+        if (accessGranted) {
+            ApplicationPackageManager.invalidateGetPackagesForUidCache();
+        }
     }
 
-    boolean canHaveOatDir(String packageName) {
-        final PackageStateInternal packageState = getPackageStateInternal(packageName);
+    boolean canHaveOatDir(@NonNull Computer snapshot, String packageName) {
+        final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
         if (packageState == null || packageState.getPkg() == null) {
             return false;
         }
@@ -8124,8 +6736,8 @@
                 packageState.getTransientState().isUpdatedSystemApp());
     }
 
-    long deleteOatArtifactsOfPackage(String packageName) {
-        PackageStateInternal packageState = getPackageStateInternal(packageName);
+    long deleteOatArtifactsOfPackage(@NonNull Computer snapshot, String packageName) {
+        PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
         if (packageState == null || packageState.getPkg() == null) {
             return -1; // error code of deleteOptimizedFiles
         }
@@ -8133,107 +6745,9 @@
                 ArtUtils.createArtPackageInfo(packageState.getPkg(), packageState));
     }
 
-    @NonNull
-    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
-        return mComputer.getUnusedPackages(downgradeTimeThresholdMillis);
-    }
-
-    @Override
-    public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
-            int userId) {
-        final int callingUid = Binder.getCallingUid();
-        final int callingAppId = UserHandle.getAppId(callingUid);
-
-        enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/,
-                true /*checkShell*/, "setHarmfulAppInfo");
-
-        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
-                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
-            throw new SecurityException("Caller must have the "
-                    + SET_HARMFUL_APP_WARNINGS + " permission.");
-        }
-
-        PackageStateMutator.Result result = commitPackageStateMutation(null, packageName,
-                packageState -> packageState.userState(userId)
-                        .setHarmfulAppWarning(warning == null ? null : warning.toString()));
-        if (result.isSpecificPackageNull()) {
-            throw new IllegalArgumentException("Unknown package: " + packageName);
-        }
-        scheduleWritePackageRestrictions(userId);
-    }
-
-    @Nullable
-    @Override
-    public CharSequence getHarmfulAppWarning(@NonNull String packageName, @UserIdInt int userId) {
-        return mComputer.getHarmfulAppWarning(packageName, userId);
-    }
-
-    @Override
-    public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
-        final int callingUid = Binder.getCallingUid();
-        final int callingAppId = UserHandle.getAppId(callingUid);
-
-        enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
-                true /*checkShell*/, "isPackageStateProtected");
-
-        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
-                && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
-            throw new SecurityException("Caller must have the "
-                    + MANAGE_DEVICE_ADMINS + " permission.");
-        }
-
-        return mProtectedPackages.isPackageStateProtected(userId, packageName);
-    }
-
-    @Override
-    public void sendDeviceCustomizationReadyBroadcast() {
-        mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY,
-                "sendDeviceCustomizationReadyBroadcast");
-
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            BroadcastHelper.sendDeviceCustomizationReadyBroadcast();
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    @Override
-    public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
-        enforceOwnerRights(packageName, Binder.getCallingUid());
-        mimeTypes = CollectionUtils.emptyIfNull(mimeTypes);
-        final PackageStateInternal packageState = getPackageStateInternal(packageName);
-        Set<String> existingMimeTypes = packageState.getMimeGroups().get(mimeGroup);
-        if (existingMimeTypes == null) {
-            throw new IllegalArgumentException("Unknown MIME group " + mimeGroup
-                    + " for package " + packageName);
-        }
-        if (existingMimeTypes.size() == mimeTypes.size()
-                && existingMimeTypes.containsAll(mimeTypes)) {
-            return;
-        }
-
-        ArraySet<String> mimeTypesSet = new ArraySet<>(mimeTypes);
-        commitPackageStateMutation(null, packageName, packageStateWrite -> {
-            packageStateWrite.setMimeGroup(mimeGroup, mimeTypesSet);
-        });
-        if (mComponentResolver.updateMimeGroup(snapshotComputer(), packageName, mimeGroup)) {
-            Binder.withCleanCallingIdentity(() ->
-                    mPreferredActivityHelper.clearPackagePreferredActivities(packageName,
-                            UserHandle.USER_ALL));
-        }
-
-        scheduleWriteSettings();
-    }
-
-    @Override
-    public List<String> getMimeGroup(String packageName, String mimeGroup) {
-        enforceOwnerRights(packageName, Binder.getCallingUid());
-        return getMimeGroupInternal(packageName, mimeGroup);
-    }
-
-    private List<String> getMimeGroupInternal(String packageName, String mimeGroup) {
-        final PackageStateInternal packageState = getPackageStateInternal(packageName);
+    List<String> getMimeGroupInternal(@NonNull Computer snapshot, String packageName,
+            String mimeGroup) {
+        final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
         if (packageState == null) {
             return Collections.emptyList();
         }
@@ -8247,32 +6761,6 @@
         return new ArrayList<>(mimeTypes);
     }
 
-    @Override
-    public void setSplashScreenTheme(@NonNull String packageName, @Nullable String themeId,
-            int userId) {
-        final int callingUid = Binder.getCallingUid();
-        enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
-                false /* checkShell */, "setSplashScreenTheme");
-        enforceOwnerRights(packageName, callingUid);
-
-        PackageStateInternal packageState = getPackageStateInstalledFiltered(packageName,
-                callingUid, userId);
-        if (packageState == null) {
-            return;
-        }
-
-        commitPackageStateMutation(null, packageName, state ->
-                state.userState(userId).setSplashScreenTheme(themeId));
-    }
-
-    @Override
-    public String getSplashScreenTheme(@NonNull String packageName, int userId) {
-        PackageStateInternal packageState =
-                getPackageStateInstalledFiltered(packageName, Binder.getCallingUid(), userId);
-        return packageState == null ? null
-                : packageState.getUserStateOrDefault(userId).getSplashScreenTheme();
-    }
-
     /**
      * Temporary method that wraps mSettings.writeLPr() and calls mPermissionManager's
      * writeLegacyPermissionsTEMP() beforehand.
@@ -8286,21 +6774,6 @@
     }
 
     @Override
-    public IBinder getHoldLockToken() {
-        if (!Build.IS_DEBUGGABLE) {
-            throw new SecurityException("getHoldLockToken requires a debuggable build");
-        }
-
-        mContext.enforceCallingPermission(
-                Manifest.permission.INJECT_EVENTS,
-                "getHoldLockToken requires INJECT_EVENTS permission");
-
-        final Binder token = new Binder();
-        token.attachInterface(this, "holdLock:" + Binder.getCallingUid());
-        return token;
-    }
-
-    @Override
     public void verifyHoldLockToken(IBinder token) {
         if (!Build.IS_DEBUGGABLE) {
             throw new SecurityException("holdLock requires a debuggable build");
@@ -8315,15 +6788,6 @@
         }
     }
 
-    @Override
-    public void holdLock(IBinder token, int durationMs) {
-        mTestUtilityService.verifyHoldLockToken(token);
-
-        synchronized (mLock) {
-            SystemClock.sleep(durationMs);
-        }
-    }
-
     static String getDefaultTimeouts() {
         final long token = Binder.clearCallingIdentity();
         try {
@@ -8348,16 +6812,16 @@
      * Returns the array containing per-uid timeout configuration.
      * This is derived from DeviceConfig flags.
      */
-    public @NonNull PerUidReadTimeouts[] getPerUidReadTimeouts() {
+    public @NonNull PerUidReadTimeouts[] getPerUidReadTimeouts(@NonNull Computer snapshot) {
         PerUidReadTimeouts[] result = mPerUidReadTimeoutsCache;
         if (result == null) {
-            result = parsePerUidReadTimeouts();
+            result = parsePerUidReadTimeouts(snapshot);
             mPerUidReadTimeoutsCache = result;
         }
         return result;
     }
 
-    private @NonNull PerUidReadTimeouts[] parsePerUidReadTimeouts() {
+    private @NonNull PerUidReadTimeouts[] parsePerUidReadTimeouts(@NonNull Computer snapshot) {
         final String defaultTimeouts = getDefaultTimeouts();
         final String knownDigestersList = getKnownDigestersList();
         final List<PerPackageReadTimeouts> perPackageReadTimeouts =
@@ -8371,7 +6835,8 @@
         final List<PerUidReadTimeouts> result = new ArrayList<>(perPackageReadTimeouts.size());
         for (int i = 0, size = perPackageReadTimeouts.size(); i < size; ++i) {
             final PerPackageReadTimeouts perPackage = perPackageReadTimeouts.get(i);
-            final PackageStateInternal ps = getPackageStateInternal(perPackage.packageName);
+            final PackageStateInternal ps =
+                    snapshot.getPackageStateInternal(perPackage.packageName);
             if (ps == null) {
                 if (DEBUG_PER_UID_READ_TIMEOUTS) {
                     Slog.i(TAG, "PerUidReadTimeouts: package not found = "
@@ -8421,17 +6886,7 @@
         return result.toArray(new PerUidReadTimeouts[result.size()]);
     }
 
-    @Override
-    public void setKeepUninstalledPackages(List<String> packageList) {
-        mContext.enforceCallingPermission(
-                Manifest.permission.KEEP_UNINSTALLED_PACKAGES,
-                "setKeepUninstalledPackages requires KEEP_UNINSTALLED_PACKAGES permission");
-        Objects.requireNonNull(packageList);
-
-        setKeepUninstalledPackagesInternal(packageList);
-    }
-
-    private void setKeepUninstalledPackagesInternal(List<String> packageList) {
+    void setKeepUninstalledPackagesInternal(@NonNull Computer snapshot, List<String> packageList) {
         Preconditions.checkNotNull(packageList);
         synchronized (mKeepUninstalledPackages) {
             List<String> toRemove = new ArrayList<>(mKeepUninstalledPackages);
@@ -8441,7 +6896,7 @@
             mKeepUninstalledPackages.addAll(packageList);
 
             for (int i = 0; i < toRemove.size(); i++) {
-                deletePackageIfUnused(toRemove.get(i));
+                deletePackageIfUnused(snapshot, toRemove.get(i));
             }
         }
     }
@@ -8452,19 +6907,6 @@
         }
     }
 
-    @Override
-    public IntentSender getLaunchIntentSenderForPackage(String packageName, String callingPackage,
-            String featureId, int userId) throws RemoteException {
-        return mResolveIntentHelper.getLaunchIntentSenderForPackage(snapshotComputer(),
-                packageName, callingPackage, featureId, userId);
-    }
-
-    @Override
-    public boolean canPackageQuery(@NonNull String sourcePackageName,
-            @NonNull String targetPackageName, @UserIdInt int userId) {
-        return mComputer.canPackageQuery(sourcePackageName, targetPackageName, userId);
-    }
-
     boolean getSafeMode() {
         return mSafeMode;
     }
@@ -8501,43 +6943,44 @@
         mInstrumentation.put(name, instrumentation);
     }
 
-    String[] getKnownPackageNamesInternal(int knownPackage, int userId) {
+    String[] getKnownPackageNamesInternal(@NonNull Computer snapshot, int knownPackage,
+            int userId) {
         switch (knownPackage) {
             case PackageManagerInternal.PACKAGE_BROWSER:
                 return new String[] { mDefaultAppProvider.getDefaultBrowser(userId) };
             case PackageManagerInternal.PACKAGE_INSTALLER:
-                return mComputer.filterOnlySystemPackages(mRequiredInstallerPackage);
+                return snapshot.filterOnlySystemPackages(mRequiredInstallerPackage);
             case PackageManagerInternal.PACKAGE_UNINSTALLER:
-                return mComputer.filterOnlySystemPackages(mRequiredUninstallerPackage);
+                return snapshot.filterOnlySystemPackages(mRequiredUninstallerPackage);
             case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
-                return mComputer.filterOnlySystemPackages(mSetupWizardPackage);
+                return snapshot.filterOnlySystemPackages(mSetupWizardPackage);
             case PackageManagerInternal.PACKAGE_SYSTEM:
                 return new String[]{"android"};
             case PackageManagerInternal.PACKAGE_VERIFIER:
-                return mComputer.filterOnlySystemPackages(mRequiredVerifierPackage);
+                return snapshot.filterOnlySystemPackages(mRequiredVerifierPackage);
             case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
-                return mComputer.filterOnlySystemPackages(
+                return snapshot.filterOnlySystemPackages(
                         mDefaultTextClassifierPackage, mSystemTextClassifierPackageName);
             case PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER:
-                return mComputer.filterOnlySystemPackages(mRequiredPermissionControllerPackage);
+                return snapshot.filterOnlySystemPackages(mRequiredPermissionControllerPackage);
             case PackageManagerInternal.PACKAGE_CONFIGURATOR:
-                return mComputer.filterOnlySystemPackages(mConfiguratorPackage);
+                return snapshot.filterOnlySystemPackages(mConfiguratorPackage);
             case PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER:
-                return mComputer.filterOnlySystemPackages(mIncidentReportApproverPackage);
+                return snapshot.filterOnlySystemPackages(mIncidentReportApproverPackage);
             case PackageManagerInternal.PACKAGE_AMBIENT_CONTEXT_DETECTION:
-                return mComputer.filterOnlySystemPackages(mAmbientContextDetectionPackage);
+                return snapshot.filterOnlySystemPackages(mAmbientContextDetectionPackage);
             case PackageManagerInternal.PACKAGE_APP_PREDICTOR:
-                return mComputer.filterOnlySystemPackages(mAppPredictionServicePackage);
+                return snapshot.filterOnlySystemPackages(mAppPredictionServicePackage);
             case PackageManagerInternal.PACKAGE_COMPANION:
-                return mComputer.filterOnlySystemPackages(COMPANION_PACKAGE_NAME);
+                return snapshot.filterOnlySystemPackages(COMPANION_PACKAGE_NAME);
             case PackageManagerInternal.PACKAGE_RETAIL_DEMO:
                 return TextUtils.isEmpty(mRetailDemoPackage)
                         ? ArrayUtils.emptyArray(String.class)
                         : new String[] {mRetailDemoPackage};
             case PackageManagerInternal.PACKAGE_OVERLAY_CONFIG_SIGNATURE:
-                return mComputer.filterOnlySystemPackages(getOverlayConfigSignaturePackageName());
+                return snapshot.filterOnlySystemPackages(mOverlayConfigSignaturePackage);
             case PackageManagerInternal.PACKAGE_RECENTS:
-                return mComputer.filterOnlySystemPackages(mRecentsPackage);
+                return snapshot.filterOnlySystemPackages(mRecentsPackage);
             default:
                 return ArrayUtils.emptyArray(String.class);
         }
@@ -8557,10 +7000,6 @@
         mDefaultAppProvider.setDefaultBrowser(packageName, async, userId);
     }
 
-    ResolveInfo getInstantAppInstallerInfo() {
-        return mInstantAppInstallerInfo;
-    }
-
     PackageUsage getPackageUsage() {
         return mPackageUsage;
     }
@@ -8652,10 +7091,6 @@
         }
     }
 
-    ResolveInfo getResolveInfo() {
-        return mResolveInfo;
-    }
-
     ApplicationInfo getCoreAndroidApplication() {
         return mAndroidApplication;
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 8d3fbf7..2a1a990 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -850,6 +850,8 @@
         ret.recommendedInstallLocation = recommendedInstallLocation;
         ret.multiArch = pkg.isMultiArch();
         ret.debuggable = pkg.isDebuggable();
+        ret.isSdkLibrary = pkg.isIsSdkLibrary();
+
         return ret;
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 500b4ec..15753cd2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -131,6 +131,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.WeakHashMap;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
@@ -144,6 +145,10 @@
     private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
     private static final int DEFAULT_STAGED_READY_TIMEOUT_MS = 60 * 1000;
     private static final String TAG = "PackageManagerShellCommand";
+    private static final Set<String> UNSUPPORTED_INSTALL_CMD_OPTS = Set.of(
+            "--multi-package"
+    );
+    private static final Set<String> UNSUPPORTED_SESSION_CREATE_OPTS = Collections.emptySet();
 
     final IPackageManager mInterface;
     final LegacyPermissionManagerInternal mLegacyPermissionManager;
@@ -159,9 +164,9 @@
 
     private static final SecureRandom RANDOM = new SecureRandom();
 
-    PackageManagerShellCommand(@NonNull PackageManagerService service,
+    PackageManagerShellCommand(@NonNull IPackageManager packageManager,
             @NonNull Context context, @NonNull DomainVerificationShell domainVerificationShell) {
-        mInterface = service;
+        mInterface = packageManager;
         mLegacyPermissionManager = LocalServices.getService(LegacyPermissionManagerInternal.class);
         mPermissionManager = context.getSystemService(PermissionManager.class);
         mContext = context;
@@ -1330,7 +1335,7 @@
     }
 
     private int runStreamingInstall() throws RemoteException {
-        final InstallParams params = makeInstallParams();
+        final InstallParams params = makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS);
         if (params.sessionParams.dataLoaderParams == null) {
             params.sessionParams.setDataLoaderParams(
                     PackageManagerShellCommandDataLoader.getStreamingDataLoaderParams(this));
@@ -1339,7 +1344,7 @@
     }
 
     private int runIncrementalInstall() throws RemoteException {
-        final InstallParams params = makeInstallParams();
+        final InstallParams params = makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS);
         if (params.sessionParams.dataLoaderParams == null) {
             params.sessionParams.setDataLoaderParams(
                     PackageManagerShellCommandDataLoader.getIncrementalDataLoaderParams(this));
@@ -1348,7 +1353,7 @@
     }
 
     private int runInstall() throws RemoteException {
-        return doRunInstall(makeInstallParams());
+        return doRunInstall(makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS));
     }
 
     private int doRunInstall(final InstallParams params) throws RemoteException {
@@ -1500,7 +1505,7 @@
 
     private int runInstallCreate() throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
-        final InstallParams installParams = makeInstallParams();
+        final InstallParams installParams = makeInstallParams(UNSUPPORTED_SESSION_CREATE_OPTS);
         final int sessionId = doCreateSession(installParams.sessionParams,
                 installParams.installerPackageName, installParams.userId);
 
@@ -2535,8 +2540,10 @@
             privAppPermissions = SystemConfig.getInstance()
                     .getSystemExtPrivAppPermissions(pkg);
         } else if (isApexApp(pkg)) {
+            final String apexName = ApexManager.getInstance().getApexModuleNameForPackageName(
+                    getApexPackageNameContainingPackage(pkg));
             privAppPermissions = SystemConfig.getInstance()
-                    .getApexPrivAppPermissions(getApexPackageNameContainingPackage(pkg), pkg);
+                    .getApexPrivAppPermissions(apexName, pkg);
         } else {
             privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
         }
@@ -2562,8 +2569,10 @@
             privAppPermissions = SystemConfig.getInstance()
                     .getSystemExtPrivAppDenyPermissions(pkg);
         } else if (isApexApp(pkg)) {
+            final String apexName = ApexManager.getInstance().getApexModuleNameForPackageName(
+                    getApexPackageNameContainingPackage(pkg));
             privAppPermissions = SystemConfig.getInstance()
-                    .getApexPrivAppDenyPermissions(getApexPackageNameContainingPackage(pkg), pkg);
+                    .getApexPrivAppDenyPermissions(apexName, pkg);
         } else {
             privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
         }
@@ -2896,7 +2905,7 @@
         long stagedReadyTimeoutMs = DEFAULT_STAGED_READY_TIMEOUT_MS;
     }
 
-    private InstallParams makeInstallParams() {
+    private InstallParams makeInstallParams(Set<String> unsupportedOptions) {
         final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
         final InstallParams params = new InstallParams();
 
@@ -2910,6 +2919,9 @@
         boolean replaceExisting = true;
         boolean forceNonStaged = false;
         while ((opt = getNextOption()) != null) {
+            if (unsupportedOptions.contains(opt)) {
+                throw new IllegalArgumentException("Unsupported option " + opt);
+            }
             switch (opt) {
                 case "-r": // ignore
                     break;
@@ -3817,7 +3829,7 @@
         pw.println("       [--user USER_ID] INTENT");
         pw.println("    Prints all broadcast receivers that can handle the given INTENT.");
         pw.println("");
-        pw.println("  install [-rtfdgw] [-i PACKAGE] [--user USER_ID|all|current]");
+        pw.println("  install [-rtfdg] [-i PACKAGE] [--user USER_ID|all|current]");
         pw.println("       [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
         pw.println("       [--install-reason 0/1/2/3/4] [--originating-uri URI]");
         pw.println("       [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
diff --git a/services/core/java/com/android/server/pm/PackageRemovedInfo.java b/services/core/java/com/android/server/pm/PackageRemovedInfo.java
index fdad833..28ad4b6 100644
--- a/services/core/java/com/android/server/pm/PackageRemovedInfo.java
+++ b/services/core/java/com/android/server/pm/PackageRemovedInfo.java
@@ -38,8 +38,6 @@
     String mInstallerPackageName;
     int mUid = -1;
     int mRemovedAppId = -1;
-    // If not -1, the app is going through an appId change
-    int mNewAppId = -1;
     int[] mOrigUsers;
     int[] mRemovedUsers = null;
     int[] mBroadcastUsers = null;
@@ -67,22 +65,16 @@
         sendPackageRemovedBroadcastInternal(killApp, removedBySystem);
     }
 
-    void sendSystemPackageUpdatedBroadcasts(int newAppId) {
+    void sendSystemPackageUpdatedBroadcasts() {
         if (mIsRemovedPackageSystemUpdate) {
-            sendSystemPackageUpdatedBroadcastsInternal(newAppId);
+            sendSystemPackageUpdatedBroadcastsInternal();
         }
     }
 
-    private void sendSystemPackageUpdatedBroadcastsInternal(int newAppId) {
+    private void sendSystemPackageUpdatedBroadcastsInternal() {
         Bundle extras = new Bundle(2);
-        extras.putInt(Intent.EXTRA_UID, newAppId);
-        // When appId changes, do not set the replacing extra
-        if (mNewAppId >= 0) {
-            extras.putBoolean(Intent.EXTRA_UID_CHANGING, true);
-            extras.putInt(Intent.EXTRA_PREVIOUS_UID, mRemovedAppId >= 0 ? mRemovedAppId : mUid);
-        } else {
-            extras.putBoolean(Intent.EXTRA_REPLACING, true);
-        }
+        extras.putInt(Intent.EXTRA_UID, mRemovedAppId >= 0 ? mRemovedAppId : mUid);
+        extras.putBoolean(Intent.EXTRA_REPLACING, true);
         mPackageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, mRemovedPackage, extras,
                 0, null /*targetPackage*/, null, null, null, mBroadcastAllowList, null);
         if (mInstallerPackageName != null) {
@@ -90,17 +82,13 @@
                     mRemovedPackage, extras, 0 /*flags*/,
                     mInstallerPackageName, null, null, null, null /* broadcastAllowList */,
                     null);
+            mPackageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
+                    mRemovedPackage, extras, 0 /*flags*/,
+                    mInstallerPackageName, null, null, null, null /* broadcastAllowList */,
+                    null);
         }
-        if (mNewAppId < 0) {
-            mPackageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, mRemovedPackage,
-                    extras, 0, null /*targetPackage*/, null, null, null, mBroadcastAllowList, null);
-            if (mInstallerPackageName != null) {
-                mPackageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
-                        mRemovedPackage, extras, 0 /*flags*/,
-                        mInstallerPackageName, null, null, null, null /* broadcastAllowList */,
-                        null);
-            }
-        }
+        mPackageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, mRemovedPackage,
+                extras, 0, null /*targetPackage*/, null, null, null, mBroadcastAllowList, null);
         mPackageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, null, 0,
                 mRemovedPackage, null, null, null, null /* broadcastAllowList */,
                 getTemporaryAppAllowlistBroadcastOptions(REASON_PACKAGE_REPLACED).toBundle());
@@ -134,15 +122,10 @@
         extras.putBoolean(Intent.EXTRA_DATA_REMOVED, mDataRemoved);
         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
         extras.putBoolean(Intent.EXTRA_USER_INITIATED, !removedBySystem);
-
-        // When appId changes, do not set the replacing extra
-        if (mNewAppId >= 0) {
-            extras.putBoolean(Intent.EXTRA_UID_CHANGING, true);
-            extras.putInt(Intent.EXTRA_NEW_UID, mNewAppId);
-        } else if (mIsUpdate || mIsRemovedPackageSystemUpdate) {
+        final boolean isReplace = mIsUpdate || mIsRemovedPackageSystemUpdate;
+        if (isReplace) {
             extras.putBoolean(Intent.EXTRA_REPLACING, true);
         }
-
         extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, mRemovedForAllUsers);
         if (mRemovedPackage != null) {
             mPackageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
@@ -165,9 +148,9 @@
             }
         }
         if (mRemovedAppId >= 0) {
-            // If the package is not actually removed, some services need to know the
-            // package name affected.
-            if (mNewAppId >= 0 || mIsUpdate || mIsRemovedPackageSystemUpdate) {
+            // If a system app's updates are uninstalled the UID is not actually removed. Some
+            // services need to know the package name affected.
+            if (isReplace) {
                 extras.putString(Intent.EXTRA_PACKAGE_NAME, mRemovedPackage);
             }
 
diff --git a/services/core/java/com/android/server/pm/PackageSender.java b/services/core/java/com/android/server/pm/PackageSender.java
index d380098..656d596 100644
--- a/services/core/java/com/android/server/pm/PackageSender.java
+++ b/services/core/java/com/android/server/pm/PackageSender.java
@@ -16,6 +16,7 @@
 
 package com.android.server.pm;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.IIntentReceiver;
 import android.os.Bundle;
@@ -30,9 +31,9 @@
             Bundle extras, int flags, String targetPkg,
             IIntentReceiver finishedReceiver, int[] userIds, int[] instantUserIds,
             @Nullable SparseArray<int[]> broadcastAllowList, @Nullable Bundle bOptions);
-    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
-            boolean includeStopped, int appId, int[] userIds, int[] instantUserIds,
-            int dataLoaderType);
+    void sendPackageAddedForNewUsers(@NonNull Computer snapshot, String packageName,
+            boolean sendBootCompleted, boolean includeStopped, int appId, int[] userIds,
+            int[] instantUserIds, int dataLoaderType);
     void notifyPackageAdded(String packageName, int uid);
     void notifyPackageChanged(String packageName, int uid);
     void notifyPackageRemoved(String packageName, int uid);
diff --git a/services/core/java/com/android/server/pm/PackageSessionVerifier.java b/services/core/java/com/android/server/pm/PackageSessionVerifier.java
index 6b57deb..2016fc3 100644
--- a/services/core/java/com/android/server/pm/PackageSessionVerifier.java
+++ b/services/core/java/com/android/server/pm/PackageSessionVerifier.java
@@ -24,7 +24,6 @@
 import android.content.Intent;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.PackageInfo;
-import android.content.pm.PackageInstaller.SessionInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.SigningDetails;
@@ -110,7 +109,7 @@
                 verifyAPK(session, callback);
             } catch (PackageManagerException e) {
                 String errorMessage = PackageManager.installStatusToString(e.error, e.getMessage());
-                session.setSessionFailed(SessionInfo.SESSION_VERIFICATION_FAILED, errorMessage);
+                session.setSessionFailed(e.error, errorMessage);
                 callback.onResult(e.error, e.getMessage());
             }
         });
@@ -137,7 +136,7 @@
                 }
                 if (returnCode != PackageManager.INSTALL_SUCCEEDED) {
                     String errorMessage = PackageManager.installStatusToString(returnCode, msg);
-                    session.setSessionFailed(SessionInfo.SESSION_VERIFICATION_FAILED, errorMessage);
+                    session.setSessionFailed(returnCode, errorMessage);
                     callback.onResult(returnCode, msg);
                 } else {
                     session.setSessionReady();
@@ -220,7 +219,7 @@
     }
 
     private void onVerificationFailure(StagingManager.StagedSession session, Callback callback,
-            @SessionInfo.SessionErrorCode int errorCode, String errorMessage) {
+            int errorCode, String errorMessage) {
         if (!ensureActiveApexSessionIsAborted(session)) {
             Slog.e(TAG, "Failed to abort apex session " + session.sessionId());
             // Safe to ignore active apex session abortion failure since session will be marked
@@ -312,7 +311,7 @@
             // Failed to get hold of StorageManager
             Slog.e(TAG, "Failed to get hold of StorageManager", e);
             throw new PackageManagerException(
-                    SessionInfo.SESSION_UNKNOWN_ERROR,
+                    PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
                     "Failed to get hold of StorageManager");
         }
         // Proactively mark session as ready before calling apexd. Although this call order
@@ -350,7 +349,7 @@
         final ParseResult<SigningDetails> newResult = ApkSignatureVerifier.verify(
                 input.reset(), apexPath, minSignatureScheme);
         if (newResult.isError()) {
-            throw new PackageManagerException(SessionInfo.SESSION_VERIFICATION_FAILED,
+            throw new PackageManagerException(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
                     "Failed to parse APEX package " + apexPath + " : "
                             + newResult.getException(), newResult.getException());
         }
@@ -369,7 +368,7 @@
                 input.reset(), existingApexPkg.applicationInfo.sourceDir,
                 SigningDetails.SignatureSchemeVersion.JAR);
         if (existingResult.isError()) {
-            throw new PackageManagerException(SessionInfo.SESSION_VERIFICATION_FAILED,
+            throw new PackageManagerException(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
                     "Failed to parse APEX package " + existingApexPkg.applicationInfo.sourceDir
                             + " : " + existingResult.getException(), existingResult.getException());
         }
@@ -383,7 +382,7 @@
             return;
         }
 
-        throw new PackageManagerException(SessionInfo.SESSION_VERIFICATION_FAILED,
+        throw new PackageManagerException(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
                 "APK-container signature of APEX package " + packageName + " with version "
                         + newApexPkg.versionCodeMajor + " and path " + apexPath + " is not"
                         + " compatible with the one currently installed on device");
@@ -426,11 +425,12 @@
                 packageInfo = PackageInfoWithoutStateUtils.generate(parsedPackage, apexInfo, flags);
                 if (packageInfo == null) {
                     throw new PackageManagerException(
-                            SessionInfo.SESSION_VERIFICATION_FAILED,
+                            PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
                             "Unable to generate package info: " + apexInfo.modulePath);
                 }
             } catch (PackageManagerException e) {
-                throw new PackageManagerException(SessionInfo.SESSION_VERIFICATION_FAILED,
+                throw new PackageManagerException(
+                        PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
                         "Failed to parse APEX package " + apexInfo.modulePath + " : " + e, e);
             }
             result.add(packageInfo);
@@ -452,7 +452,7 @@
             }
         }
         throw new PackageManagerException(
-                SessionInfo.SESSION_VERIFICATION_FAILED,
+                PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
                 "Could not find rollback id for commit session: " + sessionId);
     }
 
@@ -560,7 +560,7 @@
         try {
             checkActiveSessions(InstallLocationUtils.getStorageManager().supportsCheckpoint());
         } catch (RemoteException e) {
-            throw new PackageManagerException(SessionInfo.SESSION_VERIFICATION_FAILED,
+            throw new PackageManagerException(PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
                     "Can't query fs-checkpoint status : " + e);
         }
     }
@@ -576,7 +576,7 @@
         }
         if (!supportsCheckpoint && activeSessions > 1) {
             throw new PackageManagerException(
-                    SessionInfo.SESSION_VERIFICATION_FAILED,
+                    PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
                     "Cannot stage multiple sessions without checkpoint support");
         }
     }
@@ -607,13 +607,13 @@
                     // will be deleted.
                 }
                 stagedSession.setSessionFailed(
-                        SessionInfo.SESSION_CONFLICT,
+                        PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
                         "Session was failed by rollback session: " + session.sessionId());
                 Slog.i(TAG, "Session " + stagedSession.sessionId() + " is marked failed due to "
                         + "rollback session: " + session.sessionId());
             } else if (!isRollback(session) && isRollback(stagedSession)) {
                 throw new PackageManagerException(
-                        SessionInfo.SESSION_CONFLICT,
+                        PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
                         "Session was failed by rollback session: " + stagedSession.sessionId());
 
             }
@@ -636,7 +636,7 @@
         final String packageName = child.getPackageName();
         if (packageName == null) {
             throw new PackageManagerException(
-                    SessionInfo.SESSION_VERIFICATION_FAILED,
+                    PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
                     "Cannot stage session " + child.sessionId() + " with package name null");
         }
         for (StagingManager.StagedSession stagedSession : mStagedSessions) {
@@ -648,14 +648,14 @@
                 if (stagedSession.getCommittedMillis() < parent.getCommittedMillis()) {
                     // Fail the session committed later when there are overlapping packages
                     throw new PackageManagerException(
-                            SessionInfo.SESSION_VERIFICATION_FAILED,
+                            PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
                             "Package: " + packageName + " in session: "
                                     + child.sessionId()
                                     + " has been staged already by session: "
                                     + stagedSession.sessionId());
                 } else {
                     stagedSession.setSessionFailed(
-                            SessionInfo.SESSION_VERIFICATION_FAILED,
+                            PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
                             "Package: " + packageName + " in session: "
                                     + stagedSession.sessionId()
                                     + " has been staged already by session: "
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index f06ae1e..2bae00f 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -477,6 +477,7 @@
 
     public void setSharedUserAppId(int sharedUserAppId) {
         mSharedUserAppId = sharedUserAppId;
+        onChanged();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/PreferredActivityHelper.java b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
index 8c49baf..9befd6e 100644
--- a/services/core/java/com/android/server/pm/PreferredActivityHelper.java
+++ b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
@@ -25,6 +25,7 @@
 import static com.android.server.pm.PackageManagerService.TAG;
 
 import android.annotation.NonNull;
+import android.annotation.UserIdInt;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -74,17 +75,18 @@
         mPm = pm;
     }
 
-    private ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType,
-            @PackageManager.ResolveInfoFlagsBits long flags, List<ResolveInfo> query,
-            boolean always, boolean removeMatches, boolean debug, int userId) {
-        return findPreferredActivityNotLocked(
-                intent, resolvedType, flags, query, always, removeMatches, debug, userId,
+    private ResolveInfo findPreferredActivityNotLocked(@NonNull Computer snapshot, Intent intent,
+            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
+            List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug,
+            @UserIdInt int userId) {
+        return findPreferredActivityNotLocked(snapshot, intent, resolvedType, flags, query, always,
+                removeMatches, debug, userId,
                 UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID);
     }
 
     // TODO: handle preferred activities missing while user has amnesia
     /** <b>must not hold {@link PackageManagerService.mLock}</b> */
-    public ResolveInfo findPreferredActivityNotLocked(
+    public ResolveInfo findPreferredActivityNotLocked(@NonNull Computer snapshot,
             Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
             List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug,
             int userId, boolean queryMayBeFiltered) {
@@ -95,7 +97,7 @@
         if (!mPm.mUserManager.exists(userId)) return null;
 
         PackageManagerService.FindPreferredActivityBodyResult body =
-                mPm.findPreferredActivityInternal(
+                snapshot.findPreferredActivityInternal(
                 intent, resolvedType, flags, query, always,
                 removeMatches, debug, userId, queryMayBeFiltered);
         if (body.mChanged) {
@@ -117,7 +119,7 @@
             mPm.clearPackagePreferredActivitiesLPw(packageName, changedUsers, userId);
         }
         if (changedUsers.size() > 0) {
-            updateDefaultHomeNotLocked(changedUsers);
+            updateDefaultHomeNotLocked(mPm.snapshotComputer(), changedUsers);
             mPm.postPreferredActivityChangedBroadcast(userId);
             mPm.scheduleWritePackageRestrictions(userId);
         }
@@ -128,7 +130,7 @@
      *
      * @return Whether the ACTION_PREFERRED_ACTIVITY_CHANGED broadcast has been scheduled.
      */
-    public boolean updateDefaultHomeNotLocked(int userId) {
+    public boolean updateDefaultHomeNotLocked(@NonNull Computer snapshot, @UserIdInt int userId) {
         if (Thread.holdsLock(mPm.mLock)) {
             Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
                     + " is holding mLock", new Throwable());
@@ -139,10 +141,10 @@
             // before that.
             return false;
         }
-        final Intent intent = mPm.getHomeIntent();
-        final List<ResolveInfo> resolveInfos = mPm.snapshotComputer().queryIntentActivitiesInternal(
+        final Intent intent = snapshot.getHomeIntent();
+        final List<ResolveInfo> resolveInfos = snapshot.queryIntentActivitiesInternal(
                 intent, null, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
-        final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
+        final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(snapshot,
                 intent, null, 0, resolveInfos, true, false, false, userId);
         final String packageName = preferredResolveInfo != null
                 && preferredResolveInfo.activityInfo != null
@@ -151,7 +153,7 @@
         if (TextUtils.equals(currentPackageName, packageName)) {
             return false;
         }
-        final String[] callingPackages = mPm.getPackagesForUid(Binder.getCallingUid());
+        final String[] callingPackages = snapshot.getPackagesForUid(Binder.getCallingUid());
         if (callingPackages != null && ArrayUtils.contains(callingPackages,
                 mPm.mRequiredPermissionControllerPackage)) {
             // PermissionController manages default home directly.
@@ -173,23 +175,21 @@
     /**
      * Variant that takes a {@link WatchedIntentFilter}
      */
-    public void addPreferredActivity(WatchedIntentFilter filter, int match,
-            ComponentName[] set, ComponentName activity, boolean always, int userId,
+    public void addPreferredActivity(@NonNull Computer snapshot, WatchedIntentFilter filter,
+            int match, ComponentName[] set, ComponentName activity, boolean always, int userId,
             String opname, boolean removeExisting) {
         // writer
         int callingUid = Binder.getCallingUid();
-        mPm.enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
+        snapshot.enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
                 false /* checkShell */, "add preferred activity");
         if (mPm.mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
                 != PackageManager.PERMISSION_GRANTED) {
-            synchronized (mPm.mLock) {
-                if (mPm.getUidTargetSdkVersion(callingUid)
-                        < Build.VERSION_CODES.FROYO) {
-                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
-                            + callingUid);
-                    return;
-                }
+            if (snapshot.getUidTargetSdkVersion(callingUid)
+                    < Build.VERSION_CODES.FROYO) {
+                Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
+                        + callingUid);
+                return;
             }
             mPm.mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
@@ -213,7 +213,8 @@
                     new PreferredActivity(filter, match, set, activity, always));
             mPm.scheduleWritePackageRestrictions(userId);
         }
-        if (!(isHomeFilter(filter) && updateDefaultHomeNotLocked(userId))) {
+        // Re-snapshot after mLock
+        if (!(isHomeFilter(filter) && updateDefaultHomeNotLocked(mPm.snapshotComputer(), userId))) {
             mPm.postPreferredActivityChangedBroadcast(userId);
         }
     }
@@ -221,8 +222,8 @@
     /**
      * Variant that takes a {@link WatchedIntentFilter}
      */
-    public void replacePreferredActivity(WatchedIntentFilter filter, int match,
-            ComponentName[] set, ComponentName activity, int userId) {
+    public void replacePreferredActivity(@NonNull Computer snapshot, WatchedIntentFilter filter,
+            int match, ComponentName[] set, ComponentName activity, int userId) {
         if (filter.countActions() != 1) {
             throw new IllegalArgumentException(
                     "replacePreferredActivity expects filter to have only 1 action.");
@@ -237,13 +238,14 @@
         }
 
         final int callingUid = Binder.getCallingUid();
-        mPm.enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
+        snapshot.enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
                 false /* checkShell */, "replace preferred activity");
         if (mPm.mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
                 != PackageManager.PERMISSION_GRANTED) {
             synchronized (mPm.mLock) {
-                if (mPm.getUidTargetSdkVersion(callingUid)
+                // TODO: Remove lock?
+                if (mPm.snapshotComputer().getUidTargetSdkVersion(callingUid)
                         < Build.VERSION_CODES.FROYO) {
                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
                             + Binder.getCallingUid());
@@ -295,21 +297,23 @@
                 }
             }
         }
-        addPreferredActivity(filter, match, set, activity, true, userId,
+
+        // Retake a snapshot after editing with lock held
+        addPreferredActivity(mPm.snapshotComputer(), filter, match, set, activity, true, userId,
                 "Replacing preferred", false);
     }
 
-    public void clearPackagePreferredActivities(String packageName) {
+    public void clearPackagePreferredActivities(@NonNull Computer snapshot, String packageName) {
         final int callingUid = Binder.getCallingUid();
-        if (mPm.getInstantAppPackageName(callingUid) != null) {
+        if (snapshot.getInstantAppPackageName(callingUid) != null) {
             return;
         }
-        final PackageStateInternal packageState = mPm.getPackageStateInternal(packageName);
-        if (packageState == null || !mPm.isCallerSameApp(packageName, callingUid)) {
+        final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
+        if (packageState == null || !snapshot.isCallerSameApp(packageName, callingUid)) {
             if (mPm.mContext.checkCallingOrSelfPermission(
                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
                     != PackageManager.PERMISSION_GRANTED) {
-                if (mPm.getUidTargetSdkVersion(callingUid)
+                if (snapshot.getUidTargetSdkVersion(callingUid)
                         < Build.VERSION_CODES.FROYO) {
                     Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
                             + callingUid);
@@ -319,7 +323,7 @@
                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
             }
         }
-        if (packageState != null && mPm.shouldFilterApplication(packageState, callingUid,
+        if (packageState != null && snapshot.shouldFilterApplication(packageState, callingUid,
                 UserHandle.getUserId(callingUid))) {
             return;
         }
@@ -328,23 +332,23 @@
     }
 
     /** <b>must not hold {@link #PackageManagerService.mLock}</b> */
-    void updateDefaultHomeNotLocked(SparseBooleanArray userIds) {
+    void updateDefaultHomeNotLocked(@NonNull Computer snapshot, SparseBooleanArray userIds) {
         if (Thread.holdsLock(mPm.mLock)) {
             Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
                     + " is holding mLock", new Throwable());
         }
         for (int i = userIds.size() - 1; i >= 0; --i) {
             final int userId = userIds.keyAt(i);
-            updateDefaultHomeNotLocked(userId);
+            updateDefaultHomeNotLocked(snapshot, userId);
         }
     }
 
-    public void setHomeActivity(ComponentName comp, int userId) {
-        if (mPm.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+    public void setHomeActivity(@NonNull Computer snapshot, ComponentName comp, int userId) {
+        if (snapshot.getInstantAppPackageName(Binder.getCallingUid()) != null) {
             return;
         }
         ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
-        mPm.getHomeActivitiesAsUser(homeActivities, userId);
+        snapshot.getHomeActivitiesAsUser(homeActivities, userId);
 
         boolean found = false;
 
@@ -363,7 +367,7 @@
             throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
                     + userId);
         }
-        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
+        replacePreferredActivity(snapshot, getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
                 set, comp, userId);
     }
 
@@ -400,7 +404,7 @@
             mPm.scheduleWritePackageRestrictions(userId);
         }
         if (isHomeFilter(filter)) {
-            updateDefaultHomeNotLocked(userId);
+            updateDefaultHomeNotLocked(mPm.snapshotComputer(), userId);
         }
         mPm.postPreferredActivityChangedBroadcast(userId);
     }
@@ -416,7 +420,7 @@
             changed = mPm.mSettings.clearPackagePersistentPreferredActivities(packageName, userId);
         }
         if (changed) {
-            updateDefaultHomeNotLocked(userId);
+            updateDefaultHomeNotLocked(mPm.snapshotComputer(), userId);
             mPm.postPreferredActivityChangedBroadcast(userId);
             mPm.scheduleWritePackageRestrictions(userId);
         }
@@ -505,7 +509,7 @@
                         synchronized (mPm.mLock) {
                             mPm.mSettings.readPreferredActivitiesLPw(readParser, readUserId);
                         }
-                        updateDefaultHomeNotLocked(readUserId);
+                        updateDefaultHomeNotLocked(mPm.snapshotComputer(), readUserId);
                     });
         } catch (Exception e) {
             if (DEBUG_BACKUP) {
@@ -597,7 +601,7 @@
                     mPm.mPermissionManager.resetRuntimePermissions(pkg, userId);
                 }
             }
-            updateDefaultHomeNotLocked(userId);
+            updateDefaultHomeNotLocked(mPm.snapshotComputer(), userId);
             resetNetworkPolicies(userId);
             mPm.scheduleWritePackageRestrictions(userId);
         } finally {
@@ -609,12 +613,11 @@
         mPm.mInjector.getLocalService(NetworkPolicyManagerInternal.class).resetUserState(userId);
     }
 
-    // TODO: This method should not touch the Computer directly
-    public int getPreferredActivities(List<IntentFilter> outFilters,
-            List<ComponentName> outActivities, String packageName, Computer computer) {
+    public int getPreferredActivities(@NonNull Computer snapshot, List<IntentFilter> outFilters,
+            List<ComponentName> outActivities, String packageName) {
         List<WatchedIntentFilter> temp =
                 WatchedIntentFilter.toWatchedIntentFilterList(outFilters);
-        int result = getPreferredActivitiesInternal(temp, outActivities, packageName, computer);
+        int result = getPreferredActivitiesInternal(snapshot, temp, outActivities, packageName);
         outFilters.clear();
         for (int i = 0; i < temp.size(); i++) {
             outFilters.add(temp.get(i).getIntentFilter());
@@ -625,16 +628,17 @@
     /**
      * Variant that takes a {@link WatchedIntentFilter}
      */
-    private int getPreferredActivitiesInternal(List<WatchedIntentFilter> outFilters,
-            List<ComponentName> outActivities, String packageName, Computer computer) {
+    private int getPreferredActivitiesInternal(@NonNull Computer snapshot,
+            List<WatchedIntentFilter> outFilters, List<ComponentName> outActivities,
+            String packageName) {
         final int callingUid = Binder.getCallingUid();
-        if (mPm.getInstantAppPackageName(callingUid) != null) {
+        if (snapshot.getInstantAppPackageName(callingUid) != null) {
             return 0;
         }
         int num = 0;
         final int userId = UserHandle.getCallingUserId();
 
-        PreferredIntentResolver pir = computer.getPreferredActivities(userId);
+        PreferredIntentResolver pir = snapshot.getPreferredActivities(userId);
         if (pir != null) {
             final Iterator<PreferredActivity> it = pir.filterIterator();
             while (it.hasNext()) {
@@ -642,8 +646,9 @@
                 final String prefPackageName = pa.mPref.mComponent.getPackageName();
                 if (packageName == null
                         || (prefPackageName.equals(packageName) && pa.mPref.mAlways)) {
-                    if (mPm.shouldFilterApplication(
-                            mPm.getPackageStateInternal(prefPackageName), callingUid, userId)) {
+                    if (snapshot.shouldFilterApplication(
+                            snapshot.getPackageStateInternal(prefPackageName), callingUid,
+                            userId)) {
                         continue;
                     }
                     if (outFilters != null) {
@@ -659,7 +664,8 @@
         return num;
     }
 
-    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
+    public ResolveInfo findPersistentPreferredActivity(@NonNull Computer snapshot, Intent intent,
+            int userId) {
         if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
             throw new SecurityException(
                     "findPersistentPreferredActivity can only be run by the system");
@@ -670,24 +676,23 @@
         final int callingUid = Binder.getCallingUid();
         intent = PackageManagerServiceUtils.updateIntentForResolve(intent);
         final String resolvedType = intent.resolveTypeIfNeeded(mPm.mContext.getContentResolver());
-        final long flags = mPm.updateFlagsForResolve(
+        final long flags = snapshot.updateFlagsForResolve(
                 0, userId, callingUid, false /*includeInstantApps*/,
-                mPm.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
+                snapshot.isImplicitImageCaptureIntentAndNotSetByDpc(intent, userId, resolvedType,
                         0));
-        final List<ResolveInfo> query = mPm.snapshotComputer().queryIntentActivitiesInternal(intent,
+        final List<ResolveInfo> query = snapshot.queryIntentActivitiesInternal(intent,
                 resolvedType, flags, userId);
-        synchronized (mPm.mLock) {
-            return mPm.findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
-                    userId);
-        }
+        return snapshot.findPersistentPreferredActivity(intent, resolvedType, flags, query, false,
+                userId);
     }
 
     /**
      * Variant that takes a {@link WatchedIntentFilter}
      */
-    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
-            WatchedIntentFilter filter, int match, ComponentName activity) {
-        if (mPm.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+    public void setLastChosenActivity(@NonNull Computer snapshot, Intent intent,
+            String resolvedType, int flags, WatchedIntentFilter filter, int match,
+            ComponentName activity) {
+        if (snapshot.getInstantAppPackageName(Binder.getCallingUid()) != null) {
             return;
         }
         final int userId = UserHandle.getCallingUserId();
@@ -701,25 +706,26 @@
             filter.dump(new PrintStreamPrinter(System.out), "    ");
         }
         intent.setComponent(null);
-        final List<ResolveInfo> query = mPm.snapshotComputer().queryIntentActivitiesInternal(intent,
+        final List<ResolveInfo> query = snapshot.queryIntentActivitiesInternal(intent,
                 resolvedType, flags, userId);
         // Find any earlier preferred or last chosen entries and nuke them
-        findPreferredActivityNotLocked(
-                intent, resolvedType, flags, query, false, true, false, userId);
+        findPreferredActivityNotLocked(snapshot, intent, resolvedType, flags, query, false, true,
+                false, userId);
         // Add the new activity as the last chosen for this filter
-        addPreferredActivity(filter, match, null, activity, false, userId,
+        addPreferredActivity(snapshot, filter, match, null, activity, false, userId,
                 "Setting last chosen", false);
     }
 
-    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
-        if (mPm.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+    public ResolveInfo getLastChosenActivity(@NonNull Computer snapshot, Intent intent,
+            String resolvedType, int flags) {
+        if (snapshot.getInstantAppPackageName(Binder.getCallingUid()) != null) {
             return null;
         }
         final int userId = UserHandle.getCallingUserId();
         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
-        final List<ResolveInfo> query = mPm.snapshotComputer().queryIntentActivitiesInternal(intent,
+        final List<ResolveInfo> query = snapshot.queryIntentActivitiesInternal(intent,
                 resolvedType, flags, userId);
-        return findPreferredActivityNotLocked(
-                intent, resolvedType, flags, query, false, false, false, userId);
+        return findPreferredActivityNotLocked(snapshot, intent, resolvedType, flags, query, false,
+                false, false, userId);
     }
 }
diff --git a/services/core/java/com/android/server/pm/PreferredComponent.java b/services/core/java/com/android/server/pm/PreferredComponent.java
index 4ec042f..2a1ca2c 100644
--- a/services/core/java/com/android/server/pm/PreferredComponent.java
+++ b/services/core/java/com/android/server/pm/PreferredComponent.java
@@ -57,7 +57,6 @@
     private String mParseError;
 
     private final Callbacks mCallbacks;
-    private final String mSetupWizardPackageName;
 
     public interface Callbacks {
         public boolean onReadTag(String tagName, TypedXmlPullParser parser)
@@ -72,7 +71,6 @@
         mAlways = always;
         mShortComponent = component.flattenToShortString();
         mParseError = null;
-        mSetupWizardPackageName = null;
         if (set != null) {
             final int N = set.length;
             String[] myPackages = new String[N];
@@ -174,8 +172,6 @@
         mSetPackages = myPackages;
         mSetClasses = myClasses;
         mSetComponents = myComponents;
-        final PackageManagerInternal packageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
-        mSetupWizardPackageName = packageManagerInternal.getSetupWizardPackageName();
     }
 
     public String getParseError() {
@@ -209,6 +205,7 @@
         final int NQ = query.size();
         final int NS = mSetPackages.length;
         final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
+        String setupWizardPackageName = pmi.getSetupWizardPackageName();
         int numMatch = 0;
         for (int i=0; i<NQ; i++) {
             ResolveInfo ri = query.get(i);
@@ -217,7 +214,7 @@
 
             // ignore SetupWizard package's launcher capability because it is only existed
             // during SetupWizard is running
-            if (excludeSetupWizardPackage && ai.packageName.equals(mSetupWizardPackageName)) {
+            if (excludeSetupWizardPackage && ai.packageName.equals(setupWizardPackageName)) {
                 continue;
             }
 
@@ -307,6 +304,8 @@
         if (!excludeSetupWizardPackage && NS < NQ) {
             return false;
         }
+        final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
+        String setupWizardPackageName = pmi.getSetupWizardPackageName();
         for (int i=0; i<NQ; i++) {
             ResolveInfo ri = query.get(i);
             ActivityInfo ai = ri.activityInfo;
@@ -314,7 +313,7 @@
 
             // ignore SetupWizard package's launcher capability because it is only existed
             // during SetupWizard is running
-            if (excludeSetupWizardPackage && ai.packageName.equals(mSetupWizardPackageName)) {
+            if (excludeSetupWizardPackage && ai.packageName.equals(setupWizardPackageName)) {
                 continue;
             }
 
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 4d1519c..b181cdd 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -118,7 +118,8 @@
 
     public void removePackageLI(AndroidPackage pkg, boolean chatty) {
         // Remove the parent package setting
-        PackageStateInternal ps = mPm.getPackageStateInternal(pkg.getPackageName());
+        PackageStateInternal ps = mPm.snapshotComputer()
+                .getPackageStateInternal(pkg.getPackageName());
         if (ps != null) {
             removePackageLI(ps.getPackageName(), chatty);
         } else if (DEBUG_REMOVE && chatty) {
@@ -271,8 +272,8 @@
             synchronized (mPm.mLock) {
                 mPm.mDomainVerificationManager.clearPackage(deletedPs.getPackageName());
                 mPm.mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName);
-                mPm.mAppsFilter.removePackage(mPm.getPackageStateInternal(packageName),
-                        false /* isReplace */);
+                mPm.mAppsFilter.removePackage(mPm.snapshotComputer()
+                                .getPackageStateInternal(packageName), false /* isReplace */);
                 removedAppId = mPm.mSettings.removePackageLPw(packageName);
                 if (outInfo != null) {
                     outInfo.mRemovedAppId = removedAppId;
@@ -284,7 +285,11 @@
                     List<AndroidPackage> sharedUserPkgs =
                             sus != null ? sus.getPackages() : Collections.emptyList();
                     mPermissionManager.onPackageUninstalled(packageName, deletedPs.getAppId(),
-                            deletedPs.getPkg(), sharedUserPkgs, UserHandle.USER_ALL);
+                            deletedPkg, sharedUserPkgs, UserHandle.USER_ALL);
+                    // After permissions are handled, check if the shared user can be migrated
+                    if (sus != null) {
+                        mPm.mSettings.checkAndConvertSharedUserSettingsLPw(sus);
+                    }
                 }
                 mPm.clearPackagePreferredActivitiesLPw(
                         deletedPs.getPackageName(), changedUsers, UserHandle.USER_ALL);
@@ -294,7 +299,8 @@
             if (changedUsers.size() > 0) {
                 final PreferredActivityHelper preferredActivityHelper =
                         new PreferredActivityHelper(mPm);
-                preferredActivityHelper.updateDefaultHomeNotLocked(changedUsers);
+                preferredActivityHelper.updateDefaultHomeNotLocked(mPm.snapshotComputer(),
+                        changedUsers);
                 mPm.postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
             }
         }
diff --git a/services/core/java/com/android/server/pm/ResolveIntentHelper.java b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
index 25356a4..b74670b 100644
--- a/services/core/java/com/android/server/pm/ResolveIntentHelper.java
+++ b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
@@ -115,7 +115,7 @@
             if (!mUserManager.exists(userId)) return null;
             final int callingUid = Binder.getCallingUid();
             flags = computer.updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
-                    computer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
+                    computer.isImplicitImageCaptureIntentAndNotSetByDpc(intent, userId,
                             resolvedType, flags));
             computer.enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
                     false /*checkShell*/, "resolve intent");
@@ -170,9 +170,9 @@
                 }
                 // If we have saved a preference for a preferred activity for
                 // this Intent, use that.
-                ResolveInfo ri = mPreferredActivityHelper.findPreferredActivityNotLocked(intent,
-                        resolvedType, flags, query, true, false, debug, userId,
-                        queryMayBeFiltered);
+                ResolveInfo ri = mPreferredActivityHelper.findPreferredActivityNotLocked(computer,
+                        intent, resolvedType, flags, query, true, false, debug,
+                        userId, queryMayBeFiltered);
                 if (ri != null) {
                     return ri;
                 }
@@ -317,7 +317,7 @@
         final String instantAppPkgName = computer.getInstantAppPackageName(filterCallingUid);
         flags = computer.updateFlagsForResolve(flags, userId, filterCallingUid,
                 false /*includeInstantApps*/,
-                computer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
+                computer.isImplicitImageCaptureIntentAndNotSetByDpc(intent, userId,
                         resolvedType, flags));
         Intent originalIntent = null;
         ComponentName comp = intent.getComponent();
@@ -562,7 +562,7 @@
         final int callingUid = Binder.getCallingUid();
         flags = computer.updateFlagsForResolve(flags, userId, callingUid,
                 false /*includeInstantApps*/,
-                computer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
+                computer.isImplicitImageCaptureIntentAndNotSetByDpc(intent, userId,
                         resolvedType, flags));
         computer.enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
                 false /*checkShell*/, "query intent activity options");
diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java
index 33f0b54..4e8313b 100644
--- a/services/core/java/com/android/server/pm/ScanPackageUtils.java
+++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java
@@ -165,25 +165,15 @@
             }
         }
 
-        int previousAppId = Process.INVALID_UID;
-
         if (pkgSetting != null && oldSharedUserSetting != sharedUserSetting) {
-            if (oldSharedUserSetting != null && sharedUserSetting == null) {
-                previousAppId = pkgSetting.getAppId();
-                // Log that something is leaving shareduid and keep going
-                Slog.i(TAG,
-                        "Package " + parsedPackage.getPackageName() + " shared user changed from "
-                                + oldSharedUserSetting.name + " to " + "<nothing>.");
-            } else {
-                PackageManagerService.reportSettingsProblem(Log.WARN,
-                        "Package " + parsedPackage.getPackageName() + " shared user changed from "
-                                + (oldSharedUserSetting != null
-                                ? oldSharedUserSetting.name : "<nothing>")
-                                + " to "
-                                + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
-                                + "; replacing with new");
-                pkgSetting = null;
-            }
+            PackageManagerService.reportSettingsProblem(Log.WARN,
+                    "Package " + parsedPackage.getPackageName() + " shared user changed from "
+                            + (oldSharedUserSetting != null
+                            ? oldSharedUserSetting.name : "<nothing>")
+                            + " to "
+                            + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
+                            + "; replacing with new");
+            pkgSetting = null;
         }
 
         String[] usesSdkLibraries = null;
@@ -474,8 +464,8 @@
 
         return new ScanResult(request, true, pkgSetting, changedAbiCodePath,
                 !createNewPackage /* existingSettingCopied */,
-                previousAppId, sdkLibraryInfo, staticSharedLibraryInfo,
-                dynamicSharedLibraryInfos);
+                Process.INVALID_UID /* previousAppId */ , sdkLibraryInfo,
+                staticSharedLibraryInfo, dynamicSharedLibraryInfos);
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/ScanResult.java b/services/core/java/com/android/server/pm/ScanResult.java
index f77be1f..e2860ca 100644
--- a/services/core/java/com/android/server/pm/ScanResult.java
+++ b/services/core/java/com/android/server/pm/ScanResult.java
@@ -70,7 +70,9 @@
         mPkgSetting = pkgSetting;
         mChangedAbiCodePath = changedAbiCodePath;
         mExistingSettingCopied = existingSettingCopied;
-        mPreviousAppId = previousAppId;
+        // Hardcode mPreviousAppId to INVALID_UID (http://b/221088088)
+        // This will disable all migration code paths in PMS and PermMS
+        mPreviousAppId = Process.INVALID_UID;
         mSdkSharedLibraryInfo = sdkSharedLibraryInfo;
         mStaticSharedLibraryInfo = staticSharedLibraryInfo;
         mDynamicSharedLibraryInfos = dynamicSharedLibraryInfos;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index d366574..698dbe9 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -29,6 +29,7 @@
 import static android.os.Process.SYSTEM_UID;
 
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+import static com.android.server.pm.SharedUidMigration.BEST_EFFORT;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -39,7 +40,6 @@
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.ComponentInfo;
 import android.content.pm.IntentFilterVerificationInfo;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
@@ -62,7 +62,6 @@
 import android.os.Message;
 import android.os.PatternMatcher;
 import android.os.PersistableBundle;
-import android.os.Process;
 import android.os.SELinux;
 import android.os.SystemClock;
 import android.os.Trace;
@@ -112,11 +111,9 @@
 import com.android.server.pm.pkg.PackageStateInternal;
 import com.android.server.pm.pkg.PackageUserState;
 import com.android.server.pm.pkg.PackageUserStateInternal;
-import com.android.server.pm.pkg.PackageUserStateUtils;
 import com.android.server.pm.pkg.SuspendParams;
 import com.android.server.pm.pkg.component.ParsedComponent;
 import com.android.server.pm.pkg.component.ParsedIntentInfo;
-import com.android.server.pm.pkg.component.ParsedMainComponent;
 import com.android.server.pm.pkg.component.ParsedPermission;
 import com.android.server.pm.pkg.component.ParsedProcess;
 import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
@@ -410,8 +407,6 @@
         int[] excludedUserIds;
     }
 
-    private static int mFirstAvailableUid = Process.FIRST_APPLICATION_UID;
-
     /** Map from volume UUID to {@link VersionInfo} */
     @Watched
     private final WatchedArrayMap<String, VersionInfo> mVersion = new WatchedArrayMap<>();
@@ -474,10 +469,8 @@
 
     @Watched
     final WatchedArrayMap<String, SharedUserSetting> mSharedUsers = new WatchedArrayMap<>();
-    @Watched
-    private final WatchedArrayList<SettingBase> mAppIds;
-    @Watched
-    private final WatchedSparseArray<SettingBase> mOtherAppIds;
+    @Watched(manual = true)
+    private final AppIdSettingMap mAppIds;
 
     // For reading/writing settings file.
     @Watched
@@ -567,7 +560,6 @@
         mCrossProfileIntentResolvers.registerObserver(mObserver);
         mSharedUsers.registerObserver(mObserver);
         mAppIds.registerObserver(mObserver);
-        mOtherAppIds.registerObserver(mObserver);
         mRenamedPackages.registerObserver(mObserver);
         mNextAppLinkGeneration.registerObserver(mObserver);
         mDefaultBrowserApp.registerObserver(mObserver);
@@ -593,8 +585,7 @@
 
         mLock = new PackageManagerTracedLock();
         mPackages.putAll(pkgSettings);
-        mAppIds = new WatchedArrayList<>();
-        mOtherAppIds = new WatchedSparseArray<>();
+        mAppIds = new AppIdSettingMap();
         mSystemDir = null;
         mPermissions = null;
         mRuntimePermissionsPersistence = null;
@@ -630,8 +621,7 @@
         mKeySetManagerService = new KeySetManagerService(mPackages);
 
         mLock = lock;
-        mAppIds = new WatchedArrayList<>();
-        mOtherAppIds = new WatchedSparseArray<>();
+        mAppIds = new AppIdSettingMap();
         mPermissions = new LegacyPermissionSettings(lock);
         mRuntimePermissionsPersistence = new RuntimePermissionPersistence(
                 runtimePermissionsPersistence, new Consumer<Integer>() {
@@ -712,7 +702,6 @@
                 mCrossProfileIntentResolvers, r.mCrossProfileIntentResolvers);
         mSharedUsers.snapshot(r.mSharedUsers);
         mAppIds = r.mAppIds.snapshot();
-        mOtherAppIds = r.mOtherAppIds.snapshot();
         WatchedArrayList.snapshot(
                 mPastSignatures, r.mPastSignatures);
         WatchedArrayMap.snapshot(
@@ -784,7 +773,7 @@
         SharedUserSetting s = mSharedUsers.get(name);
         if (s == null && create) {
             s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
-            s.mAppId = acquireAndRegisterNewAppIdLPw(s);
+            s.mAppId = mAppIds.acquireAndRegisterNewAppId(s);
             if (s.mAppId < 0) {
                 // < 0 means we couldn't assign a userid; throw exception
                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
@@ -892,7 +881,7 @@
                 pkgPrivateFlags, 0 /*userId*/, usesSdkLibraries, usesSdkLibrariesVersions,
                 usesStaticLibraries, usesStaticLibrariesVersions, mimeGroups, domainSetId);
         p.setAppId(uid);
-        if (registerExistingAppIdLPw(uid, p, name)) {
+        if (mAppIds.registerExistingAppId(uid, p, name)) {
             mPackages.put(name, p);
             return p;
         }
@@ -911,7 +900,7 @@
         }
         s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
         s.mAppId = uid;
-        if (registerExistingAppIdLPw(uid, s, name)) {
+        if (mAppIds.registerExistingAppId(uid, s, name)) {
             mSharedUsers.put(name, s);
             return s;
         }
@@ -1212,11 +1201,11 @@
         final boolean createdNew;
         if (p.getAppId() == 0 || forceNew) {
             // Assign new user ID
-            p.setAppId(acquireAndRegisterNewAppIdLPw(p));
+            p.setAppId(mAppIds.acquireAndRegisterNewAppId(p));
             createdNew = true;
         } else {
             // Add new setting to list of user IDs
-            createdNew = registerExistingAppIdLPw(p.getAppId(), p, p.getPackageName());
+            createdNew = mAppIds.registerExistingAppId(p.getAppId(), p, p.getPackageName());
         }
         if (p.getAppId() < 0) {
             PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -1277,7 +1266,8 @@
     // Utility method that adds a PackageSetting to mPackages and
     // completes updating the shared user attributes and any restored
     // app link verification state
-    private void addPackageSettingLPw(PackageSetting p, SharedUserSetting sharedUser) {
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    void addPackageSettingLPw(PackageSetting p, SharedUserSetting sharedUser) {
         mPackages.put(p.getPackageName(), p);
         if (sharedUser != null) {
             SharedUserSetting existingSharedUserSetting = getSharedUserSettingLPr(p);
@@ -1300,16 +1290,16 @@
             p.setAppId(sharedUser.mAppId);
         }
 
-        // If the we know about this user id, we have to update it as it
+        // If we know about this user id, we have to update it as it
         // has to point to the same PackageSetting instance as the package.
         Object userIdPs = getSettingLPr(p.getAppId());
         if (sharedUser == null) {
             if (userIdPs != null && userIdPs != p) {
-                replaceAppIdLPw(p.getAppId(), p);
+                mAppIds.replaceSetting(p.getAppId(), p);
             }
         } else {
             if (userIdPs != null && userIdPs != sharedUser) {
-                replaceAppIdLPw(p.getAppId(), sharedUser);
+                mAppIds.replaceSetting(p.getAppId(), sharedUser);
             }
         }
     }
@@ -1358,69 +1348,41 @@
         mInstallerPackages.remove(packageName);
     }
 
-    /** Returns true if the requested AppID was valid and not already registered. */
-    private boolean registerExistingAppIdLPw(int appId, SettingBase obj, Object name) {
-        if (appId > Process.LAST_APPLICATION_UID) {
-            return false;
-        }
-
-        if (appId >= Process.FIRST_APPLICATION_UID) {
-            int size = mAppIds.size();
-            final int index = appId - Process.FIRST_APPLICATION_UID;
-            // fill the array until our index becomes valid
-            while (index >= size) {
-                mAppIds.add(null);
-                size++;
-            }
-            if (mAppIds.get(index) != null) {
-                PackageManagerService.reportSettingsProblem(Log.WARN,
-                        "Adding duplicate app id: " + appId
-                        + " name=" + name);
-                return false;
-            }
-            mAppIds.set(index, obj);
-        } else {
-            if (mOtherAppIds.get(appId) != null) {
-                PackageManagerService.reportSettingsProblem(Log.WARN,
-                        "Adding duplicate shared id: " + appId
-                                + " name=" + name);
-                return false;
-            }
-            mOtherAppIds.put(appId, obj);
-        }
-        return true;
-    }
-
     /** Gets the setting associated with the provided App ID */
     public SettingBase getSettingLPr(int appId) {
-        if (appId >= Process.FIRST_APPLICATION_UID) {
-            final int size = mAppIds.size();
-            final int index = appId - Process.FIRST_APPLICATION_UID;
-            return index < size ? mAppIds.get(index) : null;
-        } else {
-            return mOtherAppIds.get(appId);
-        }
+        return mAppIds.getSetting(appId);
     }
 
     /** Unregisters the provided app ID. */
     void removeAppIdLPw(int appId) {
-        if (appId >= Process.FIRST_APPLICATION_UID) {
-            final int size = mAppIds.size();
-            final int index = appId - Process.FIRST_APPLICATION_UID;
-            if (index < size) mAppIds.set(index, null);
-        } else {
-            mOtherAppIds.remove(appId);
+        mAppIds.removeSetting(appId);
+    }
+    /**
+     * Transparently convert a SharedUserSetting into PackageSettings without changing appId.
+     * The sharedUser passed to this method has to be {@link SharedUserSetting#isSingleUser()}.
+     */
+    void convertSharedUserSettingsLPw(SharedUserSetting sharedUser) {
+        final PackageSetting ps = sharedUser.getPackageSettings().valueAt(0);
+        mAppIds.replaceSetting(sharedUser.getAppId(), ps);
+
+        // Unlink the SharedUserSetting
+        ps.setSharedUserAppId(INVALID_UID);
+        if (!sharedUser.getDisabledPackageSettings().isEmpty()) {
+            final PackageSetting disabledPs = sharedUser.getDisabledPackageSettings().valueAt(0);
+            disabledPs.setSharedUserAppId(INVALID_UID);
         }
-        setFirstAvailableUid(appId + 1);
+        mSharedUsers.remove(sharedUser.getName());
     }
 
-    private void replaceAppIdLPw(int appId, SettingBase obj) {
-        if (appId >= Process.FIRST_APPLICATION_UID) {
-            final int size = mAppIds.size();
-            final int index = appId - Process.FIRST_APPLICATION_UID;
-            if (index < size) mAppIds.set(index, obj);
-        } else {
-            mOtherAppIds.put(appId, obj);
+    /**
+     * Check and convert eligible SharedUserSettings to PackageSettings.
+     */
+    void checkAndConvertSharedUserSettingsLPw(SharedUserSetting sharedUser) {
+        if (!sharedUser.isSingleUser()) return;
+        final AndroidPackage pkg = sharedUser.getPackageSettings().valueAt(0).getPkg();
+        if (pkg != null && pkg.isLeavingSharedUid()
+                && SharedUidMigration.applyStrategy(BEST_EFFORT)) {
+            convertSharedUserSettingsLPw(sharedUser);
         }
     }
 
@@ -4190,10 +4152,11 @@
                     // Accumulate all required args and call the installer after mPackages lock
                     // has been released
                     final String seInfo = AndroidPackageUtils.getSeInfo(ps.getPkg(), ps);
+                    final boolean usesSdk = !ps.getPkg().getUsesSdkLibraries().isEmpty();
                     final CreateAppDataArgs args = Installer.buildCreateAppDataArgs(
                             ps.getVolumeUuid(), ps.getPackageName(), userHandle,
                             StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE,
-                            ps.getAppId(), seInfo, ps.getPkg().getTargetSdkVersion());
+                            ps.getAppId(), seInfo, ps.getPkg().getTargetSdkVersion(), usesSdk);
                     batch.createAppData(args);
                 } else {
                     // Make sure the app is excluded from storage mapping for this user
@@ -4264,33 +4227,6 @@
         }
     }
 
-    // This should be called (at least) whenever an application is removed
-    private void setFirstAvailableUid(int uid) {
-        if (uid > mFirstAvailableUid) {
-            mFirstAvailableUid = uid;
-        }
-    }
-
-    /** Returns a new AppID or -1 if we could not find an available AppID to assign */
-    private int acquireAndRegisterNewAppIdLPw(SettingBase obj) {
-        // Let's be stupidly inefficient for now...
-        final int size = mAppIds.size();
-        for (int i = mFirstAvailableUid - Process.FIRST_APPLICATION_UID; i < size; i++) {
-            if (mAppIds.get(i) == null) {
-                mAppIds.set(i, obj);
-                return Process.FIRST_APPLICATION_UID + i;
-            }
-        }
-
-        // None left?
-        if (size > (Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID)) {
-            return -1;
-        }
-
-        mAppIds.add(obj);
-        return Process.FIRST_APPLICATION_UID + size;
-    }
-
     public VerifierDeviceIdentity getVerifierDeviceIdentityLPw(@NonNull Computer computer) {
         if (mVerifierDeviceIdentity == null) {
             mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
@@ -4323,33 +4259,6 @@
         return getDisabledSystemPkgLPr(enabledPackageSetting.getPackageName());
     }
 
-    boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, long flags, int userId) {
-        final PackageSetting ps = mPackages.get(componentInfo.packageName);
-        if (ps == null) return false;
-
-        final PackageUserStateInternal userState = ps.readUserState(userId);
-        return PackageUserStateUtils.isMatch(userState, componentInfo, flags);
-    }
-
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    public boolean isEnabledAndMatchLPr(AndroidPackage pkg, ParsedMainComponent component,
-            long flags, int userId) {
-        final PackageSetting ps = mPackages.get(component.getPackageName());
-        if (ps == null) return false;
-
-        final PackageUserStateInternal userState = ps.readUserState(userId);
-        return PackageUserStateUtils.isMatch(userState, pkg.isSystem(), pkg.isEnabled(), component,
-                flags);
-    }
-
-    boolean isOrphaned(String packageName) {
-        final PackageSetting pkg = mPackages.get(packageName);
-        if (pkg == null) {
-            throw new IllegalArgumentException("Unknown package: " + packageName);
-        }
-        return pkg.getInstallSource().isOrphaned;
-    }
-
     int getApplicationEnabledSettingLPr(String packageName, int userId)
             throws PackageManager.NameNotFoundException {
         final PackageSetting pkg = mPackages.get(packageName);
diff --git a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
index 3fe0790..479a404 100644
--- a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
+++ b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
@@ -741,9 +741,11 @@
         }
         SharedLibraryInfo libraryInfo = versionedLib.valueAt(libIdx);
 
+        final Computer snapshot = mPm.snapshotComputer();
+
         // Remove the shared library overlays from its dependent packages.
         for (int currentUserId : mPm.mUserManager.getUserIds()) {
-            final List<VersionedPackage> dependents = mPm.getPackagesUsingSharedLibrary(
+            final List<VersionedPackage> dependents = snapshot.getPackagesUsingSharedLibrary(
                     libraryInfo, 0, Process.SYSTEM_UID, currentUserId);
             if (dependents == null) {
                 continue;
diff --git a/services/core/java/com/android/server/pm/SharedUidMigration.java b/services/core/java/com/android/server/pm/SharedUidMigration.java
new file mode 100644
index 0000000..e44ef66
--- /dev/null
+++ b/services/core/java/com/android/server/pm/SharedUidMigration.java
@@ -0,0 +1,99 @@
+/*
+ * 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.pm;
+
+import android.annotation.IntDef;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.SystemProperties;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A utility class hosting code configuring shared UID migration behavior.
+ */
+public final class SharedUidMigration {
+
+    /**
+     * The system property key used to configure the shared UID migration strategy.
+     */
+    public static final String PROPERTY_KEY = "persist.debug.pm.shared_uid_migration_strategy";
+
+    /**
+     * Only leave shared UID for newly installed packages.
+     */
+    public static final int NEW_INSTALL_ONLY = 1;
+    /**
+     * Opportunistically migrate any single-package shared UID group.
+     */
+    public static final int BEST_EFFORT = 2;
+    /**
+     * Run appId transitions when the device reboots.
+     */
+    public static final int TRANSITION_AT_BOOT = 3;
+    /**
+     * Run appId transitions as soon as the upgrade is installed.
+     */
+    public static final int LIVE_TRANSITION = 4;
+
+    @IntDef({
+            NEW_INSTALL_ONLY,
+            BEST_EFFORT,
+            TRANSITION_AT_BOOT,
+            LIVE_TRANSITION,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Strategy {}
+
+    @Strategy
+    private static final int DEFAULT = BEST_EFFORT;
+
+    /**
+     * Whether shared UID migration is fully disabled. Disabled means the sharedUserMaxSdkVersion
+     * attribute will be directly ignored in the parsing phase.
+     */
+    public static boolean isDisabled() {
+        return !PackageManager.ENABLE_SHARED_UID_MIGRATION;
+    }
+
+    /**
+     * If the system is userdebug, returns the strategy to use by getting the system property
+     * {@link #PROPERTY_KEY}, or else returns the default strategy enabled in the build.
+     */
+    public static int getCurrentStrategy() {
+        if (!Build.IS_USERDEBUG) {
+            return DEFAULT;
+        }
+
+        final int s = SystemProperties.getInt(PROPERTY_KEY, DEFAULT);
+        // No transition strategies can be used (http://b/221088088)
+        if (s > BEST_EFFORT || s < NEW_INSTALL_ONLY) {
+            return DEFAULT;
+        }
+        return s;
+    }
+
+    /**
+     * Should the strategy be used based on the current active strategy.
+     */
+    public static boolean applyStrategy(@Strategy int strategy) {
+        return !isDisabled() && getCurrentStrategy() >= strategy;
+    }
+
+    private SharedUidMigration() {}
+}
diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java
index 4d0bbc6..23f0de8 100644
--- a/services/core/java/com/android/server/pm/SharedUserSetting.java
+++ b/services/core/java/com/android/server/pm/SharedUserSetting.java
@@ -221,6 +221,25 @@
     }
 
     /**
+     * A shared user is considered "single user" if there is exactly one single package
+     * currently using it. In the case when that package is also a system app, the APK on
+     * the system partition has to also leave shared UID.
+     */
+    public boolean isSingleUser() {
+        if (mPackages.size() != 1) {
+            return false;
+        }
+        if (mDisabledPackages.size() > 1) {
+            return false;
+        }
+        if (mDisabledPackages.size() == 1) {
+            final AndroidPackage pkg = mDisabledPackages.valueAt(0).getPkg();
+            return pkg != null && pkg.isLeavingSharedUid();
+        }
+        return true;
+    }
+
+    /**
      * Determine the targetSdkVersion for a sharedUser and update pkg.applicationInfo.seInfo
      * to ensure that all apps within the sharedUser share an SELinux domain. Use the lowest
      * targetSdkVersion of all apps within the shared user, which corresponds to the least
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 1cf2dc5..25fe000 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -488,7 +488,8 @@
         mShortcutBitmapSaver = new ShortcutBitmapSaver(this);
         mShortcutDumpFiles = new ShortcutDumpFiles(this);
         mIsAppSearchEnabled = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SHORTCUT_APPSEARCH_INTEGRATION, true);
+                SystemUiDeviceConfigFlags.SHORTCUT_APPSEARCH_INTEGRATION, true)
+                && !injectIsLowRamDevice();
 
         if (onlyForPackageManagerApis) {
             return; // Don't do anything further.  For unit tests only.
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 52a7bed..43dde5c 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -28,8 +28,6 @@
 import android.content.pm.ApexStagedEvent;
 import android.content.pm.IStagedApexObserver;
 import android.content.pm.PackageInstaller;
-import android.content.pm.PackageInstaller.SessionInfo;
-import android.content.pm.PackageInstaller.SessionInfo.SessionErrorCode;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.StagedApexInfo;
@@ -124,7 +122,7 @@
         boolean containsApkSession();
         boolean containsApexSession();
         void setSessionReady();
-        void setSessionFailed(@SessionErrorCode int errorCode, String errorMessage);
+        void setSessionFailed(int errorCode, String errorMessage);
         void setSessionApplied();
         CompletableFuture<Void> installSession();
         boolean hasParentSessionId();
@@ -279,7 +277,7 @@
             String packageName = apexSession.getPackageName();
             String errorMsg = mApexManager.getApkInApexInstallError(packageName);
             if (errorMsg != null) {
-                throw new PackageManagerException(SessionInfo.SESSION_ACTIVATION_FAILED,
+                throw new PackageManagerException(PackageManager.INSTALL_ACTIVATION_FAILED,
                         "Failed to install apk-in-apex of " + packageName + " : " + errorMsg);
             }
         }
@@ -392,7 +390,7 @@
                 revertMsg += " Reason for revert: " + reasonForRevert;
             }
             Slog.d(TAG, revertMsg);
-            session.setSessionFailed(SessionInfo.SESSION_UNKNOWN_ERROR, revertMsg);
+            session.setSessionFailed(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, revertMsg);
             return;
         }
 
@@ -477,7 +475,7 @@
             for (String apkInApex : mApexManager.getApksInApex(packageName)) {
                 if (!apkNames.add(apkInApex)) {
                     throw new PackageManagerException(
-                            SessionInfo.SESSION_ACTIVATION_FAILED,
+                            PackageManager.INSTALL_ACTIVATION_FAILED,
                             "Package: " + packageName + " in session: "
                                     + apexSession.sessionId() + " has duplicate apk-in-apex: "
                                     + apkInApex, null);
@@ -495,9 +493,7 @@
             // Should be impossible
             throw new RuntimeException(e);
         } catch (ExecutionException ee) {
-            PackageManagerException e = (PackageManagerException) ee.getCause();
-            final String errorMsg = PackageManager.installStatusToString(e.error, e.getMessage());
-            throw new PackageManagerException(SessionInfo.SESSION_ACTIVATION_FAILED, errorMsg);
+            throw (PackageManagerException) ee.getCause();
         }
     }
 
@@ -651,7 +647,7 @@
             // is upgrading. Fail all the sessions and exit early.
             for (int i = 0; i < sessions.size(); i++) {
                 StagedSession session = sessions.get(i);
-                session.setSessionFailed(SessionInfo.SESSION_ACTIVATION_FAILED,
+                session.setSessionFailed(PackageManager.INSTALL_ACTIVATION_FAILED,
                         "Build fingerprint has changed");
             }
             return;
@@ -691,7 +687,7 @@
             final ApexSessionInfo apexSession = apexSessions.get(session.sessionId());
             if (apexSession == null || apexSession.isUnknown) {
                 hasFailedApexSession = true;
-                session.setSessionFailed(SessionInfo.SESSION_ACTIVATION_FAILED, "apexd did "
+                session.setSessionFailed(PackageManager.INSTALL_ACTIVATION_FAILED, "apexd did "
                         + "not know anything about a staged session supposed to be activated");
                 continue;
             } else if (isApexSessionFailed(apexSession)) {
@@ -707,7 +703,7 @@
                     errorMsg += " Error: " + apexSession.errorMessage;
                 }
                 Slog.d(TAG, errorMsg);
-                session.setSessionFailed(SessionInfo.SESSION_ACTIVATION_FAILED, errorMsg);
+                session.setSessionFailed(PackageManager.INSTALL_ACTIVATION_FAILED, errorMsg);
                 continue;
             } else if (apexSession.isActivated || apexSession.isSuccess) {
                 hasAppliedApexSession = true;
@@ -716,13 +712,13 @@
                 // Apexd did not apply the session for some unknown reason. There is no guarantee
                 // that apexd will install it next time. Safer to proactively mark it as failed.
                 hasFailedApexSession = true;
-                session.setSessionFailed(SessionInfo.SESSION_ACTIVATION_FAILED,
+                session.setSessionFailed(PackageManager.INSTALL_ACTIVATION_FAILED,
                         "Staged session " + session.sessionId() + " at boot didn't activate nor "
                         + "fail. Marking it as failed anyway.");
             } else {
                 Slog.w(TAG, "Apex session " + session.sessionId() + " is in impossible state");
                 hasFailedApexSession = true;
-                session.setSessionFailed(SessionInfo.SESSION_ACTIVATION_FAILED,
+                session.setSessionFailed(PackageManager.INSTALL_ACTIVATION_FAILED,
                         "Impossible state");
             }
         }
@@ -742,7 +738,7 @@
                     // Session has been already failed in the loop above.
                     continue;
                 }
-                session.setSessionFailed(SessionInfo.SESSION_ACTIVATION_FAILED,
+                session.setSessionFailed(PackageManager.INSTALL_ACTIVATION_FAILED,
                         "Another apex session failed");
             }
             return;
@@ -758,7 +754,7 @@
             } catch (Exception e) {
                 Slog.e(TAG, "Staged install failed due to unhandled exception", e);
                 onInstallationFailure(session, new PackageManagerException(
-                        SessionInfo.SESSION_ACTIVATION_FAILED,
+                        PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
                         "Staged install failed due to unhandled exception: " + e),
                         supportsCheckpoint, needsCheckpoint);
             }
diff --git a/services/core/java/com/android/server/pm/StorageEventHelper.java b/services/core/java/com/android/server/pm/StorageEventHelper.java
index bb7e55a..df19d3e 100644
--- a/services/core/java/com/android/server/pm/StorageEventHelper.java
+++ b/services/core/java/com/android/server/pm/StorageEventHelper.java
@@ -26,13 +26,13 @@
 import static com.android.server.pm.PackageManagerService.TAG;
 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
 
+import android.annotation.NonNull;
 import android.app.ResourcesManager;
 import android.content.IIntentReceiver;
 import android.content.pm.PackageManager;
 import android.content.pm.PackagePartitions;
 import android.content.pm.UserInfo;
 import android.content.pm.VersionedPackage;
-import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.UserHandle;
@@ -48,6 +48,7 @@
 import com.android.internal.policy.AttributeCache;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -78,7 +79,7 @@
                 // Clean up any users or apps that were removed or recreated
                 // while this volume was missing
                 mPm.mUserManager.reconcileUsers(volumeUuid);
-                reconcileApps(volumeUuid);
+                reconcileApps(mPm.snapshotComputer(), volumeUuid);
 
                 // Clean up any install sessions that expired or were
                 // cancelled while this volume was missing
@@ -299,8 +300,8 @@
      * aren't expected, either due to uninstallation or reinstallation on
      * another volume.
      */
-    public void reconcileApps(String volumeUuid) {
-        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
+    public void reconcileApps(@NonNull Computer snapshot, String volumeUuid) {
+        List<String> absoluteCodePaths = collectAbsoluteCodePaths(snapshot);
         List<File> filesToDelete = null;
 
         final File[] files = FileUtils.listFilesOrEmpty(
@@ -345,10 +346,10 @@
         }
     }
 
-    private List<String> collectAbsoluteCodePaths() {
+    private List<String> collectAbsoluteCodePaths(@NonNull Computer snapshot) {
         List<String> codePaths = new ArrayList<>();
         final ArrayMap<String, ? extends PackageStateInternal> packageStates =
-                mPm.getPackageStates();
+                snapshot.getPackageStates();
         final int packageCount = packageStates.size();
         for (int i = 0; i < packageCount; i++) {
             final PackageStateInternal ps = packageStates.valueAt(i);
diff --git a/services/core/java/com/android/server/pm/SuspendPackageHelper.java b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
index 3ef5599..588dfaf 100644
--- a/services/core/java/com/android/server/pm/SuspendPackageHelper.java
+++ b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
@@ -100,14 +100,14 @@
      * @return The names of failed packages.
      */
     @Nullable
-    String[] setPackagesSuspended(@NonNull Computer computer, @Nullable String[] packageNames,
+    String[] setPackagesSuspended(@NonNull Computer snapshot, @Nullable String[] packageNames,
             boolean suspended, @Nullable PersistableBundle appExtras,
             @Nullable PersistableBundle launcherExtras, @Nullable SuspendDialogInfo dialogInfo,
             @NonNull String callingPackage, @UserIdInt int userId, int callingUid) {
         if (ArrayUtils.isEmpty(packageNames)) {
             return packageNames;
         }
-        if (suspended && !isSuspendAllowedForUser(userId, callingUid)) {
+        if (suspended && !isSuspendAllowedForUser(snapshot, userId, callingUid)) {
             Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
             return packageNames;
         }
@@ -123,7 +123,7 @@
         ArraySet<String> modifiedPackages = new ArraySet<>();
 
         final boolean[] canSuspend = suspended
-                ? canSuspendPackageForUser(computer, packageNames, userId, callingUid) : null;
+                ? canSuspendPackageForUser(snapshot, packageNames, userId, callingUid) : null;
         for (int i = 0; i < packageNames.length; i++) {
             final String packageName = packageNames[i];
             if (callingPackage.equals(packageName)) {
@@ -133,9 +133,9 @@
                 continue;
             }
             final PackageStateInternal packageState =
-                    computer.getPackageStateInternal(packageName);
+                    snapshot.getPackageStateInternal(packageName);
             if (packageState == null
-                    || computer.shouldFilterApplication(packageState, callingUid, userId)) {
+                    || snapshot.shouldFilterApplication(packageState, callingUid, userId)) {
                 Slog.w(TAG, "Could not find package setting for package: " + packageName
                         + ". Skipping suspending/un-suspending.");
                 unmodifiablePackages.add(packageName);
@@ -191,9 +191,11 @@
             }
         });
 
+        final Computer newSnapshot = mPm.snapshotComputer();
+
         if (!changedPackagesList.isEmpty()) {
             final String[] changedPackages = changedPackagesList.toArray(new String[0]);
-            sendPackagesSuspendedForUser(
+            sendPackagesSuspendedForUser(newSnapshot,
                     suspended ? Intent.ACTION_PACKAGES_SUSPENDED
                             : Intent.ACTION_PACKAGES_UNSUSPENDED,
                     changedPackages, changedUids.toArray(), userId);
@@ -202,7 +204,7 @@
         }
         // Send the suspension changed broadcast to ensure suspension state is not stale.
         if (!modifiedPackages.isEmpty()) {
-            sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_SUSPENSION_CHANGED,
+            sendPackagesSuspendedForUser(newSnapshot, Intent.ACTION_PACKAGES_SUSPENSION_CHANGED,
                     modifiedPackages.toArray(new String[0]), modifiedUids.toArray(), userId);
         }
         return unmodifiablePackages.toArray(new String[0]);
@@ -217,14 +219,14 @@
      * @return The names of packages which are Unsuspendable.
      */
     @NonNull
-    String[] getUnsuspendablePackagesForUser(@NonNull Computer computer,
+    String[] getUnsuspendablePackagesForUser(@NonNull Computer snapshot,
             @NonNull String[] packageNames, @UserIdInt int userId, int callingUid) {
-        if (!isSuspendAllowedForUser(userId, callingUid)) {
+        if (!isSuspendAllowedForUser(snapshot, userId, callingUid)) {
             Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
             return packageNames;
         }
         final ArraySet<String> unactionablePackages = new ArraySet<>();
-        final boolean[] canSuspend = canSuspendPackageForUser(computer, packageNames, userId,
+        final boolean[] canSuspend = canSuspendPackageForUser(snapshot, packageNames, userId,
                 callingUid);
         for (int i = 0; i < packageNames.length; i++) {
             if (!canSuspend[i]) {
@@ -232,7 +234,7 @@
                 continue;
             }
             final PackageStateInternal packageState =
-                    computer.getPackageStateFiltered(packageNames[i], callingUid, userId);
+                    snapshot.getPackageStateFiltered(packageNames[i], callingUid, userId);
             if (packageState == null) {
                 Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]);
                 unactionablePackages.add(packageNames[i]);
@@ -250,8 +252,9 @@
      * @return The app extras of the suspended package.
      */
     @Nullable
-    Bundle getSuspendedPackageAppExtras(@NonNull String packageName, int userId, int callingUid) {
-        final PackageStateInternal ps = mPm.getPackageStateInternal(packageName, callingUid);
+    Bundle getSuspendedPackageAppExtras(@NonNull Computer snapshot, @NonNull String packageName,
+            int userId, int callingUid) {
+        final PackageStateInternal ps = snapshot.getPackageStateInternal(packageName, callingUid);
         if (ps == null) {
             return null;
         }
@@ -329,12 +332,14 @@
             }
         });
 
+        final Computer newSnapshot = mPm.snapshotComputer();
+
         mPm.scheduleWritePackageRestrictions(userId);
         if (!unsuspendedPackages.isEmpty()) {
             final String[] packageArray = unsuspendedPackages.toArray(
                     new String[unsuspendedPackages.size()]);
             sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId);
-            sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_UNSUSPENDED,
+            sendPackagesSuspendedForUser(newSnapshot, Intent.ACTION_PACKAGES_UNSUSPENDED,
                     packageArray, unsuspendedUids.toArray(), userId);
         }
     }
@@ -348,10 +353,10 @@
      * @return The launcher extras.
      */
     @Nullable
-    Bundle getSuspendedPackageLauncherExtras(@NonNull String packageName, int userId,
-            int callingUid) {
-        final PackageStateInternal packageState = mPm.getPackageStateInternal(
-                packageName, callingUid);
+    Bundle getSuspendedPackageLauncherExtras(@NonNull Computer snapshot,
+            @NonNull String packageName, int userId, int callingUid) {
+        final PackageStateInternal packageState =
+                snapshot.getPackageStateInternal(packageName, callingUid);
         if (packageState == null) {
             return null;
         }
@@ -376,9 +381,10 @@
      * @param callingUid The caller's uid.
      * @return {@code true}, if the given package is suspended.
      */
-    boolean isPackageSuspended(@NonNull String packageName, int userId, int callingUid) {
-        final PackageStateInternal packageState = mPm.getPackageStateInternal(
-                packageName, callingUid);
+    boolean isPackageSuspended(@NonNull Computer snapshot, @NonNull String packageName, int userId,
+            int callingUid) {
+        final PackageStateInternal packageState =
+                snapshot.getPackageStateInternal(packageName, callingUid);
         return packageState != null && packageState.getUserStateOrDefault(userId)
                 .isSuspended();
     }
@@ -392,8 +398,9 @@
      * @return The name of suspending package.
      */
     @Nullable
-    String getSuspendingPackage(@NonNull String suspendedPackage, int userId, int callingUid) {
-        final PackageStateInternal packageState = mPm.getPackageStateInternal(
+    String getSuspendingPackage(@NonNull Computer snapshot, @NonNull String suspendedPackage,
+            int userId, int callingUid) {
+        final PackageStateInternal packageState = snapshot.getPackageStateInternal(
                 suspendedPackage, callingUid);
         if (packageState == null) {
             return  null;
@@ -424,9 +431,10 @@
      * @return The dialog info.
      */
     @Nullable
-    SuspendDialogInfo getSuspendedDialogInfo(@NonNull String suspendedPackage,
-            @NonNull String suspendingPackage, int userId, int callingUid) {
-        final PackageStateInternal packageState = mPm.getPackageStateInternal(
+    SuspendDialogInfo getSuspendedDialogInfo(@NonNull Computer snapshot,
+            @NonNull String suspendedPackage, @NonNull String suspendingPackage, int userId,
+            int callingUid) {
+        final PackageStateInternal packageState = snapshot.getPackageStateInternal(
                 suspendedPackage, callingUid);
         if (packageState == null) {
             return  null;
@@ -454,9 +462,9 @@
      * @param callingUid The caller's uid.
      * @return {@code true} if the user is allowed to suspend packages by the caller.
      */
-    boolean isSuspendAllowedForUser(int userId, int callingUid) {
+    boolean isSuspendAllowedForUser(@NonNull Computer snapshot, int userId, int callingUid) {
         final UserManagerService userManager = mInjector.getUserManagerService();
-        return isCallerDeviceOrProfileOwner(userId, callingUid)
+        return isCallerDeviceOrProfileOwner(snapshot, userId, callingUid)
                 || (!userManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId)
                 && !userManager.hasUserRestriction(UserManager.DISALLOW_UNINSTALL_APPS, userId));
     }
@@ -471,21 +479,23 @@
      * @return An array containing results of the checks
      */
     @NonNull
-    boolean[] canSuspendPackageForUser(@NonNull Computer computer, @NonNull String[] packageNames,
+    boolean[] canSuspendPackageForUser(@NonNull Computer snapshot, @NonNull String[] packageNames,
             int userId, int callingUid) {
         final boolean[] canSuspend = new boolean[packageNames.length];
-        final boolean isCallerOwner = isCallerDeviceOrProfileOwner(userId, callingUid);
+        final boolean isCallerOwner = isCallerDeviceOrProfileOwner(snapshot, userId, callingUid);
         final long token = Binder.clearCallingIdentity();
         try {
             final DefaultAppProvider defaultAppProvider = mInjector.getDefaultAppProvider();
             final String activeLauncherPackageName = defaultAppProvider.getDefaultHome(userId);
             final String dialerPackageName = defaultAppProvider.getDefaultDialer(userId);
-            final String requiredInstallerPackage = getKnownPackageName(PACKAGE_INSTALLER, userId);
+            final String requiredInstallerPackage =
+                    getKnownPackageName(snapshot, PACKAGE_INSTALLER, userId);
             final String requiredUninstallerPackage =
-                    getKnownPackageName(PACKAGE_UNINSTALLER, userId);
-            final String requiredVerifierPackage = getKnownPackageName(PACKAGE_VERIFIER, userId);
+                    getKnownPackageName(snapshot, PACKAGE_UNINSTALLER, userId);
+            final String requiredVerifierPackage =
+                    getKnownPackageName(snapshot, PACKAGE_VERIFIER, userId);
             final String requiredPermissionControllerPackage =
-                    getKnownPackageName(PACKAGE_PERMISSION_CONTROLLER, userId);
+                    getKnownPackageName(snapshot, PACKAGE_PERMISSION_CONTROLLER, userId);
             for (int i = 0; i < packageNames.length; i++) {
                 canSuspend[i] = false;
                 final String packageName = packageNames[i];
@@ -530,7 +540,7 @@
                             + "\": protected package");
                     continue;
                 }
-                if (!isCallerOwner && computer.getBlockUninstall(userId, packageName)) {
+                if (!isCallerOwner && snapshot.getBlockUninstall(userId, packageName)) {
                     Slog.w(TAG, "Cannot suspend package \"" + packageName
                             + "\": blocked by admin");
                     continue;
@@ -539,7 +549,7 @@
                 // Cannot suspend static shared libs as they are considered
                 // a part of the using app (emulating static linking). Also
                 // static libs are installed always on internal storage.
-                PackageStateInternal packageState = computer.getPackageStateInternal(packageName);
+                PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
                 AndroidPackage pkg = packageState == null ? null : packageState.getPkg();
                 if (pkg != null) {
                     // Cannot suspend SDK libs as they are controlled by SDK manager.
@@ -580,8 +590,8 @@
      * @param userId The user where packages reside.
      */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    void sendPackagesSuspendedForUser(@NonNull String intent, @NonNull String[] pkgList,
-            @NonNull int[] uidList, int userId) {
+    void sendPackagesSuspendedForUser(@NonNull Computer snapshot, @NonNull String intent,
+            @NonNull String[] pkgList, @NonNull int[] uidList, int userId) {
         final List<List<String>> pkgsToSend = new ArrayList(pkgList.length);
         final List<IntArray> uidsToSend = new ArrayList(pkgList.length);
         final List<SparseArray<int[]>> allowListsToSend = new ArrayList(pkgList.length);
@@ -592,8 +602,8 @@
             final String pkgName = pkgList[i];
             final int uid = uidList[i];
             SparseArray<int[]> allowList = mInjector.getAppsFilter().getVisibilityAllowList(
-                    mPm.getPackageStateInternal(pkgName, SYSTEM_UID),
-                    userIds, mPm.getPackageStates());
+                    snapshot.getPackageStateInternal(pkgName, SYSTEM_UID),
+                    userIds, snapshot.getPackageStates());
             if (allowList == null) {
                 allowList = new SparseArray<>(0);
             }
@@ -628,19 +638,22 @@
         }
     }
 
-    private String getKnownPackageName(@KnownPackage int knownPackage, int userId) {
-        final String[] knownPackages = mPm.getKnownPackageNamesInternal(knownPackage, userId);
+    private String getKnownPackageName(@NonNull Computer snapshot, @KnownPackage int knownPackage,
+            int userId) {
+        final String[] knownPackages =
+                mPm.getKnownPackageNamesInternal(snapshot, knownPackage, userId);
         return knownPackages.length > 0 ? knownPackages[0] : null;
     }
 
-    private boolean isCallerDeviceOrProfileOwner(int userId, int callingUid) {
+    private boolean isCallerDeviceOrProfileOwner(@NonNull Computer snapshot, int userId,
+            int callingUid) {
         if (callingUid == SYSTEM_UID) {
             return true;
         }
         final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
         if (ownerPackage != null) {
-            return callingUid == mPm.getPackageUidInternal(
-                    ownerPackage, 0, userId, callingUid);
+            return callingUid == snapshot.getPackageUidInternal(ownerPackage, 0, userId,
+                    callingUid);
         }
         return false;
     }
@@ -659,9 +672,10 @@
                 return;
             }
             final int[] targetUserIds = new int[] {userId};
+            final Computer snapshot = mPm.snapshotComputer();
             for (String packageName : affectedPackages) {
                 final Bundle appExtras = suspended
-                        ? getSuspendedPackageAppExtras(packageName, userId, SYSTEM_UID)
+                        ? getSuspendedPackageAppExtras(snapshot, packageName, userId, SYSTEM_UID)
                         : null;
                 final Bundle intentExtras;
                 if (appExtras != null) {
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index f07c9ec..9c74dd7 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -15,6 +15,9 @@
       "name": "CtsClassloaderSplitsHostTestCases"
     },
     {
+      "name": "CtsCompilationTestCases"
+    },
+    {
       "name": "CtsAppEnumerationTestCases"
     },
     {
@@ -49,9 +52,6 @@
       "options": [
         {
           "include-filter": "com.google.android.security.gts.PackageVerifierTest"
-        },
-        {
-          "exclude-filter": "com.google.android.security.gts.PackageVerifierTest#testAdbInstall_timeout_allowed"
         }
       ]
     },
@@ -111,9 +111,6 @@
     },
     {
       "name": "PackageManagerServiceHostTests"
-    },
-    {
-      "name": "CtsCompilationTestCases"
     }
   ],
   "imports": [
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
index 5047690..95482d7 100644
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
@@ -118,8 +118,11 @@
                     flags | StorageManager.FLAG_STORAGE_DE, false);
             } else {
                 try {
-                    Log.e(TAG, "prepareUserData failed", e);
-                    RecoverySystem.rebootPromptAndWipeUserData(mContext, "prepareUserData failed");
+                    Log.wtf(TAG, "prepareUserData failed for user " + userId, e);
+                    if (userId == UserHandle.USER_SYSTEM) {
+                        RecoverySystem.rebootPromptAndWipeUserData(mContext,
+                                "prepareUserData failed for system user");
+                    }
                 } catch (IOException e2) {
                     throw new RuntimeException("error rebooting into recovery", e2);
                 }
diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index eb2de60..0e6d5e5 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -312,4 +312,12 @@
      */
     public abstract void setDefaultCrossProfileIntentFilters(
             @UserIdInt int parentUserId, @UserIdInt int profileUserId);
+
+    /**
+     * Returns {@code true} if the system should ignore errors when preparing
+     * the storage directories for the user with ID {@code userId}. This will
+     * return {@code false} for all new users; it will only return {@code true}
+     * for users that already existed on-disk from an older version of Android.
+     */
+    public abstract boolean shouldIgnorePrepareStorageErrors(int userId);
 }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index d99305d..34b7ad4 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -211,6 +211,8 @@
     private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions";
     private static final String TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL =
             "lastRequestQuietModeEnabledCall";
+    private static final String TAG_IGNORE_PREPARE_STORAGE_ERRORS =
+            "ignorePrepareStorageErrors";
     private static final String ATTR_KEY = "key";
     private static final String ATTR_VALUE_TYPE = "type";
     private static final String ATTR_MULTIPLE = "m";
@@ -320,6 +322,14 @@
 
         private long mLastRequestQuietModeEnabledMillis;
 
+        /**
+         * {@code true} if the system should ignore errors when preparing the
+         * storage directories for this user. This is {@code false} for all new
+         * users; it will only be {@code true} for users that already existed
+         * on-disk from an older version of Android.
+         */
+        private boolean mIgnorePrepareStorageErrors;
+
         void setLastRequestQuietModeEnabledMillis(long millis) {
             mLastRequestQuietModeEnabledMillis = millis;
         }
@@ -328,6 +338,25 @@
             return mLastRequestQuietModeEnabledMillis;
         }
 
+        boolean getIgnorePrepareStorageErrors() {
+            return mIgnorePrepareStorageErrors;
+        }
+
+        @SuppressWarnings("AndroidFrameworkCompatChange")  // This is not an app-visible API.
+        void setIgnorePrepareStorageErrors() {
+            // This method won't be called for new users.  But to fully rule out
+            // the possibility of mIgnorePrepareStorageErrors ever being true
+            // for any user on any device that launched with T or later, we also
+            // explicitly check that DEVICE_INITIAL_SDK_INT is below T before
+            // honoring the request to set mIgnorePrepareStorageErrors to true.
+            if (Build.VERSION.DEVICE_INITIAL_SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+                mIgnorePrepareStorageErrors = true;
+                return;
+            }
+            Slog.w(LOG_TAG, "Not setting mIgnorePrepareStorageErrors to true"
+                    + " since this is a new device");
+        }
+
         void clearSeedAccountData() {
             seedAccountName = null;
             seedAccountType = null;
@@ -1564,13 +1593,13 @@
     }
 
     @Override
-    public boolean isCredentialSharedWithParent(@UserIdInt int userId) {
+    public boolean isCredentialSharableWithParent(@UserIdInt int userId) {
         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId,
-                "isCredentialSharedWithParent");
+                "isCredentialSharableWithParent");
         synchronized (mUsersLock) {
             UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
             return userTypeDetails != null && userTypeDetails.isProfile()
-                    && userTypeDetails.isCredentialSharedWithParent();
+                    && userTypeDetails.isCredentialSharableWithParent();
         }
     }
 
@@ -3408,6 +3437,10 @@
             serializer.endTag(/* namespace */ null, TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL);
         }
 
+        serializer.startTag(/* namespace */ null, TAG_IGNORE_PREPARE_STORAGE_ERRORS);
+        serializer.text(String.valueOf(userData.getIgnorePrepareStorageErrors()));
+        serializer.endTag(/* namespace */ null, TAG_IGNORE_PREPARE_STORAGE_ERRORS);
+
         serializer.endTag(null, TAG_USER);
 
         serializer.endDocument();
@@ -3517,6 +3550,7 @@
         Bundle legacyLocalRestrictions = null;
         RestrictionsSet localRestrictions = null;
         Bundle globalRestrictions = null;
+        boolean ignorePrepareStorageErrors = true; // default is true for old users
 
         final TypedXmlPullParser parser = Xml.resolvePullParser(is);
         int type;
@@ -3595,6 +3629,11 @@
                     if (type == XmlPullParser.TEXT) {
                         lastRequestQuietModeEnabledTimestamp = Long.parseLong(parser.getText());
                     }
+                } else if (TAG_IGNORE_PREPARE_STORAGE_ERRORS.equals(tag)) {
+                    type = parser.next();
+                    if (type == XmlPullParser.TEXT) {
+                        ignorePrepareStorageErrors = Boolean.parseBoolean(parser.getText());
+                    }
                 }
             }
         }
@@ -3622,6 +3661,9 @@
         userData.persistSeedData = persistSeedData;
         userData.seedAccountOptions = seedAccountOptions;
         userData.setLastRequestQuietModeEnabledMillis(lastRequestQuietModeEnabledTimestamp);
+        if (ignorePrepareStorageErrors) {
+            userData.setIgnorePrepareStorageErrors();
+        }
 
         synchronized (mRestrictionsLock) {
             if (baseRestrictions != null) {
@@ -4106,11 +4148,11 @@
                 continue;
             }
             if (filter.direction == DefaultCrossProfileIntentFilter.Direction.TO_PARENT) {
-                mPm.addCrossProfileIntentFilter(
+                mPm.addCrossProfileIntentFilter(mPm.snapshotComputer(),
                         filter.filter, mContext.getOpPackageName(), profileUserId, parentUserId,
                         filter.flags);
             } else {
-                mPm.addCrossProfileIntentFilter(
+                mPm.addCrossProfileIntentFilter(mPm.snapshotComputer(),
                         filter.filter, mContext.getOpPackageName(), parentUserId, profileUserId,
                         filter.flags);
             }
@@ -4596,12 +4638,12 @@
             final String restriction = getUserRemovalRestriction(userId);
             if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(restriction, false)) {
                 Slog.w(LOG_TAG, "Cannot remove user. " + restriction + " is enabled.");
-                return UserManager.REMOVE_RESULT_ERROR;
+                return UserManager.REMOVE_RESULT_ERROR_USER_RESTRICTION;
             }
         }
         if (userId == UserHandle.USER_SYSTEM) {
             Slog.e(LOG_TAG, "System user cannot be removed.");
-            return UserManager.REMOVE_RESULT_ERROR;
+            return UserManager.REMOVE_RESULT_ERROR_SYSTEM_USER;
         }
 
         final long ident = Binder.clearCallingIdentity();
@@ -4613,7 +4655,7 @@
                     if (userData == null) {
                         Slog.e(LOG_TAG,
                                 "Cannot remove user " + userId + ", invalid user id provided.");
-                        return UserManager.REMOVE_RESULT_ERROR;
+                        return UserManager.REMOVE_RESULT_ERROR_USER_NOT_FOUND;
                     }
 
                     if (mRemovingUserIds.get(userId)) {
@@ -5732,6 +5774,9 @@
                 pw.println();
             }
         }
+
+        pw.println("    Ignore errors preparing storage: "
+                + userData.getIgnorePrepareStorageErrors());
     }
 
     private static void dumpTimeAgo(PrintWriter pw, StringBuilder sb, long nowTime, long time) {
@@ -6135,6 +6180,14 @@
             UserManagerService.this.setDefaultCrossProfileIntentFilters(
                     profileUserId, userTypeDetails, restrictions, parentUserId);
         }
+
+        @Override
+        public boolean shouldIgnorePrepareStorageErrors(int userId) {
+            synchronized (mUsersLock) {
+                UserData userData = mUsers.get(userId);
+                return userData != null && userData.getIgnorePrepareStorageErrors();
+            }
+        }
     }
 
     /**
@@ -6297,7 +6350,8 @@
      * {@link SecurityException} if not.
      */
     private void verifyCallingPackage(String callingPackage, int callingUid) {
-        int packageUid = mPm.getPackageUid(callingPackage, 0,  UserHandle.getUserId(callingUid));
+        int packageUid = mPm.snapshotComputer()
+                .getPackageUid(callingPackage, 0,  UserHandle.getUserId(callingUid));
         if (packageUid != callingUid) {
             throw new SecurityException("Specified package " + callingPackage
                     + " does not match the calling uid " + callingUid);
diff --git a/services/core/java/com/android/server/pm/UserTypeDetails.java b/services/core/java/com/android/server/pm/UserTypeDetails.java
index 2f5e238..4aad1a7 100644
--- a/services/core/java/com/android/server/pm/UserTypeDetails.java
+++ b/services/core/java/com/android/server/pm/UserTypeDetails.java
@@ -161,7 +161,7 @@
      *
      * <p> Default value is false
      */
-    private final boolean mIsCredentialSharedWithParent;
+    private final boolean mIsCredentialSharableWithParent;
 
     private UserTypeDetails(@NonNull String name, boolean enabled, int maxAllowed,
             @UserInfoFlag int baseType, @UserInfoFlag int defaultUserInfoPropertyFlags, int label,
@@ -174,7 +174,7 @@
             @Nullable Bundle defaultSecureSettings,
             @Nullable List<DefaultCrossProfileIntentFilter> defaultCrossProfileIntentFilters,
             boolean isMediaSharedWithParent,
-            boolean isCredentialSharedWithParent) {
+            boolean isCredentialSharableWithParent) {
         this.mName = name;
         this.mEnabled = enabled;
         this.mMaxAllowed = maxAllowed;
@@ -194,7 +194,7 @@
         this.mBadgeColors = badgeColors;
         this.mDarkThemeBadgeColors = darkThemeBadgeColors;
         this.mIsMediaSharedWithParent = isMediaSharedWithParent;
-        this.mIsCredentialSharedWithParent = isCredentialSharedWithParent;
+        this.mIsCredentialSharableWithParent = isCredentialSharableWithParent;
     }
 
     /**
@@ -323,8 +323,8 @@
      * Returns true if the user has shared encryption credential with parent user or
      * false otherwise.
      */
-    public boolean isCredentialSharedWithParent() {
-        return mIsCredentialSharedWithParent;
+    public boolean isCredentialSharableWithParent() {
+        return mIsCredentialSharableWithParent;
     }
 
     /** Returns a {@link Bundle} representing the default user restrictions. */
@@ -419,7 +419,7 @@
         private @DrawableRes int mBadgePlain = Resources.ID_NULL;
         private @DrawableRes int mBadgeNoBackground = Resources.ID_NULL;
         private boolean mIsMediaSharedWithParent = false;
-        private boolean mIsCredentialSharedWithParent = false;
+        private boolean mIsCredentialSharableWithParent = false;
 
         public Builder setName(String name) {
             mName = name;
@@ -521,10 +521,10 @@
 
         /**
          * Sets shared media property for the user.
-         * @param isCredentialSharedWithParent  the value to be set, true or false
+         * @param isCredentialSharableWithParent  the value to be set, true or false
          */
-        public Builder setIsCredentialSharedWithParent(boolean isCredentialSharedWithParent) {
-            mIsCredentialSharedWithParent = isCredentialSharedWithParent;
+        public Builder setIsCredentialSharableWithParent(boolean isCredentialSharableWithParent) {
+            mIsCredentialSharableWithParent = isCredentialSharableWithParent;
             return this;
         }
 
@@ -571,7 +571,7 @@
                     mDefaultSecureSettings,
                     mDefaultCrossProfileIntentFilters,
                     mIsMediaSharedWithParent,
-                    mIsCredentialSharedWithParent);
+                    mIsCredentialSharableWithParent);
         }
 
         private boolean hasBadge() {
diff --git a/services/core/java/com/android/server/pm/UserTypeFactory.java b/services/core/java/com/android/server/pm/UserTypeFactory.java
index 1e3b67c..cb18c6d 100644
--- a/services/core/java/com/android/server/pm/UserTypeFactory.java
+++ b/services/core/java/com/android/server/pm/UserTypeFactory.java
@@ -122,7 +122,7 @@
                 .setLabel(0)
                 .setDefaultRestrictions(null)
                 .setIsMediaSharedWithParent(true)
-                .setIsCredentialSharedWithParent(true);
+                .setIsCredentialSharableWithParent(true);
     }
 
     /**
@@ -154,7 +154,7 @@
                 .setDefaultRestrictions(getDefaultManagedProfileRestrictions())
                 .setDefaultSecureSettings(getDefaultManagedProfileSecureSettings())
                 .setDefaultCrossProfileIntentFilters(getDefaultManagedCrossProfileIntentFilter())
-                .setIsCredentialSharedWithParent(true);
+                .setIsCredentialSharableWithParent(true);
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/VerificationParams.java b/services/core/java/com/android/server/pm/VerificationParams.java
index 4334cbd..7423bf6 100644
--- a/services/core/java/com/android/server/pm/VerificationParams.java
+++ b/services/core/java/com/android/server/pm/VerificationParams.java
@@ -72,6 +72,7 @@
 import android.util.Slog;
 
 import com.android.server.DeviceIdleInternal;
+import com.android.server.sdksandbox.SdkSandboxManagerLocal;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -372,9 +373,10 @@
          * Determine if we have any installed package verifiers. If we
          * do, then we'll defer to them to verify the packages.
          */
+        final Computer snapshot = mPm.snapshotComputer();
         final int requiredUid = requiredVerifierPackage == null ? -1
-                : mPm.getPackageUid(requiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
-                        verifierUserId);
+                : snapshot.getPackageUid(requiredVerifierPackage,
+                        MATCH_DEBUG_TRIAGED_MISSING, verifierUserId);
         verificationState.setRequiredVerifierUid(requiredUid);
         final boolean isVerificationEnabled = isVerificationEnabled(pkgLite,
                 verifierUserId);
@@ -391,8 +393,8 @@
         verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 
         // Query all live verifiers based on current user state
-        final ParceledListSlice<ResolveInfo> receivers = mPm.queryIntentReceivers(verification,
-                PACKAGE_MIME_TYPE, 0, verifierUserId);
+        final ParceledListSlice<ResolveInfo> receivers = mPm.queryIntentReceivers(snapshot,
+                verification, PACKAGE_MIME_TYPE, 0, verifierUserId);
 
         if (DEBUG_VERIFY) {
             Slog.d(TAG, "Found " + receivers.getList().size() + " verifiers for intent "
@@ -440,9 +442,22 @@
         final long verificationTimeout = VerificationUtils.getVerificationTimeout(mPm.mContext,
                 streaming);
 
-        final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
+        List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
                 receivers.getList(), verificationState);
 
+        // Add broadcastReceiver Component to verify Sdk before run in Sdk sandbox.
+        if (pkgLite.isSdkLibrary) {
+            if (sufficientVerifiers == null) {
+                sufficientVerifiers = new ArrayList<>();
+            }
+            ComponentName sdkSandboxComponentName = new ComponentName("android",
+                    SdkSandboxManagerLocal.VERIFIER_RECEIVER);
+            sufficientVerifiers.add(sdkSandboxComponentName);
+
+            // Add uid of system_server the same uid for SdkSandboxManagerService
+            verificationState.addSufficientVerifier(Process.myUid());
+        }
+
         DeviceIdleInternal idleController =
                 mPm.mInjector.getLocalService(DeviceIdleInternal.class);
         final BroadcastOptions options = BroadcastOptions.makeBasic();
diff --git a/services/core/java/com/android/server/pm/WatchedIntentFilter.java b/services/core/java/com/android/server/pm/WatchedIntentFilter.java
index 30f276e..5d7a2a3 100644
--- a/services/core/java/com/android/server/pm/WatchedIntentFilter.java
+++ b/services/core/java/com/android/server/pm/WatchedIntentFilter.java
@@ -84,7 +84,7 @@
     }
 
     // Convert an {@link IntentFilter} to a {@link WatchedIntentFilter}
-    protected WatchedIntentFilter(IntentFilter f) {
+    public WatchedIntentFilter(IntentFilter f) {
         mFilter = new IntentFilter(f);
     }
 
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index e28a6ea..7e4da94 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -31,13 +31,13 @@
 import android.content.pm.dex.DexMetadataHelper;
 import android.content.pm.dex.ISnapshotRuntimeProfileCallback;
 import android.content.pm.dex.PackageOptimizationInfo;
-import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Handler;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.system.Os;
@@ -55,6 +55,7 @@
 import com.android.server.pm.Installer.InstallerException;
 import com.android.server.pm.PackageManagerServiceCompilerMapping;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
 
 import dalvik.system.DexFile;
 import dalvik.system.VMRuntime;
@@ -92,7 +93,7 @@
     private static final String BOOT_IMAGE_PROFILE_NAME = "android.prof";
 
     private final Context mContext;
-    private final IPackageManager mPackageManager;
+    private IPackageManager mPackageManager;
     private final Object mInstallLock;
     @GuardedBy("mInstallLock")
     private final Installer mInstaller;
@@ -103,10 +104,9 @@
         verifyTronLoggingConstants();
     }
 
-    public ArtManagerService(Context context, IPackageManager pm, Installer installer,
+    public ArtManagerService(Context context, Installer installer,
             Object installLock) {
         mContext = context;
-        mPackageManager = pm;
         mInstaller = installer;
         mInstallLock = installLock;
         mHandler = new Handler(BackgroundThread.getHandler().getLooper());
@@ -114,6 +114,15 @@
         LocalServices.addService(ArtManagerInternal.class, new ArtManagerInternalImpl());
     }
 
+    @NonNull
+    private IPackageManager getPackageManager() {
+        if (mPackageManager == null) {
+            mPackageManager = IPackageManager.Stub.asInterface(
+                    ServiceManager.getService("package"));
+        }
+        return mPackageManager;
+    }
+
     private boolean checkAndroidPermissions(int callingUid, String callingPackage) {
         // Callers always need this permission
         mContext.enforceCallingOrSelfPermission(
@@ -157,7 +166,7 @@
         }
         PackageInfo info = null;
         try {
-            info = mPackageManager.getPackageInfo(packageName, /*flags*/ 0, /*userId*/ 0);
+            info =  getPackageManager().getPackageInfo(packageName, /*flags*/ 0, /*userId*/ 0);
         } catch (RemoteException ignored) {
             // Should not happen.
         }
@@ -221,7 +230,7 @@
 
             // TODO(calin): consider adding an API to PMS which can retrieve the
             // PackageParser.Package.
-            info = mPackageManager.getPackageInfo(packageName, /*flags*/ 0, /*userId*/ 0);
+            info =  getPackageManager().getPackageInfo(packageName, /*flags*/ 0, /*userId*/ 0);
         } catch (RemoteException ignored) {
             // Should not happen.
         }
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 5371454..17109e9 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -23,6 +23,8 @@
 
 import static java.util.function.Function.identity;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
@@ -33,6 +35,7 @@
 import android.os.FileUtils;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
@@ -109,7 +112,7 @@
     // record class loaders or ISAs.)
     private final DynamicCodeLogger mDynamicCodeLogger;
 
-    private final IPackageManager mPackageManager;
+    private IPackageManager mPackageManager;
     private final PackageDexOptimizer mPackageDexOptimizer;
     private final Object mInstallLock;
     @GuardedBy("mInstallLock")
@@ -128,16 +131,22 @@
     private static int DEX_SEARCH_FOUND_SPLIT = 2;  // dex file is a split apk
     private static int DEX_SEARCH_FOUND_SECONDARY = 3;  // dex file is a secondary dex
 
-    public DexManager(Context context, IPackageManager pms, PackageDexOptimizer pdo,
-            Installer installer, Object installLock) {
+    public DexManager(Context context, PackageDexOptimizer pdo, Installer installer,
+            Object installLock) {
+        this(context, pdo, installer, installLock, null);
+    }
+
+    @VisibleForTesting
+    public DexManager(Context context, PackageDexOptimizer pdo, Installer installer,
+            Object installLock, @Nullable IPackageManager packageManager) {
         mContext = context;
         mPackageCodeLocationsCache = new HashMap<>();
         mPackageDexUsage = new PackageDexUsage();
-        mPackageManager = pms;
         mPackageDexOptimizer = pdo;
         mInstaller = installer;
         mInstallLock = installLock;
-        mDynamicCodeLogger = new DynamicCodeLogger(pms, installer);
+        mDynamicCodeLogger = new DynamicCodeLogger(installer);
+        mPackageManager = packageManager;
 
         // This is currently checked to handle tests that pass in a null context.
         // TODO(b/174783329): Modify the tests to pass in a mocked Context, PowerManager,
@@ -157,6 +166,15 @@
         }
     }
 
+    @NonNull
+    private IPackageManager getPackageManager() {
+        if (mPackageManager == null) {
+            mPackageManager = IPackageManager.Stub.asInterface(
+                    ServiceManager.getService("package"));
+        }
+        return mPackageManager;
+    }
+
     public DynamicCodeLogger getDynamicCodeLogger() {
         return mDynamicCodeLogger;
     }
@@ -529,7 +547,7 @@
 
             PackageInfo pkg;
             try {
-                pkg = mPackageManager.getPackageInfo(packageName, /*flags*/0,
+                pkg = getPackageManager().getPackageInfo(packageName, /*flags*/0,
                     dexUseInfo.getOwnerUserId());
             } catch (RemoteException e) {
                 throw new AssertionError(e);
@@ -673,7 +691,7 @@
                 // to get back the real app uid and its storage kind. These are only used
                 // to perform extra validation in installd.
                 // TODO(calin): maybe a bit overkill.
-                pkg = mPackageManager.getPackageInfo(packageName, /*flags*/0,
+                pkg = getPackageManager().getPackageInfo(packageName, /*flags*/0,
                     dexUseInfo.getOwnerUserId());
             } catch (RemoteException ignore) {
                 // Can't happen, DexManager is local.
diff --git a/services/core/java/com/android/server/pm/dex/DynamicCodeLogger.java b/services/core/java/com/android/server/pm/dex/DynamicCodeLogger.java
index 75b4e38..9b94e99 100644
--- a/services/core/java/com/android/server/pm/dex/DynamicCodeLogger.java
+++ b/services/core/java/com/android/server/pm/dex/DynamicCodeLogger.java
@@ -19,11 +19,13 @@
 import static com.android.server.pm.dex.PackageDynamicCodeLoading.FILE_TYPE_DEX;
 import static com.android.server.pm.dex.PackageDynamicCodeLoading.FILE_TYPE_NATIVE;
 
+import android.annotation.NonNull;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.os.FileUtils;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.util.EventLog;
@@ -58,20 +60,30 @@
     private static final String DCL_DEX_SUBTAG = "dcl";
     private static final String DCL_NATIVE_SUBTAG = "dcln";
 
-    private final IPackageManager mPackageManager;
+    private IPackageManager mPackageManager;
     private final PackageDynamicCodeLoading mPackageDynamicCodeLoading;
     private final Installer mInstaller;
 
-    DynamicCodeLogger(IPackageManager pms, Installer installer) {
-        this(pms, installer, new PackageDynamicCodeLoading());
+    DynamicCodeLogger(Installer installer) {
+        mInstaller = installer;
+        mPackageDynamicCodeLoading = new PackageDynamicCodeLoading();
     }
 
     @VisibleForTesting
-    DynamicCodeLogger(IPackageManager pms, Installer installer,
-            PackageDynamicCodeLoading packageDynamicCodeLoading) {
-        mPackageManager = pms;
-        mPackageDynamicCodeLoading = packageDynamicCodeLoading;
+    DynamicCodeLogger(@NonNull IPackageManager packageManager, @NonNull Installer installer,
+            @NonNull PackageDynamicCodeLoading packageDynamicCodeLoading) {
+        mPackageManager = packageManager;
         mInstaller = installer;
+        mPackageDynamicCodeLoading = packageDynamicCodeLoading;
+    }
+
+    @NonNull
+    private IPackageManager getPackageManager() {
+        if (mPackageManager == null) {
+            mPackageManager = IPackageManager.Stub.asInterface(
+                    ServiceManager.getService("package"));
+        }
+        return mPackageManager;
     }
 
     public Set<String> getAllPackagesWithDynamicCodeLoading() {
@@ -104,7 +116,7 @@
 
                 try {
                     PackageInfo ownerInfo =
-                            mPackageManager.getPackageInfo(packageName, /*flags*/ 0, userId);
+                            getPackageManager().getPackageInfo(packageName, /*flags*/ 0, userId);
                     appInfo = ownerInfo == null ? null : ownerInfo.applicationInfo;
                 } catch (RemoteException ignored) {
                     // Can't happen, we're local.
@@ -167,7 +179,7 @@
                     loadingUid = appInfo.uid;
                 } else {
                     try {
-                        loadingUid = mPackageManager.getPackageUid(loadingPackageName, /*flags*/ 0,
+                        loadingUid =  getPackageManager().getPackageUid(loadingPackageName, /*flags*/ 0,
                                 userId);
                     } catch (RemoteException ignored) {
                         // Can't happen, we're local.
@@ -223,7 +235,7 @@
     public void recordNative(int loadingUid, String path) {
         String[] packages;
         try {
-            packages = mPackageManager.getPackagesForUid(loadingUid);
+            packages =  getPackageManager().getPackagesForUid(loadingUid);
             if (packages == null || packages.length == 0) {
                 return;
             }
diff --git a/services/core/java/com/android/server/pm/dex/OWNERS b/services/core/java/com/android/server/pm/dex/OWNERS
index 052a4ca..5ca8ddd 100644
--- a/services/core/java/com/android/server/pm/dex/OWNERS
+++ b/services/core/java/com/android/server/pm/dex/OWNERS
@@ -1,3 +1,4 @@
 alanstokes@google.com
 jiakaiz@google.com
 ngeoffray@google.com
+mast@google.com
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 63469cb..8d1bcfc 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -122,6 +122,12 @@
         info.isStub = pkg.isStub();
         info.coreApp = pkg.isCoreApp();
 
+        if (pkgSetting != null && !pkgSetting.hasSharedUser()) {
+            // It is possible that this shared UID app has left
+            info.sharedUserId = null;
+            info.sharedUserLabel = 0;
+        }
+
         if ((flags & PackageManager.GET_ACTIVITIES) != 0) {
             final int N = pkg.getActivities().size();
             if (N > 0) {
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 9961ae5..d060930 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -1403,7 +1403,7 @@
                 }
             } else {
                 if (ps.getUserStateOrDefault(userId).isInstantApp() && !bp.isInstant()) {
-                    throw new SecurityException("Cannot grant non-ephemeral permission" + permName
+                    throw new SecurityException("Cannot grant non-ephemeral permission " + permName
                             + " for package " + packageName);
                 }
 
@@ -3291,10 +3291,13 @@
         } else if (pkg.isSystemExt()) {
             permissions = systemConfig.getSystemExtPrivAppPermissions(pkg.getPackageName());
         } else if (containingApexPackageName != null) {
+            final ApexManager apexManager = ApexManager.getInstance();
+            final String apexName = apexManager.getApexModuleNameForPackageName(
+                    containingApexPackageName);
             final Set<String> privAppPermissions = systemConfig.getPrivAppPermissions(
                     pkg.getPackageName());
             final Set<String> apexPermissions = systemConfig.getApexPrivAppPermissions(
-                    containingApexPackageName, pkg.getPackageName());
+                    apexName, pkg.getPackageName());
             if (privAppPermissions != null) {
                 // TODO(andreionea): Remove check as soon as all apk-in-apex
                 // permission allowlists are migrated.
@@ -3532,8 +3535,9 @@
         final Boolean granted =
                 SystemConfig.getInstance().getOemPermissions(pkg.getPackageName()).get(permission);
         if (granted == null) {
-            throw new IllegalStateException("OEM permission" + permission + " requested by package "
-                    + pkg.getPackageName() + " must be explicitly declared granted or not");
+            throw new IllegalStateException("OEM permission " + permission
+                    + " requested by package " + pkg.getPackageName()
+                    + " must be explicitly declared granted or not");
         }
         return Boolean.TRUE == granted;
     }
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
index f6f9faf..40f859c 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
@@ -287,9 +287,6 @@
 
     ParsingPackage setInstallLocation(int installLocation);
 
-    /** @see R#styleable.AndroidManifest_inheritKeyStoreKeys */
-    ParsingPackage setInheritKeyStoreKeys(boolean inheritKeyStoreKeys);
-
     /** @see R#styleable.AndroidManifest_sharedUserMaxSdkVersion */
     ParsingPackage setLeavingSharedUid(boolean leavingSharedUid);
 
@@ -305,6 +302,8 @@
 
     ParsingPackage setMinSdkVersion(int minSdkVersion);
 
+    ParsingPackage setMaxSdkVersion(int maxSdkVersion);
+
     ParsingPackage setNetworkSecurityConfigRes(int networkSecurityConfigRes);
 
     ParsingPackage setNonLocalizedLabel(CharSequence nonLocalizedLabel);
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
index 6767027..67d9aec 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
@@ -383,6 +383,7 @@
     @Nullable
     private SparseIntArray minExtensionVersions;
     private int minSdkVersion = ParsingUtils.DEFAULT_MIN_SDK_VERSION;
+    private int maxSdkVersion = ParsingUtils.DEFAULT_MAX_SDK_VERSION;
     private int networkSecurityConfigRes;
     @Nullable
     private CharSequence nonLocalizedLabel;
@@ -494,7 +495,6 @@
                 ATTRIBUTIONS_ARE_USER_VISIBLE,
                 RESET_ENABLED_SETTINGS_ON_APP_DATA_CLEARED,
                 SDK_LIBRARY,
-                INHERIT_KEYSTORE_KEYS,
         })
         public @interface Values {}
         private static final long EXTERNAL_STORAGE = 1L;
@@ -547,9 +547,8 @@
         private static final long ATTRIBUTIONS_ARE_USER_VISIBLE = 1L << 47;
         private static final long RESET_ENABLED_SETTINGS_ON_APP_DATA_CLEARED = 1L << 48;
         private static final long SDK_LIBRARY = 1L << 49;
-        private static final long INHERIT_KEYSTORE_KEYS = 1L << 50;
-        private static final long ENABLE_ON_BACK_INVOKED_CALLBACK = 1L << 51;
-        private static final long LEAVING_SHARED_UID = 1L << 52;
+        private static final long ENABLE_ON_BACK_INVOKED_CALLBACK = 1L << 50;
+        private static final long LEAVING_SHARED_UID = 1L << 51;
     }
 
     private ParsingPackageImpl setBoolean(@Booleans.Values long flag, boolean value) {
@@ -1308,6 +1307,7 @@
         dest.writeFloat(this.maxAspectRatio);
         dest.writeFloat(this.minAspectRatio);
         dest.writeInt(this.minSdkVersion);
+        dest.writeInt(this.maxSdkVersion);
         dest.writeInt(this.networkSecurityConfigRes);
         dest.writeCharSequence(this.nonLocalizedLabel);
         dest.writeString(this.permission);
@@ -1456,6 +1456,7 @@
         this.maxAspectRatio = in.readFloat();
         this.minAspectRatio = in.readFloat();
         this.minSdkVersion = in.readInt();
+        this.maxSdkVersion = in.readInt();
         this.networkSecurityConfigRes = in.readInt();
         this.nonLocalizedLabel = in.readCharSequence();
         this.permission = in.readString();
@@ -2070,6 +2071,11 @@
     }
 
     @Override
+    public int getMaxSdkVersion() {
+        return maxSdkVersion;
+    }
+
+    @Override
     public int getNetworkSecurityConfigRes() {
         return networkSecurityConfigRes;
     }
@@ -2394,11 +2400,6 @@
     }
 
     @Override
-    public boolean shouldInheritKeyStoreKeys() {
-        return getBoolean(Booleans.INHERIT_KEYSTORE_KEYS);
-    }
-
-    @Override
     public boolean isOnBackInvokedCallbackEnabled() {
         return getBoolean(Booleans.ENABLE_ON_BACK_INVOKED_CALLBACK);
     }
@@ -2552,11 +2553,6 @@
     }
 
     @Override
-    public ParsingPackageImpl setInheritKeyStoreKeys(boolean value) {
-        return setBoolean(Booleans.INHERIT_KEYSTORE_KEYS, value);
-    }
-
-    @Override
     public ParsingPackageImpl setLeavingSharedUid(boolean value) {
         return setBoolean(Booleans.LEAVING_SHARED_UID, value);
     }
@@ -2604,6 +2600,12 @@
     }
 
     @Override
+    public ParsingPackageImpl setMaxSdkVersion(int value) {
+        maxSdkVersion = value;
+        return this;
+    }
+
+    @Override
     public ParsingPackageImpl setNetworkSecurityConfigRes(int value) {
         networkSecurityConfigRes = value;
         return this;
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java
index 50033f6..20b1ed8 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java
@@ -352,11 +352,6 @@
     int getLocaleConfigRes();
 
     /**
-     * @see R.styleable#AndroidManifest_inheritKeyStoreKeys
-     */
-    boolean shouldInheritKeyStoreKeys();
-
-    /**
      * @see R.styleable.AndroidManifestApplication_enableOnBackInvokedCallback
      */
     boolean isOnBackInvokedCallbackEnabled();
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index ed1ab01..b323948 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -91,6 +91,7 @@
 import com.android.internal.os.ClassLoaderFactory;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.XmlUtils;
+import com.android.server.pm.SharedUidMigration;
 import com.android.server.pm.permission.CompatibilityPermissionInfo;
 import com.android.server.pm.pkg.component.ComponentMutateUtils;
 import com.android.server.pm.pkg.component.ComponentParseUtils;
@@ -208,6 +209,8 @@
 
     public static final int SDK_VERSION = Build.VERSION.SDK_INT;
     public static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES;
+    public static final String[] PREVIOUS_CODENAMES =
+            Build.VERSION.KNOWN_CODENAMES.toArray(new String[]{});
 
     public static boolean sCompatibilityModeEnabled = true;
     public static boolean sUseRoundIcon = false;
@@ -235,6 +238,7 @@
      */
     public static final int PARSE_IGNORE_OVERLAY_REQUIRED_SYSTEM_PROPERTY = 1 << 7;
     public static final int PARSE_FRAMEWORK_RES_SPLITS = 1 << 8;
+    public static final int PARSE_CHECK_MAX_SDK_VERSION = 1 << 9;
 
     public static final int PARSE_CHATTY = 1 << 31;
 
@@ -893,9 +897,7 @@
                 .setTargetSandboxVersion(anInteger(PARSE_DEFAULT_TARGET_SANDBOX,
                         R.styleable.AndroidManifest_targetSandboxVersion, sa))
                 /* Set the global "on SD card" flag */
-                .setExternalStorage((flags & PARSE_EXTERNAL_STORAGE) != 0)
-                .setInheritKeyStoreKeys(bool(false,
-                        R.styleable.AndroidManifest_inheritKeyStoreKeys, sa));
+                .setExternalStorage((flags & PARSE_EXTERNAL_STORAGE) != 0);
 
         boolean foundApp = false;
         final int depth = parser.getDepth();
@@ -1003,7 +1005,7 @@
             case TAG_FEATURE_GROUP:
                 return parseFeatureGroup(input, pkg, res, parser);
             case TAG_USES_SDK:
-                return parseUsesSdk(input, pkg, res, parser);
+                return parseUsesSdk(input, pkg, res, parser, flags);
             case TAG_SUPPORT_SCREENS:
                 return parseSupportScreens(input, pkg, res, parser);
             case TAG_PROTECTED_BROADCAST:
@@ -1047,8 +1049,11 @@
             }
         }
 
-        int maxSdkVersion = anInteger(0, R.styleable.AndroidManifest_sharedUserMaxSdkVersion, sa);
-        boolean leaving = (maxSdkVersion != 0) && (maxSdkVersion < Build.VERSION.RESOURCES_SDK_INT);
+        boolean leaving = false;
+        if (!SharedUidMigration.isDisabled()) {
+            int max = anInteger(0, R.styleable.AndroidManifest_sharedUserMaxSdkVersion, sa);
+            leaving = (max != 0) && (max < Build.VERSION.RESOURCES_SDK_INT);
+        }
 
         return input.success(pkg
                 .setLeavingSharedUid(leaving)
@@ -1512,15 +1517,17 @@
     }
 
     private static ParseResult<ParsingPackage> parseUsesSdk(ParseInput input,
-            ParsingPackage pkg, Resources res, XmlResourceParser parser)
+            ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags)
             throws IOException, XmlPullParserException {
         if (SDK_VERSION > 0) {
+            final boolean checkMaxSdkVersion = (flags & PARSE_CHECK_MAX_SDK_VERSION) != 0;
             TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesSdk);
             try {
                 int minVers = ParsingUtils.DEFAULT_MIN_SDK_VERSION;
                 String minCode = null;
                 int targetVers = ParsingUtils.DEFAULT_TARGET_SDK_VERSION;
                 String targetCode = null;
+                int maxVers = Integer.MAX_VALUE;
 
                 TypedValue val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_minSdkVersion);
                 if (val != null) {
@@ -1548,6 +1555,14 @@
                     targetCode = minCode;
                 }
 
+                if (checkMaxSdkVersion) {
+                    val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_maxSdkVersion);
+                    if (val != null) {
+                        // maxSdkVersion only supports integer
+                        maxVers = val.data;
+                    }
+                }
+
                 ParseResult<Integer> targetSdkVersionResult = FrameworkParsingPackageUtils
                         .computeTargetSdkVersion(targetVers, targetCode, SDK_CODENAMES, input);
                 if (targetSdkVersionResult.isError()) {
@@ -1572,6 +1587,15 @@
 
                 pkg.setMinSdkVersion(minSdkVersion)
                         .setTargetSdkVersion(targetSdkVersion);
+                if (checkMaxSdkVersion) {
+                    ParseResult<Integer> maxSdkVersionResult = FrameworkParsingPackageUtils
+                            .computeMaxSdkVersion(maxVers, SDK_VERSION, input);
+                    if (maxSdkVersionResult.isError()) {
+                        return input.error(maxSdkVersionResult);
+                    }
+                    int maxSdkVersion = maxSdkVersionResult.getResult();
+                    pkg.setMaxSdkVersion(maxSdkVersion);
+                }
 
                 int type;
                 final int innerDepth = parser.getDepth();
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingUtils.java
index cb474df..0751285 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingUtils.java
@@ -50,6 +50,7 @@
     public static final String ANDROID_RES_NAMESPACE = "http://schemas.android.com/apk/res/android";
 
     public static final int DEFAULT_MIN_SDK_VERSION = 1;
+    public static final int DEFAULT_MAX_SDK_VERSION = Integer.MAX_VALUE;
     public static final int DEFAULT_TARGET_SDK_VERSION = 0;
 
     public static final int NOT_SET = -1;
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/PkgWithoutStateAppInfo.java b/services/core/java/com/android/server/pm/pkg/parsing/PkgWithoutStateAppInfo.java
index 3205b76..99bcdb96 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/PkgWithoutStateAppInfo.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/PkgWithoutStateAppInfo.java
@@ -250,6 +250,11 @@
     int getMinSdkVersion();
 
     /**
+     * @see R.styleable#AndroidManifestUsesSdk_maxSdkVersion
+     */
+    int getMaxSdkVersion();
+
+    /**
      * @see ApplicationInfo#getNativeHeapZeroInitialized()
      * @see R.styleable#AndroidManifestApplication_nativeHeapZeroInitialized
      */
diff --git a/services/core/java/com/android/server/policy/KeyCombinationManager.java b/services/core/java/com/android/server/policy/KeyCombinationManager.java
index 68e078c..9213c87 100644
--- a/services/core/java/com/android/server/policy/KeyCombinationManager.java
+++ b/services/core/java/com/android/server/policy/KeyCombinationManager.java
@@ -48,7 +48,7 @@
     // The rule has been triggered by current keys.
     @GuardedBy("mLock")
     private TwoKeysCombinationRule mTriggeredRule;
-    private final Handler mHandler = new Handler();
+    private final Handler mHandler;
 
     // Keys in a key combination must be pressed within this interval of each other.
     private static final long COMBINE_KEY_DELAY_MILLIS = 150;
@@ -93,6 +93,11 @@
             return false;
         }
 
+        // The excessive delay before it dispatching to client.
+        long getKeyInterceptDelayMs() {
+            return COMBINE_KEY_DELAY_MILLIS;
+        }
+
         abstract void execute();
         abstract void cancel();
 
@@ -103,7 +108,8 @@
         }
     }
 
-    public KeyCombinationManager() {
+    public KeyCombinationManager(Handler handler) {
+        mHandler = handler;
     }
 
     void addRule(TwoKeysCombinationRule rule) {
@@ -195,10 +201,18 @@
      */
     long getKeyInterceptTimeout(int keyCode) {
         synchronized (mLock) {
-            if (forAllActiveRules((rule) -> rule.shouldInterceptKey(keyCode))) {
-                return mDownTimes.get(keyCode) + COMBINE_KEY_DELAY_MILLIS;
+            if (mDownTimes.get(keyCode) == 0) {
+                return 0;
             }
-            return 0;
+            long delayMs = 0;
+            for (final TwoKeysCombinationRule rule : mActiveRules) {
+                if (rule.shouldInterceptKey(keyCode)) {
+                    delayMs = Math.max(delayMs, rule.getKeyInterceptDelayMs());
+                }
+            }
+            // Make sure the delay is less than COMBINE_KEY_DELAY_MILLIS.
+            delayMs = Math.min(delayMs, COMBINE_KEY_DELAY_MILLIS);
+            return mDownTimes.get(keyCode) + delayMs;
         }
     }
 
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyInternal.java b/services/core/java/com/android/server/policy/PermissionPolicyInternal.java
index 20b7ccd..92b9944 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyInternal.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyInternal.java
@@ -57,6 +57,7 @@
      * prompt should be shown if the app targets S-, is currently running in a visible, focused
      * task, has the REVIEW_REQUIRED flag set on its implicit notification permission, and has
      * created at least one notification channel (even if it has since been deleted).
+     *
      * @param packageName The package whose permission is being checked
      * @param userId The user for whom the package is being started
      * @param taskId The task the notification prompt should be attached to
@@ -66,10 +67,22 @@
 
     /**
      * Determine if a particular task is in the proper state to show a system-triggered permission
-     * prompt. A prompt can be shown if the task is focused, visible, and running.
+     * prompt. A prompt can be shown if the task is focused, visible, and running and
+     * 1. The intent is a launcher intent (action is ACTION_MAIN, category is LAUNCHER), or
+     * 2. The activity belongs to the same package as the one which launched the task originally,
+     * and the task was started with a launcher intent
+     *
      * @param taskInfo The task to be checked
+     * @param currPkg The package of the current top visible activity
+     * @param intent The intent of the current top visible activity
      */
-    public abstract boolean canShowPermissionPromptForTask(@Nullable TaskInfo taskInfo);
+    public abstract boolean shouldShowNotificationDialogForTask(@Nullable TaskInfo taskInfo,
+            @Nullable String currPkg, @Nullable Intent intent);
+
+    /**
+     * @return true if an intent will resolve to a permission request dialog activity
+     */
+    public abstract boolean isIntentToPermissionDialog(@NonNull Intent intent);
 
     /**
      * @return Whether the policy is initialized for a user.
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index f2ce0d4..70ef3d3 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -21,6 +21,8 @@
 import static android.app.AppOpsManager.MODE_FOREGROUND;
 import static android.app.AppOpsManager.MODE_IGNORED;
 import static android.app.AppOpsManager.OP_NONE;
+import static android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS;
+import static android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
@@ -54,6 +56,8 @@
 import android.content.pm.PermissionInfo;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -109,6 +113,7 @@
     private static final String SYSTEM_PKG = "android";
     private static final boolean DEBUG = false;
     private static final long USER_SENSITIVE_UPDATE_DELAY_MS = 60000;
+    private static final long ACTIVITY_START_DELAY_MS = 200;
 
     private final Object mLock = new Object();
 
@@ -149,6 +154,7 @@
     private List<String> mAppOpPermissions;
 
     private Context mContext;
+    private Handler mHandler;
     private PackageManagerInternal mPackageManagerInternal;
     private NotificationManagerInternal mNotificationManager;
     private final KeyguardManager mKeyguardManager;
@@ -158,6 +164,7 @@
         super(context);
 
         mContext = context;
+        mHandler = new Handler(Looper.getMainLooper());
         mPackageManager = context.getPackageManager();
         mKeyguardManager = context.getSystemService(KeyguardManager.class);
         LocalServices.addService(PermissionPolicyInternal.class, new Internal());
@@ -1016,7 +1023,7 @@
                             ActivityInterceptorInfo info) {
                         String action = info.intent.getAction();
                         ActivityInterceptResult result = null;
-                        if (!PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(action)
+                        if (!ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(action)
                                 && !PackageManager.ACTION_REQUEST_PERMISSIONS.equals(action)) {
                             return null;
                         }
@@ -1033,7 +1040,7 @@
                                 && !mContinueNotifGrantMessageUids.contains(info.realCallingUid)) {
                             return result;
                         }
-                        if (PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(action)) {
+                        if (ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(action)) {
                             String otherPkg = info.intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
                             if (otherPkg == null || (mPackageManager.getPermissionFlags(
                                     POST_NOTIFICATIONS, otherPkg, UserHandle.of(info.userId))
@@ -1052,8 +1059,8 @@
                     public void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo,
                             ActivityInterceptorInfo info) {
                         super.onActivityLaunched(taskInfo, activityInfo, info);
-                        if (!shouldShowNotificationDialogOrClearFlags(info.intent,
-                                info.checkedOptions)) {
+                        if (!shouldShowNotificationDialogOrClearFlags(taskInfo,
+                                activityInfo.packageName, info.intent, info.checkedOptions, true)) {
                             return;
                         }
                         UserHandle user = UserHandle.of(taskInfo.userId);
@@ -1085,7 +1092,7 @@
                 return false;
             }
 
-            if (PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(intent.getAction())
+            if (ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(intent.getAction())
                     && (callingUid != Process.SYSTEM_UID || !SYSTEM_PKG.equals(callingPackage))) {
                 return false;
             }
@@ -1104,18 +1111,48 @@
             launchNotificationPermissionRequestDialog(packageName, user, taskId);
         }
 
+        @Override
+        public boolean isIntentToPermissionDialog(@NonNull Intent intent) {
+            return Objects.equals(intent.getPackage(),
+                    mPackageManager.getPermissionControllerPackageName())
+                    && (Objects.equals(intent.getAction(), ACTION_REQUEST_PERMISSIONS_FOR_OTHER)
+                    || Objects.equals(intent.getAction(), ACTION_REQUEST_PERMISSIONS));
+        }
+
+        @Override
+        public boolean shouldShowNotificationDialogForTask(TaskInfo taskInfo, String currPkg,
+                Intent intent) {
+            return shouldShowNotificationDialogOrClearFlags(
+                    taskInfo, currPkg, intent, null, false);
+        }
+
         /**
-         * Determine if we should show a notification dialog, or clear the REVIEW_REQUIRED flag,
-         * from a particular package for a particular intent. Returns true if:
+         * Determine if a particular task is in the proper state to show a system-triggered
+         * permission prompt. A prompt can be shown if the task is just starting, or the task is
+         * currently focused, visible, and running, and,
          * 1. The isEligibleForLegacyPermissionPrompt ActivityOption is set, or
-         * 2. The intent is a launcher intent (action is ACTION_MAIN, category is LAUNCHER)
+         * 2. The intent is a launcher intent (action is ACTION_MAIN, category is LAUNCHER), or
+         * 3. The activity belongs to the same package as the one which launched the task
+         * originally, and the task was started with a launcher intent
+         * @param taskInfo The task to be checked
+         * @param currPkg The package of the current top visible activity
+         * @param intent The intent of the current top visible activity
          */
-        private boolean shouldShowNotificationDialogOrClearFlags(Intent intent,
-                ActivityOptions options) {
-            if ((options != null && options.isEligibleForLegacyPermissionPrompt())) {
-                return true;
+        private boolean shouldShowNotificationDialogOrClearFlags(TaskInfo taskInfo, String currPkg,
+                Intent intent, ActivityOptions options, boolean activityStart) {
+            if (intent == null || currPkg == null || taskInfo == null
+                    || (!(taskInfo.isFocused && taskInfo.isVisible && taskInfo.isRunning)
+                    && !activityStart)) {
+                return false;
             }
 
+            return isLauncherIntent(intent)
+                    || (options != null && options.isEligibleForLegacyPermissionPrompt())
+                    || (currPkg.equals(taskInfo.baseActivity.getPackageName())
+                    && isLauncherIntent(taskInfo.baseIntent));
+        }
+
+        private boolean isLauncherIntent(Intent intent) {
             return Intent.ACTION_MAIN.equals(intent.getAction())
                     && intent.getCategories() != null
                     && (intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)
@@ -1144,14 +1181,15 @@
             Intent grantPermission = mPackageManager
                     .buildRequestPermissionsIntent(new String[] { POST_NOTIFICATIONS });
             grantPermission.setAction(
-                    PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER);
+                    ACTION_REQUEST_PERMISSIONS_FOR_OTHER);
             grantPermission.putExtra(Intent.EXTRA_PACKAGE_NAME, pkgName);
 
             ActivityOptions options = new ActivityOptions(new Bundle());
             options.setTaskOverlay(true, false);
             options.setLaunchTaskId(taskId);
             try {
-                mContext.startActivityAsUser(grantPermission, options.toBundle(), user);
+                mHandler.postDelayed(() -> mContext.startActivityAsUser(
+                        grantPermission, options.toBundle(), user), ACTIVITY_START_DELAY_MS);
             } catch (Exception e) {
                 Log.e(LOG_TAG, "couldn't start grant permission dialog"
                         + "for other package " + pkgName, e);
@@ -1170,12 +1208,6 @@
             }
         }
 
-        @Override
-        public boolean canShowPermissionPromptForTask(@Nullable TaskInfo taskInfo) {
-            return taskInfo != null && taskInfo.isFocused && taskInfo.isVisible
-                    && taskInfo.isRunning;
-        }
-
         /**
          * Check if the intent action is removed for the calling package (often based on target SDK
          * version). If the action is removed, we'll silently cancel the activity launch.
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index cc93d4c..dc5b325 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -792,7 +792,7 @@
         public void onWakeUp() {
             synchronized (mLock) {
                 if (shouldEnableWakeGestureLp()
-                        && mBatteryManagerInternal.getPlugType() != BATTERY_PLUGGED_WIRELESS) {
+                        && getBatteryManagerInternal().getPlugType() != BATTERY_PLUGGED_WIRELESS) {
                     performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, false,
                             "Wake Up");
                     wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromWakeGesture,
@@ -2124,7 +2124,7 @@
     }
 
     private void initKeyCombinationRules() {
-        mKeyCombinationManager = new KeyCombinationManager();
+        mKeyCombinationManager = new KeyCombinationManager(mHandler);
         final boolean screenshotChordEnabled = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_enableScreenshotChord);
 
@@ -2215,11 +2215,20 @@
                             mBackKeyHandled = true;
                             interceptAccessibilityGestureTv();
                         }
-
                         @Override
                         void cancel() {
                             cancelAccessibilityGestureTv();
                         }
+                        @Override
+                        long getKeyInterceptDelayMs() {
+                            // Use a timeout of 0 to prevent additional latency in processing of
+                            // this key. This will potentially cause some unwanted UI actions if the
+                            // user does end up triggering the key combination later, but in most
+                            // cases, the user will simply hit a single key, and this will allow us
+                            // to process it without first waiting to see if the combination is
+                            // going to be triggered.
+                            return 0;
+                        }
                     });
 
             mKeyCombinationManager.addRule(
@@ -2229,11 +2238,14 @@
                             mBackKeyHandled = true;
                             interceptBugreportGestureTv();
                         }
-
                         @Override
                         void cancel() {
                             cancelBugreportGestureTv();
                         }
+                        @Override
+                        long getKeyInterceptDelayMs() {
+                            return 0;
+                        }
                     });
         }
     }
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index dcfb8b5..a82d4ea 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -27,6 +27,7 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManagerInternal;
 import android.media.AudioAttributes;
 import android.os.FileUtils;
 import android.os.Handler;
@@ -525,8 +526,7 @@
         shutdownTimingLog.traceBegin("ShutdownPackageManager");
         metricStarted(METRIC_PM);
 
-        final PackageManagerService pm = (PackageManagerService)
-            ServiceManager.getService("package");
+        final PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
         if (pm != null) {
             pm.shutdown();
         }
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index ee0e5ba..e3dcfd0 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -247,6 +247,8 @@
         if (autoGrantPermissions != null && callingPkg != null) {
             // Need to own the Uri to call in with permissions to grant.
             enforceOwner(callingPkg, uri, userId);
+            // b/208232850: Needs to verify caller before granting slice access
+            verifyCaller(callingPkg);
             for (String perm : autoGrantPermissions) {
                 if (mContext.checkPermission(perm, pid, uid) == PERMISSION_GRANTED) {
                     int providerUser = ContentProvider.getUserIdFromUri(uri, userId);
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
index 990b21c..1cc0539 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
@@ -20,6 +20,7 @@
 import android.media.permission.SafeCloseable;
 import android.media.soundtrigger.ModelParameterRange;
 import android.media.soundtrigger.PhraseRecognitionEvent;
+import android.media.soundtrigger.PhraseRecognitionExtra;
 import android.media.soundtrigger.PhraseSoundModel;
 import android.media.soundtrigger.Properties;
 import android.media.soundtrigger.RecognitionConfig;
@@ -392,7 +393,7 @@
     private static void notifyAbort(int modelHandle, LoadedModel model) {
         switch (model.type) {
             case SoundModelType.GENERIC: {
-                RecognitionEvent event = new RecognitionEvent();
+                RecognitionEvent event = newEmptyRecognitionEvent();
                 event.status = RecognitionStatus.ABORTED;
                 event.type = SoundModelType.GENERIC;
                 model.callback.recognitionCallback(modelHandle, event);
@@ -400,7 +401,7 @@
             break;
 
             case SoundModelType.KEYPHRASE: {
-                PhraseRecognitionEvent event = new PhraseRecognitionEvent();
+                PhraseRecognitionEvent event = newEmptyPhraseRecognitionEvent();
                 event.common.status = RecognitionStatus.ABORTED;
                 event.common.type = SoundModelType.KEYPHRASE;
                 model.callback.phraseRecognitionCallback(modelHandle, event);
@@ -415,6 +416,19 @@
         mNotifier.unregisterListener(this);
     }
 
+    private static PhraseRecognitionEvent newEmptyPhraseRecognitionEvent() {
+        PhraseRecognitionEvent result = new PhraseRecognitionEvent();
+        result.common = newEmptyRecognitionEvent();
+        result.phraseExtras = new PhraseRecognitionExtra[0];
+        return result;
+    }
+
+    private static RecognitionEvent newEmptyRecognitionEvent() {
+        RecognitionEvent result = new RecognitionEvent();
+        result.data = new byte[0];
+        return result;
+    }
+
     ////////////////////////////////////////////////////////////////////////////////////////////////
     // All methods below do trivial delegation - no interesting logic.
     @Override
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 59b9daf..8087738 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -36,6 +36,7 @@
 import android.app.StatusBarManager;
 import android.app.compat.CompatChanges;
 import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
 import android.compat.annotation.EnabledSince;
 import android.content.ComponentName;
 import android.content.Context;
@@ -135,6 +136,17 @@
     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
     private static final long LOCK_DOWN_COLLAPSE_STATUS_BAR = 173031413L;
 
+    /**
+     * In apps targeting {@link android.os.Build.VERSION_CODES#TIRAMISU} or higher, calling
+     * {@link android.service.quicksettings.TileService#requestListeningState} will check that the 
+     * calling package (uid) and the package of the target {@link android.content.ComponentName} 
+     * match. It'll also make sure that the context used can take actions on behalf of the current 
+     * user.
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S_V2)
+    static final long REQUEST_LISTENING_MUST_MATCH_PACKAGE = 172251878L;
+
     private final Context mContext;
 
     private final Handler mHandler = new Handler();
@@ -1652,6 +1664,7 @@
 
     @Override
     public void hideCurrentInputMethodForBubbles() {
+        enforceStatusBarService();
         final long token = Binder.clearCallingIdentity();
         try {
             InputMethodManagerInternal.get().hideCurrentInputMethod(
@@ -1776,6 +1789,42 @@
     }
 
     @Override
+    public void requestTileServiceListeningState(
+            @NonNull ComponentName componentName,
+            int userId
+    ) {
+        int callingUid = Binder.getCallingUid();
+        String packageName = componentName.getPackageName();
+
+        boolean mustPerformChecks = CompatChanges.isChangeEnabled(
+                REQUEST_LISTENING_MUST_MATCH_PACKAGE, callingUid);
+
+        if (mustPerformChecks) {
+            // Check calling user can act on behalf of current user
+            userId = mActivityManagerInternal.handleIncomingUser(Binder.getCallingPid(), callingUid,
+                    userId, false, ActivityManagerInternal.ALLOW_NON_FULL,
+                    "requestTileServiceListeningState", packageName);
+
+            // Check calling uid matches package
+            checkCallingUidPackage(packageName, callingUid, userId);
+
+            int currentUser = mActivityManagerInternal.getCurrentUserId();
+
+            // Check current user
+            if (userId != currentUser) {
+                throw new IllegalArgumentException("User " + userId + " is not the current user.");
+            }
+        }
+        if (mBar != null) {
+            try {
+                mBar.requestTileServiceListeningState(componentName);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "requestTileServiceListeningState", e);
+            }
+        }
+    }
+
+    @Override
     public void requestAddTile(
             @NonNull ComponentName componentName,
             @NonNull CharSequence label,
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index c0207f0..16592d7 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.FileObserver;
@@ -31,7 +32,6 @@
 import android.os.HandlerThread;
 import android.os.Message;
 import android.os.ResultReceiver;
-import android.os.ServiceManager;
 import android.os.ShellCallback;
 import android.os.ShellCommand;
 import android.os.UserHandle;
@@ -49,6 +49,7 @@
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.EventLogTags;
+import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.pm.PackageManagerService;
 
@@ -187,10 +188,10 @@
             // when it's within 150% of the threshold, we try trimming usage
             // back to 200% of the threshold.
             if (file.getUsableSpace() < (lowBytes * 3) / 2) {
-                final PackageManagerService pms = (PackageManagerService) ServiceManager
-                        .getService("package");
+                final PackageManagerInternal pm =
+                        LocalServices.getService(PackageManagerInternal.class);
                 try {
-                    pms.freeStorage(vol.getFsUuid(), lowBytes * 2, 0);
+                    pm.freeStorage(vol.getFsUuid(), lowBytes * 2, 0);
                 } catch (IOException e) {
                     Slog.w(TAG, e);
                 }
@@ -264,10 +265,10 @@
         for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
             final File file = vol.getPath();
             if (file.getUsableSpace() < file.getTotalSpace() * storageThresholdPercentHigh / 100) {
-                final PackageManagerService pms = (PackageManagerService) ServiceManager
-                        .getService("package");
+                final PackageManagerInternal pm =
+                        LocalServices.getService(PackageManagerInternal.class);
                 try {
-                    pms.freeAllAppCacheAboveQuota(vol.getFsUuid());
+                    pm.freeAllAppCacheAboveQuota(vol.getFsUuid());
                 } catch (IOException e) {
                     Slog.w(TAG, e);
                 }
diff --git a/services/core/java/com/android/server/trust/TEST_MAPPING b/services/core/java/com/android/server/trust/TEST_MAPPING
new file mode 100644
index 0000000..be8ed67
--- /dev/null
+++ b/services/core/java/com/android/server/trust/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+    "presubmit": [
+      {
+        "name": "TrustTests",
+        "options": [
+          {
+            "include-filter": "android.trust.test"
+          },
+          {
+            "exclude-annotation": "androidx.test.filters.FlakyTest"
+          }
+        ]
+      }
+    ]
+  }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index bd4b8d1..cc1d0e2 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -715,7 +715,7 @@
                     (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
 
             List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
-            if (enabledAgents == null) {
+            if (enabledAgents.isEmpty()) {
                 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
                         + ": no agents enabled by user");
                 continue;
@@ -1080,9 +1080,7 @@
         }
 
         List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
-        if (previouslyEnabledAgents != null) {
-            discoveredAgents.addAll(previouslyEnabledAgents);
-        }
+        discoveredAgents.addAll(previouslyEnabledAgents);
         utils.setEnabledTrustAgents(discoveredAgents, userId);
         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
index 30e2617..092853f 100644
--- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
+++ b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
@@ -39,7 +39,7 @@
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
-import android.telephony.TelephonyManager.CarrierPrivilegesListener;
+import android.telephony.TelephonyManager.CarrierPrivilegesCallback;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
@@ -98,8 +98,7 @@
     @NonNull private final OnSubscriptionsChangedListener mSubscriptionChangedListener;
 
     @NonNull
-    private final List<CarrierPrivilegesListener> mCarrierPrivilegesChangedListeners =
-            new ArrayList<>();
+    private final List<CarrierPrivilegesCallback> mCarrierPrivilegesCallbacks = new ArrayList<>();
 
     @NonNull private TelephonySubscriptionSnapshot mCurrentSnapshot;
 
@@ -151,20 +150,21 @@
                 executor, mSubscriptionChangedListener);
         mTelephonyManager.registerTelephonyCallback(executor, mActiveDataSubIdListener);
 
-        registerCarrierPrivilegesListeners();
+        registerCarrierPrivilegesCallbacks();
     }
 
-    private void registerCarrierPrivilegesListeners() {
+    // TODO(b/221306368): Refactor with the new onCarrierServiceChange in the new CPCallback
+    private void registerCarrierPrivilegesCallbacks() {
         final HandlerExecutor executor = new HandlerExecutor(mHandler);
         final int modemCount = mTelephonyManager.getActiveModemCount();
         try {
             for (int i = 0; i < modemCount; i++) {
-                CarrierPrivilegesListener carrierPrivilegesListener =
-                        new CarrierPrivilegesListener() {
+                CarrierPrivilegesCallback carrierPrivilegesCallback =
+                        new CarrierPrivilegesCallback() {
                             @Override
                             public void onCarrierPrivilegesChanged(
-                                    @NonNull List<String> privilegedPackageNames,
-                                    @NonNull int[] privilegedUids) {
+                                    @NonNull Set<String> privilegedPackageNames,
+                                    @NonNull Set<Integer> privilegedUids) {
                                 // Re-trigger the synchronous check (which is also very cheap due
                                 // to caching in CarrierPrivilegesTracker). This allows consistency
                                 // with the onSubscriptionsChangedListener and broadcasts.
@@ -172,9 +172,9 @@
                             }
                         };
 
-                mTelephonyManager.addCarrierPrivilegesListener(
-                        i, executor, carrierPrivilegesListener);
-                mCarrierPrivilegesChangedListeners.add(carrierPrivilegesListener);
+                mTelephonyManager.registerCarrierPrivilegesCallback(
+                        i, executor, carrierPrivilegesCallback);
+                mCarrierPrivilegesCallbacks.add(carrierPrivilegesCallback);
             }
         } catch (IllegalArgumentException e) {
             Slog.wtf(TAG, "Encounted exception registering carrier privileges listeners", e);
@@ -191,15 +191,15 @@
         mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionChangedListener);
         mTelephonyManager.unregisterTelephonyCallback(mActiveDataSubIdListener);
 
-        unregisterCarrierPrivilegesListeners();
+        unregisterCarrierPrivilegesCallbacks();
     }
 
-    private void unregisterCarrierPrivilegesListeners() {
-        for (CarrierPrivilegesListener carrierPrivilegesListener :
-                mCarrierPrivilegesChangedListeners) {
-            mTelephonyManager.removeCarrierPrivilegesListener(carrierPrivilegesListener);
+    private void unregisterCarrierPrivilegesCallbacks() {
+        for (CarrierPrivilegesCallback carrierPrivilegesCallback :
+                mCarrierPrivilegesCallbacks) {
+            mTelephonyManager.unregisterCarrierPrivilegesCallback(carrierPrivilegesCallback);
         }
-        mCarrierPrivilegesChangedListeners.clear();
+        mCarrierPrivilegesCallbacks.clear();
     }
 
     /**
@@ -283,7 +283,7 @@
     }
 
     private void handleActionMultiSimConfigChanged(Context context, Intent intent) {
-        unregisterCarrierPrivilegesListeners();
+        unregisterCarrierPrivilegesCallbacks();
 
         // Clear invalid slotIds from the mReadySubIdsBySlotId map.
         final int modemCount = mTelephonyManager.getActiveModemCount();
@@ -296,7 +296,7 @@
             }
         }
 
-        registerCarrierPrivilegesListeners();
+        registerCarrierPrivilegesCallbacks();
         handleSubscriptionsChanged();
     }
 
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index b05b44b..77da751 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -355,8 +355,10 @@
                 }
             }
 
-            if (!shouldVibrateForRingerModeLocked(usage)) {
-                return Vibration.Status.IGNORED_FOR_RINGER_MODE;
+            if (!attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)) {
+                if (!shouldVibrateForRingerModeLocked(usage)) {
+                    return Vibration.Status.IGNORED_FOR_RINGER_MODE;
+                }
             }
         }
         return null;
@@ -386,12 +388,12 @@
      * Return {@code true} if the device should vibrate for current ringer mode.
      *
      * <p>This checks the current {@link AudioManager#getRingerModeInternal()} against user settings
-     * for ringtone usage only. All other usages are allowed by this method.
+     * for ringtone and notification usages. All other usages are allowed by this method.
      */
     @GuardedBy("mLock")
     private boolean shouldVibrateForRingerModeLocked(@VibrationAttributes.Usage int usageHint) {
-        if (usageHint != USAGE_RINGTONE) {
-            // Only ringtone vibrations are disabled when phone is on silent mode.
+        if ((usageHint != USAGE_RINGTONE) && (usageHint != USAGE_NOTIFICATION)) {
+            // Only ringtone and notification vibrations are disabled when phone is on silent mode.
             return true;
         }
         // If audio manager was not loaded yet then assume most restrictive mode.
diff --git a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
index 58407cf..e12426b 100644
--- a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
+++ b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
@@ -60,8 +60,6 @@
     static final float RAMP_OFF_AMPLITUDE_MIN = 1e-3f;
     static final List<Step> EMPTY_STEP_LIST = new ArrayList<>();
 
-    private final Object mLock = new Object();
-
     // Used within steps.
     public final VibrationSettings vibrationSettings;
     public final DeviceVibrationEffectAdapter deviceEffectAdapter;
@@ -74,6 +72,11 @@
     private final Queue<Step> mPendingOnVibratorCompleteSteps = new LinkedList<>();
 
     // Signalling fields.
+    // Note that vibrator callback signals may happen inside vibrator HAL calls made by the
+    // VibrationThread, or on an external executor, so this lock should not be held for anything
+    // other than updating signalling state - particularly not during HAL calls or when invoking
+    // other callbacks that may trigger calls into the thread.
+    private final Object mLock = new Object();
     @GuardedBy("mLock")
     private final IntArray mSignalVibratorsComplete;
     @GuardedBy("mLock")
@@ -334,9 +337,9 @@
      * The state update is recorded for processing on the main execution thread (VibrationThread).
      */
     public void notifyVibratorComplete(int vibratorId) {
-        if (Build.IS_DEBUGGABLE) {
-            expectIsVibrationThread(false);
-        }
+        // HAL callbacks may be triggered directly within HAL calls, so these notifications
+        // could be on the VibrationThread as it calls the HAL, or some other executor later.
+        // Therefore no thread assertion is made here.
 
         if (DEBUG) {
             Slog.d(TAG, "Vibration complete reported by vibrator " + vibratorId);
@@ -356,9 +359,9 @@
      * (VibrationThread).
      */
     public void notifySyncedVibrationComplete() {
-        if (Build.IS_DEBUGGABLE) {
-            expectIsVibrationThread(false);
-        }
+        // HAL callbacks may be triggered directly within HAL calls, so these notifications
+        // could be on the VibrationThread as it calls the HAL, or some other executor later.
+        // Therefore no thread assertion is made here.
 
         if (DEBUG) {
             Slog.d(TAG, "Synced vibration complete reported by vibrator manager");
@@ -394,7 +397,7 @@
         int[] vibratorsToProcess = null;
         boolean doCancel = false;
         boolean doCancelImmediate = false;
-        // Swap out the queue of completions to process.
+        // Collect signals to process, but don't keep the lock while processing them.
         synchronized (mLock) {
             if (mSignalCancelImmediate) {
                 if (mCancelledImmediately) {
@@ -407,6 +410,7 @@
                 doCancel = true;
             }
             if (!doCancelImmediate && mSignalVibratorsComplete.size() > 0) {
+                // Swap out the queue of completions to process.
                 vibratorsToProcess = mSignalVibratorsComplete.toArray();  // makes a copy
                 mSignalVibratorsComplete.clear();
             }
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index 205ea62..cecc5c0 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -22,6 +22,7 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.Trace;
 import android.os.WorkSource;
 import android.util.Slog;
@@ -176,7 +177,7 @@
      * @return true if the vibration completed, or false if waiting timed out.
      */
     public boolean waitForThreadIdle(long maxWaitMillis) {
-        long now = System.currentTimeMillis();
+        long now = SystemClock.elapsedRealtime();
         long deadline = now + maxWaitMillis;
         synchronized (mLock) {
             while (true) {
@@ -191,7 +192,7 @@
                 } catch (InterruptedException e) {
                     Slog.w(TAG, "VibrationThread interrupted waiting to stop, continuing");
                 }
-                now = System.currentTimeMillis();
+                now = SystemClock.elapsedRealtime();
             }
         }
     }
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 9ec1079..1260e5d 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -464,10 +464,9 @@
                             && shouldCancelVibration(
                             mCurrentExternalVibration.externalVibration.getVibrationAttributes(),
                             usageFilter)) {
-                        endVibrationLocked(mCurrentExternalVibration, Vibration.Status.CANCELLED);
                         mCurrentExternalVibration.externalVibration.mute();
-                        mCurrentExternalVibration = null;
-                        setExternalControl(false);
+                        endExternalVibrateLocked(Vibration.Status.CANCELLED,
+                                /* continueExternalControl= */ false);
                     }
                 } finally {
                     Binder.restoreCallingIdentity(ident);
@@ -1283,7 +1282,7 @@
     }
 
     /** Holder for a {@link ExternalVibration}. */
-    private final class ExternalVibrationHolder {
+    private final class ExternalVibrationHolder implements IBinder.DeathRecipient {
 
         public final ExternalVibration externalVibration;
         public int scale;
@@ -1308,6 +1307,18 @@
             mEndTimeDebug = System.currentTimeMillis();
         }
 
+        public void binderDied() {
+            synchronized (mLock) {
+                if (mCurrentExternalVibration != null) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "External vibration finished because binder died");
+                    }
+                    endExternalVibrateLocked(Vibration.Status.CANCELLED,
+                            /* continueExternalControl= */ false);
+                }
+            }
+        }
+
         public Vibration.DebugInfo getDebugInfo() {
             return new Vibration.DebugInfo(
                     mStartTimeDebug, mEndTimeDebug, /* effect= */ null, /* originalEffect= */ null,
@@ -1450,10 +1461,36 @@
         }
     }
 
+    /**
+     * Ends the external vibration, and clears related service state.
+     *
+     * @param status the status to end the associated Vibration with
+     * @param continueExternalControl indicates whether external control will continue. If not, the
+     *                                HAL will have external control turned off.
+     */
+    @GuardedBy("mLock")
+    private void endExternalVibrateLocked(Vibration.Status status,
+            boolean continueExternalControl) {
+        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "endExternalVibrateLocked");
+        try {
+            if (mCurrentExternalVibration == null) {
+                return;
+            }
+            endVibrationLocked(mCurrentExternalVibration, status);
+            mCurrentExternalVibration.externalVibration.unlinkToDeath(
+                    mCurrentExternalVibration);
+            mCurrentExternalVibration = null;
+            if (!continueExternalControl) {
+                setExternalControl(false);
+            }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+        }
+    }
+
     /** Implementation of {@link IExternalVibratorService} to be triggered on external control. */
     @VisibleForTesting
     final class ExternalVibratorService extends IExternalVibratorService.Stub {
-        ExternalVibrationDeathRecipient mCurrentExternalDeathRecipient;
 
         @Override
         public int onExternalVibrationStart(ExternalVibration vib) {
@@ -1469,7 +1506,7 @@
                 return IExternalVibratorService.SCALE_MUTE;
             }
 
-            ExternalVibrationHolder cancelingExternalVibration = null;
+            boolean alreadyUnderExternalControl = false;
             boolean waitForCompletion = false;
             int scale;
             synchronized (mLock) {
@@ -1504,13 +1541,13 @@
                     //
                     // Note that this doesn't support multiple concurrent external controls, as we
                     // would need to mute the old one still if it came from a different controller.
+                    alreadyUnderExternalControl = true;
                     mCurrentExternalVibration.externalVibration.mute();
-                    endVibrationLocked(mCurrentExternalVibration, Vibration.Status.CANCELLED);
-                    cancelingExternalVibration = mCurrentExternalVibration;
+                    endExternalVibrateLocked(Vibration.Status.CANCELLED,
+                            /* continueExternalControl= */ true);
                 }
                 mCurrentExternalVibration = new ExternalVibrationHolder(vib);
-                mCurrentExternalDeathRecipient = new ExternalVibrationDeathRecipient();
-                vib.linkToDeath(mCurrentExternalDeathRecipient);
+                vib.linkToDeath(mCurrentExternalVibration);
                 mCurrentExternalVibration.scale = mVibrationScaler.getExternalVibrationScale(
                         vib.getVibrationAttributes().getUsage());
                 scale = mCurrentExternalVibration.scale;
@@ -1520,14 +1557,13 @@
                 if (!mVibrationThread.waitForThreadIdle(VIBRATION_CANCEL_WAIT_MILLIS)) {
                     Slog.e(TAG, "Timed out waiting for vibration to cancel");
                     synchronized (mLock) {
-                        stopExternalVibrateLocked(Vibration.Status.IGNORED_ERROR_CANCELLING);
+                        endExternalVibrateLocked(Vibration.Status.IGNORED_ERROR_CANCELLING,
+                                /* continueExternalControl= */ false);
                     }
                     return IExternalVibratorService.SCALE_MUTE;
                 }
             }
-            if (cancelingExternalVibration == null) {
-                // We only need to set external control if it was not already set by another
-                // external vibration.
+            if (!alreadyUnderExternalControl) {
                 if (DEBUG) {
                     Slog.d(TAG, "Vibrator going under external control.");
                 }
@@ -1547,29 +1583,12 @@
                     if (DEBUG) {
                         Slog.e(TAG, "Stopping external vibration" + vib);
                     }
-                    stopExternalVibrateLocked(Vibration.Status.FINISHED);
+                    endExternalVibrateLocked(Vibration.Status.FINISHED,
+                            /* continueExternalControl= */ false);
                 }
             }
         }
 
-        @GuardedBy("mLock")
-        private void stopExternalVibrateLocked(Vibration.Status status) {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "stopExternalVibrateLocked");
-            try {
-                if (mCurrentExternalVibration == null) {
-                    return;
-                }
-                endVibrationLocked(mCurrentExternalVibration, status);
-                mCurrentExternalVibration.externalVibration.unlinkToDeath(
-                        mCurrentExternalDeathRecipient);
-                mCurrentExternalDeathRecipient = null;
-                mCurrentExternalVibration = null;
-                setExternalControl(false);
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-        }
-
         private boolean hasExternalControlCapability() {
             for (int i = 0; i < mVibrators.size(); i++) {
                 if (mVibrators.valueAt(i).hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
@@ -1578,19 +1597,6 @@
             }
             return false;
         }
-
-        private class ExternalVibrationDeathRecipient implements IBinder.DeathRecipient {
-            public void binderDied() {
-                synchronized (mLock) {
-                    if (mCurrentExternalVibration != null) {
-                        if (DEBUG) {
-                            Slog.d(TAG, "External vibration finished because binder died");
-                        }
-                        stopExternalVibrateLocked(Vibration.Status.CANCELLED);
-                    }
-                }
-            }
-        }
     }
 
     /** Provide limited functionality from {@link VibratorManagerService} as shell commands. */
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
index f9689a8..d4648a4 100644
--- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -27,6 +27,7 @@
 import android.graphics.Region;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.InputConfig;
 import android.os.Looper;
 import android.os.Message;
 import android.util.Slog;
@@ -153,7 +154,8 @@
         final List<InputWindowHandle> tempVisibleWindows = new ArrayList<>();
 
         for (InputWindowHandle window : windowHandles) {
-            if (window.visible && window.getWindow() != null) {
+            final boolean visible = (window.inputConfig & InputConfig.NOT_VISIBLE) == 0;
+            if (visible && window.getWindow() != null) {
                 tempVisibleWindows.add(window);
             }
         }
@@ -641,7 +643,8 @@
             final RecentsAnimationController controller = service.getRecentsAnimationController();
             instance.mIgnoreDuetoRecentsAnimation = windowState != null && controller != null
                     && controller.shouldIgnoreForAccessibility(windowState);
-            instance.mIsTrustedOverlay = inputWindowHandle.trustedOverlay;
+            instance.mIsTrustedOverlay =
+                    (inputWindowHandle.inputConfig & InputConfig.TRUSTED_OVERLAY) != 0;
 
             // TODO (b/199358388) : gets the letterbox bounds of the window from other way.
             if (windowState != null && windowState.areAppWindowBoundsLetterboxed()) {
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index a4a200d..543e44c 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -757,12 +757,12 @@
     }
 
     @Override
-    public void setPreferDockBigOverlays(IBinder token, boolean preferDockBigOverlays) {
+    public void setShouldDockBigOverlays(IBinder token, boolean shouldDockBigOverlays) {
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
-                r.setPreferDockBigOverlays(preferDockBigOverlays);
+                r.setShouldDockBigOverlays(shouldDockBigOverlays);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
index 06c58ba..1d65cbb 100644
--- a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
+++ b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
@@ -58,6 +58,7 @@
     @IntDef(suffix = { "_ORDERED_ID" }, value = {
             FIRST_ORDERED_ID,
             PERMISSION_POLICY_ORDERED_ID,
+            INTENT_RESOLVER_ORDERED_ID,
             VIRTUAL_DEVICE_SERVICE_ORDERED_ID,
             LAST_ORDERED_ID // Update this when adding new ids
     })
@@ -75,6 +76,11 @@
     public static final int PERMISSION_POLICY_ORDERED_ID = 1;
 
     /**
+     * The identifier for {@link com.android.server.pm.IntentResolverInterceptor}.
+     */
+    public static final int INTENT_RESOLVER_ORDERED_ID = 2;
+
+    /**
      * The identifier for {@link com.android.server.companion.virtual.VirtualDeviceManagerService}
      * interceptor.
      */
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index a8dd856..c0cdec9 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -657,7 +657,7 @@
         for (int i = mTransitionInfoList.size() - 2; i >= 0; i--) {
             final TransitionInfo prevInfo = mTransitionInfoList.get(i);
             if (prevInfo.mIsDrawn || !prevInfo.mLastLaunchedActivity.mVisibleRequested) {
-                abort(prevInfo, "nothing will be drawn");
+                scheduleCheckActivityToBeDrawn(prevInfo.mLastLaunchedActivity, 0 /* delay */);
             }
         }
     }
@@ -757,6 +757,10 @@
     /** Makes sure that the reference to the removed activity is cleared. */
     void notifyActivityRemoved(@NonNull ActivityRecord r) {
         mLastTransitionInfo.remove(r);
+        final TransitionInfo info = getActiveTransitionInfo(r);
+        if (info != null) {
+            abort(info, "removed");
+        }
 
         final int packageUid = r.info.applicationInfo.uid;
         final PackageCompatStateInfo compatStateInfo = mPackageUidToCompatStateInfo.get(packageUid);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index e66f309..883ce99 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -278,6 +278,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.gui.DropInputMode;
 import android.hardware.HardwareBuffer;
 import android.net.Uri;
 import android.os.Binder;
@@ -533,7 +534,7 @@
         // activity can enter picture in picture while pausing (only when switching to another task)
     PictureInPictureParams pictureInPictureArgs = new PictureInPictureParams.Builder().build();
         // The PiP params used when deferring the entering of picture-in-picture.
-    boolean preferDockBigOverlays;
+    boolean shouldDockBigOverlays;
     int launchCount;        // count of launches since last state
     long lastLaunchTime;    // time of last launch of this activity
     ComponentName requestedVrComponent; // the requested component for handling VR mode.
@@ -782,6 +783,10 @@
     boolean startingDisplayed;
     boolean startingMoved;
 
+    /** The last set {@link DropInputMode} for this activity surface. */
+    @DropInputMode
+    private int mLastDropInputMode = DropInputMode.NONE;
+
     /**
      * If it is non-null, it requires all activities who have the same starting data to be drawn
      * to remove the starting window.
@@ -1548,6 +1553,60 @@
                 rootTask.setHasBeenVisible(true);
             }
         }
+
+        // Update the input mode if the embedded mode is changed.
+        updateUntrustedEmbeddingInputProtection();
+    }
+
+    @Override
+    void setSurfaceControl(SurfaceControl sc) {
+        super.setSurfaceControl(sc);
+        if (sc != null) {
+            mLastDropInputMode = DropInputMode.NONE;
+            updateUntrustedEmbeddingInputProtection();
+        }
+    }
+
+    /**
+     * Sets to drop input when obscured to activity if it is embedded in untrusted mode.
+     *
+     * Although the untrusted embedded activity should be invisible when behind other overlay,
+     * theoretically even if this activity is the top most, app can still move surface of activity
+     * below it to the top. As a result, we want to update the input mode to drop when obscured for
+     * all untrusted activities.
+     */
+    private void updateUntrustedEmbeddingInputProtection() {
+        final SurfaceControl sc = getSurfaceControl();
+        if (sc == null) {
+            return;
+        }
+        if (isEmbeddedInUntrustedMode()) {
+            // Set drop input to OBSCURED when untrusted embedded.
+            setDropInputMode(DropInputMode.OBSCURED);
+        } else {
+            // Reset drop input mode when this activity is not embedded in untrusted mode.
+            setDropInputMode(DropInputMode.NONE);
+        }
+    }
+
+    @VisibleForTesting
+    void setDropInputMode(@DropInputMode int mode) {
+        if (mLastDropInputMode != mode && getSurfaceControl() != null) {
+            mLastDropInputMode = mode;
+            mWmService.mTransactionFactory.get()
+                    .setDropInputMode(getSurfaceControl(), mode)
+                    .apply();
+        }
+    }
+
+    private boolean isEmbeddedInUntrustedMode() {
+        final TaskFragment organizedTaskFragment = getOrganizedTaskFragment();
+        if (organizedTaskFragment == null) {
+            // Not embedded.
+            return false;
+        }
+        // Check if trusted.
+        return !organizedTaskFragment.isAllowedToEmbedActivityInTrustedMode(this);
     }
 
     void updateAnimatingActivityRegistry() {
@@ -1983,7 +2042,7 @@
         mLetterboxUiController = new LetterboxUiController(mWmService, this);
         mCameraCompatControlEnabled = mWmService.mContext.getResources()
                 .getBoolean(R.bool.config_isCameraCompatControlForStretchedIssuesEnabled);
-        preferDockBigOverlays = mWmService.mContext.getResources()
+        shouldDockBigOverlays = mWmService.mContext.getResources()
                 .getBoolean(R.bool.config_dockBigOverlayWindows);
 
         if (_createTime > 0) {
@@ -2417,7 +2476,8 @@
     }
 
     private boolean transferSplashScreenIfNeeded() {
-        if (!mHandleExitSplashScreen || mStartingSurface == null || mStartingWindow == null
+        if (finishing || !mHandleExitSplashScreen || mStartingSurface == null
+                || mStartingWindow == null
                 || mTransferringSplashScreenState == TRANSFER_SPLASH_SCREEN_FINISH) {
             return false;
         }
@@ -2452,7 +2512,8 @@
         // either way, abort and reset the sequence.
         if (parcelable == null
                 || mTransferringSplashScreenState != TRANSFER_SPLASH_SCREEN_COPYING
-                || mStartingWindow == null) {
+                || mStartingWindow == null
+                || finishing) {
             if (parcelable != null) {
                 parcelable.clearIfNeeded();
             }
@@ -2854,7 +2915,9 @@
      */
     boolean supportsPictureInPicture() {
         return mAtmService.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
-                && info.supportsPictureInPicture();
+                && info.supportsPictureInPicture()
+                && (mDisplayContent != null && mDisplayContent.mDwpcHelper.isWindowingModeSupported(
+                WINDOWING_MODE_PINNED));
     }
 
     /**
@@ -3642,6 +3705,20 @@
             return;
         }
         finishing = true;
+
+        // Transfer the launch cookie to the next running activity above this in the same task.
+        if (mLaunchCookie != null && mState != RESUMED && task != null && !task.mInRemoveTask
+                && !task.isClearingToReuseTask()) {
+            final ActivityRecord nextCookieTarget = task.getActivity(
+                    // Intend to only associate the same app by checking uid.
+                    r -> r.mLaunchCookie == null && !r.finishing && r.isUid(getUid()),
+                    this, false /* includeBoundary */, false /* traverseTopToBottom */);
+            if (nextCookieTarget != null) {
+                nextCookieTarget.mLaunchCookie = mLaunchCookie;
+                mLaunchCookie = null;
+            }
+        }
+
         final TaskFragment taskFragment = getTaskFragment();
         if (taskFragment != null) {
             final Task task = taskFragment.getTask();
@@ -5428,6 +5505,11 @@
             return false;
         }
 
+        // Untrusted embedded activity can be visible only if there is no other overlay window.
+        if (hasOverlayOverUntrustedModeEmbedded()) {
+            return false;
+        }
+
         // Check if the activity is on a sleeping display, canTurnScreenOn will also check
         // keyguard visibility
         if (mDisplayContent.isSleeping()) {
@@ -5437,6 +5519,25 @@
         }
     }
 
+    /**
+     * Checks if there are any activities or other containers that belong to the same task on top of
+     * this activity when embedded in untrusted mode.
+     */
+    boolean hasOverlayOverUntrustedModeEmbedded() {
+        if (!isEmbeddedInUntrustedMode() || getRootTask() == null) {
+            // The activity is not embedded in untrusted mode.
+            return false;
+        }
+
+        // Check if there are any activities with different UID over the activity that is embedded
+        // in untrusted mode. Traverse bottom to top with boundary so that it will only check
+        // activities above this activity.
+        final ActivityRecord differentUidOverlayActivity = getRootTask().getActivity(
+                a -> a.getUid() != getUid(), this /* boundary */, false /* includeBoundary */,
+                false /* traverseTopToBottom */);
+        return differentUidOverlayActivity != null;
+    }
+
     void updateVisibilityIgnoringKeyguard(boolean behindFullscreenActivity) {
         visibleIgnoringKeyguard = (!behindFullscreenActivity || mLaunchTaskBehind)
                 && showToCurrentUser();
@@ -6669,7 +6770,8 @@
             }
             // Choose the default behavior for Launcher and SystemUI when the SplashScreen style is
             // not specified in the ActivityOptions.
-            if (mLaunchSourceType == LAUNCH_SOURCE_TYPE_HOME) {
+            if (mLaunchSourceType == LAUNCH_SOURCE_TYPE_HOME
+                    || launchedFromUid == Process.SHELL_UID) {
                 return false;
             } else if (mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEMUI) {
                 return true;
@@ -6689,7 +6791,8 @@
         // solid color splash screen.
         // Need to check sourceRecord before in case this activity is launched from service.
         return !startActivity || !(mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEM
-                || mLaunchSourceType == LAUNCH_SOURCE_TYPE_HOME);
+                || mLaunchSourceType == LAUNCH_SOURCE_TYPE_HOME
+                || launchedFromUid == Process.SHELL_UID);
     }
 
     private int getSplashscreenTheme(ActivityOptions options) {
@@ -9475,9 +9578,9 @@
         getTask().getRootTask().onPictureInPictureParamsChanged();
     }
 
-    void setPreferDockBigOverlays(boolean preferDockBigOverlays) {
-        this.preferDockBigOverlays = preferDockBigOverlays;
-        getTask().getRootTask().onPreferDockBigOverlaysChanged();
+    void setShouldDockBigOverlays(boolean shouldDockBigOverlays) {
+        this.shouldDockBigOverlays = shouldDockBigOverlays;
+        getTask().getRootTask().onShouldDockBigOverlaysChanged();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
index 19d5449..8622bd3 100644
--- a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
+++ b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
@@ -19,6 +19,7 @@
 import android.app.compat.CompatChanges;
 import android.compat.annotation.ChangeId;
 import android.os.IBinder;
+import android.os.InputConfig;
 import android.os.InputConstants;
 import android.os.Looper;
 import android.os.Process;
@@ -111,13 +112,12 @@
                 mActivityRecord.getDisplayId());
         inputWindowHandle.replaceTouchableRegionWithCrop = true;
         inputWindowHandle.name = mName;
+        inputWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
         inputWindowHandle.ownerUid = Process.myUid();
         inputWindowHandle.ownerPid = Process.myPid();
-        inputWindowHandle.layoutParamsFlags =
-                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
         inputWindowHandle.dispatchingTimeoutMillis =
                 InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
+        inputWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE;
         return inputWindowHandle;
     }
 
@@ -169,5 +169,4 @@
             finishInputEvent(event, true);
         }
     }
-
 }
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index c5fcd12..cdeb86c 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -355,10 +355,10 @@
      * @return The intercepting intent if needed.
      */
     private Intent interceptWithConfirmCredentialsIfNeeded(ActivityInfo aInfo, int userId) {
-        if (!mService.mAmInternal.shouldConfirmCredentials(userId)) {
+        if ((aInfo.flags & ActivityInfo.FLAG_SHOW_WHEN_LOCKED) != 0
+                || !mService.mAmInternal.shouldConfirmCredentials(userId)) {
             return null;
         }
-        // TODO(b/28935539): should allow certain activities to bypass work challenge
         final IntentSender target = createIntentSenderForOriginalIntent(mCallingUid,
                 FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT | FLAG_IMMUTABLE);
         final KeyguardManager km = (KeyguardManager) mServiceContext
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index fd2afd4..7d2dfa0 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1816,7 +1816,8 @@
         }
 
         if (mTargetRootTask == null) {
-            mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
+            mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
+                    mOptions);
         }
         if (newTask) {
             final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
@@ -1925,7 +1926,7 @@
         } else if (mInTask != null) {
             return mInTask;
         } else {
-            final Task rootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, null /* task */,
+            final Task rootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, null /* task */,
                     mOptions);
             final ActivityRecord top = rootTask.getTopNonFinishingActivity();
             if (top != null) {
@@ -2022,22 +2023,12 @@
     private boolean canEmbedActivity(@NonNull TaskFragment taskFragment,
             @NonNull ActivityRecord starting, boolean newTask, Task targetTask) {
         final Task hostTask = taskFragment.getTask();
-        if (hostTask == null) {
+        // Not allowed embedding a separate task or without host task.
+        if (hostTask == null || newTask || targetTask != hostTask) {
             return false;
         }
 
-        // Allowing the embedding if the task is owned by system.
-        final int hostUid = hostTask.effectiveUid;
-        if (UserHandle.getAppId(hostUid) == Process.SYSTEM_UID) {
-            return true;
-        }
-
-        if (!taskFragment.isAllowedToEmbedActivity(starting)) {
-            return false;
-        }
-
-        // Not allowed embedding task.
-        return !newTask && (targetTask == null || targetTask == hostTask);
+        return taskFragment.isAllowedToEmbedActivity(starting);
     }
 
     /**
@@ -2233,7 +2224,7 @@
                 if (targetTask.getRootTask() == null) {
                     // Target root task got cleared when we all activities were removed above.
                     // Go ahead and reset it.
-                    mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags,
+                    mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags,
                         null /* task */, mOptions);
                     mTargetRootTask.addChild(targetTask, !mLaunchTaskBehind /* toTop */,
                             (mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
@@ -2695,10 +2686,11 @@
                 // launched into the same root task.
                 mTargetRootTask = Task.fromWindowContainerToken(mSourceRecord.mLaunchRootTask);
             } else {
-                final Task launchRootTask =
-                        getLaunchRootTask(mStartActivity, mLaunchFlags, intentTask, mOptions);
+                final Task rootTask =
+                        getOrCreateRootTask(mStartActivity, mLaunchFlags, intentTask, mOptions);
+                // TODO(b/184806710): #getOrCreateRootTask should never return null?
                 mTargetRootTask =
-                        launchRootTask != null ? launchRootTask : intentActivity.getRootTask();
+                        rootTask != null ? rootTask : intentActivity.getRootTask();
             }
         }
 
@@ -2929,7 +2921,7 @@
         return launchFlags;
     }
 
-    private Task getLaunchRootTask(ActivityRecord r, int launchFlags, Task task,
+    private Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task,
             ActivityOptions aOptions) {
         // We are reusing a task, keep the root task!
         if (mReuseTask != null) {
@@ -2938,7 +2930,7 @@
 
         final boolean onTop =
                 (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
-        return mRootWindowContainer.getLaunchRootTask(r, aOptions, task, mSourceRootTask, onTop,
+        return mRootWindowContainer.getOrCreateRootTask(r, aOptions, task, mSourceRootTask, onTop,
                 mLaunchParams, launchFlags);
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index cecfccd..01dfb91 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -680,4 +680,15 @@
 
     /** Get the app tasks for a package */
     public abstract List<ActivityManager.AppTask> getAppTasks(String pkgName, int uid);
+
+    /**
+     * Determine if there exists a task which meets the criteria set by the PermissionPolicyService
+     * to show a system-owned permission dialog over, for a given package
+     * @see PermissionPolicyInternal.shouldShowNotificationDialogForTask
+     *
+     * @param pkgName The package whose activity must be top
+     * @param uid The uid that must have a top activity
+     * @return a task ID if a valid task ID is found. Otherwise, return INVALID_TASK_ID
+     */
+    public abstract int getTaskToShowPermissionDialogOn(String pkgName, int uid);
 }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index bfccdf9..b5312c4 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -205,8 +205,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.WorkSource;
-import android.os.storage.IStorageManager;
-import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.service.dreams.DreamActivity;
 import android.service.dreams.DreamManagerInternal;
@@ -4300,11 +4298,6 @@
             SystemProperties.set("persist.sys.locale",
                     locales.get(bestLocaleIndex).toLanguageTag());
             LocaleList.setDefault(locales, bestLocaleIndex);
-
-            final Message m = PooledLambda.obtainMessage(
-                    ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
-                    locales.get(bestLocaleIndex));
-            mH.sendMessage(m);
         }
 
         mTempConfig.seq = increaseConfigurationSeqLocked();
@@ -4458,17 +4451,6 @@
         Settings.System.putConfigurationForUser(resolver, config, userId);
     }
 
-    private void sendLocaleToMountDaemonMsg(Locale l) {
-        try {
-            IBinder service = ServiceManager.getService("mount");
-            IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
-            Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
-            storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error storing locale for decryption UI", e);
-        }
-    }
-
     private void expireStartAsCallerTokenMsg(IBinder permissionToken) {
         mStartActivitySources.remove(permissionToken);
         mExpiredStartAsCallerTokens.add(permissionToken);
@@ -6754,5 +6736,13 @@
             }
             return tasks;
         }
+
+        @Override
+        public int getTaskToShowPermissionDialogOn(String pkgName, int uid) {
+            synchronized (ActivityTaskManagerService.this.mGlobalLock) {
+                return ActivityTaskManagerService.this.mRootWindowContainer
+                        .getTaskToShowPermissionDialogOn(pkgName, uid);
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 5573f16..eb5ca9c 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -402,7 +402,8 @@
                     activities.add(r.info);
                 });
             }
-            if (!displayContent.mDwpcHelper.canContainActivities(activities)) {
+            if (!displayContent.mDwpcHelper.canContainActivities(activities,
+                    displayContent.getWindowingMode())) {
                 return false;
             }
         }
@@ -954,7 +955,7 @@
                 // This is the first time we failed -- restart process and
                 // retry.
                 r.launchFailed = true;
-                proc.removeActivity(r, true /* keepAssociation */);
+                r.detachFromProcess();
                 throw e;
             }
         } finally {
@@ -1046,6 +1047,9 @@
             // If a dead object exception was thrown -- fall through to
             // restart the application.
             knownToBeDead = true;
+            // Remove the process record so it won't be considered as alive.
+            mService.mProcessNames.remove(wpc.mName, wpc.mUid);
+            mService.mProcessMap.remove(wpc.getPid());
         }
 
         r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
@@ -1436,20 +1440,20 @@
                 final Rect bounds = options.getLaunchBounds();
                 task.setBounds(bounds);
 
-                Task launchRootTask =
-                        mRootWindowContainer.getLaunchRootTask(null, options, task, ON_TOP);
+                Task targetRootTask =
+                        mRootWindowContainer.getOrCreateRootTask(null, options, task, ON_TOP);
 
-                if (launchRootTask != currentRootTask) {
-                    moveHomeRootTaskToFrontIfNeeded(flags, launchRootTask.getDisplayArea(), reason);
-                    task.reparent(launchRootTask, ON_TOP, REPARENT_KEEP_ROOT_TASK_AT_FRONT,
+                if (targetRootTask != currentRootTask) {
+                    moveHomeRootTaskToFrontIfNeeded(flags, targetRootTask.getDisplayArea(), reason);
+                    task.reparent(targetRootTask, ON_TOP, REPARENT_KEEP_ROOT_TASK_AT_FRONT,
                             !ANIMATE, DEFER_RESUME, reason);
-                    currentRootTask = launchRootTask;
+                    currentRootTask = targetRootTask;
                     reparented = true;
                     // task.reparent() should already placed the task on top,
                     // still need moveTaskToFrontLocked() below for any transition settings.
                 }
-                if (launchRootTask.shouldResizeRootTaskWithLaunchBounds()) {
-                    launchRootTask.resize(bounds, !PRESERVE_WINDOWS, !DEFER_RESUME);
+                if (targetRootTask.shouldResizeRootTaskWithLaunchBounds()) {
+                    targetRootTask.resize(bounds, !PRESERVE_WINDOWS, !DEFER_RESUME);
                 } else {
                     // WM resizeTask must be done after the task is moved to the correct stack,
                     // because Task's setBounds() also updates dim layer's bounds, but that has
@@ -1693,7 +1697,7 @@
      */
     boolean restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop) {
         final Task rootTask =
-                mRootWindowContainer.getLaunchRootTask(null, aOptions, task, onTop);
+                mRootWindowContainer.getOrCreateRootTask(null, aOptions, task, onTop);
         final WindowContainer parent = task.getParent();
 
         if (parent == rootTask || task == rootTask) {
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 9e889ad..220d9ec 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -329,8 +329,12 @@
     void hideImmediately(WindowToken windowToken) {
         final boolean original = mHideImmediately;
         mHideImmediately = true;
+        final Operation op = new Operation(Operation.ACTION_FADE);
+        mTargetWindowTokens.put(windowToken, op);
         fadeWindowToken(false /* show */, windowToken, ANIMATION_TYPE_FIXED_TRANSFORM);
+        op.mLeash = windowToken.getAnimationLeash();
         mHideImmediately = original;
+        if (DEBUG) Slog.d(TAG, "hideImmediately " + windowToken.getTopChild());
     }
 
     /** Returns {@code true} if the window will rotate independently. */
diff --git a/services/core/java/com/android/server/wm/BLASTSync.md b/services/core/java/com/android/server/wm/BLASTSync.md
new file mode 100644
index 0000000..2f39d6d
--- /dev/null
+++ b/services/core/java/com/android/server/wm/BLASTSync.md
@@ -0,0 +1,108 @@
+= What does it mean for BLAST Sync to work? =
+There are two BLAST sync primitives on the server side, BLASTSyncEngine and applyWithNextDraw.
+Both of them are used to solve subclasses of this category of problem:
+ 1. You have some server side changes, which will trigger both WM/SysUI initiated SurfaceControl.Transactions, 
+    and also trigger a client redraw/update
+ 2. You want to synchronize the redraw of those clients with the application of those WM/SysUI side changes.
+
+Put simply, you would like to synchronize the graphical effects of some WM changes with the graphical output of various windows
+observing those changes.
+
+To talk about exactly what the primitives guarantee, we need to clarify what we mean by server side changes. 
+In this document we will use a term syncable state to refer to any state mutated under the WindowManager lock
+which when observed by the client, produces a visible outcome in the produced frame. 
+For example the current Configuration. 
+
+The guarantee provided by Server-side BLAST Sync Primitives is thus:
+Guarantee 1:	If you make a set of changes to syncable state, at the same time that you begin a sync, 
+then the first frame drawn by the client after observing the syncable state will be sent in a transaction
+to the consumer of the sync which was begun, rather than directly sent to SurfaceFlinger.
+
+Here "at the same time" means in the same critical section (while holding the WM lock)
+For example this guarantee means that you can write code like:
+	window.performConfigurationChange(someConfiguration)
+	window.applyOnNextDraw(consumer)
+And the consumer will always be passed the first frame containing the configuration change. This can work with any 
+syncable state not just Configuration.
+
+The following is the protocol and additional requirements for BLAST sync, and an analysis of why it is correct. Due to time
+constraints we analyze it for a single window only (as this is actually the hard part).
+
+Protocol requirements:
+    Server protocol, precondition, begin a syncSeqId integer per window at 0:
+        SA: Enter the critical section
+        SB: Change syncable state, any number of times, prepare any number of syncs (and
+            increment the seqId if a sync was prepared, assosciate it with the sync)
+        SC: Leave the critical section
+        SD: Send syncable state updates to the client, always paired with the current seqId
+        SE: When the client calls finishDrawing, execute the consumer for each sync with
+            seqId <= the seqId which the client passed to finishDrawing
+    Client protocol:
+        CA: Observe state and seqid changes up until a fixed frame deadline, then execute performTraversals
+        CB: If the seqId is incremeneted at the time of the frame deadline, configure the renderer to
+            redirect the next draw in to a transaction, record the seqId at the time
+        CC: When the draw is finished, send the transaction containing the draw to WM with the
+            previously recorded seqId
+    Additional requirements/assumptions:
+        1. The server may only send changes to the syncable state paired with the seqId. The client may
+           only receive them together (e.g. not from other sources)
+        2. In between changing and sending syncable state, the lock must be released and acquired again
+        3. The client wont draw a frame reflecting syncable state changes without passing through "performTraversals"
+        4. Drawing never fails
+        5. There are no blocking calls between the client or the server
+            
+Note that the server can begin the protocol at any time, so it may be possible for the client to proceed through
+phases SA, SB, SC, and SD multiple times before the client receives any messages.
+
+To show that the guarantee can't be violated, we use a notation of sequences, where we describe interleaving
+of protocol events. For duplicate events, we attach a number, e.g. SA_1, SA_2.
+
+We proceed by contradiction, imagine there was some sequence (..., SA_N, ...) for which the guarantee was
+not upheld. This means that either
+    1. finishDrawing with the assosciate seqId was never sent to the server OR
+    2. It was sent too late (after the first frame was sent to SF instead of WM) OR
+    3. It was sent too early (not containing the state changes originating with SA_N)
+If it was sent neither too late, nor too early, and contained the assosciated seqId, then protocol step SE
+says that the frame will be passed to the consumer and we uphold our guarantee.
+
+The first case is impossible because step SD says that the server always sends the seqId if a sync was prepared.
+If we send it the client must receive it. Since we only increment the seqId, and the client only takes the
+seqId from us (requirement 1, protocol step SB), the received ID must be higher than the clients previous seqId.
+CA says that performTraversals will execute, and CB says that when it does, if the seqId is higher than before
+it will schedule the render to sync. Requirement 4 says drawing never fails, so CC must execute, and so we will always
+eventually send every seqId (or a seqId > than it) back to the server.
+
+It also can't be sent too late. By requirement 2 we must release and acquire the lock
+after after changing and before emitting syncable state changes. This means it's guaranteed
+that even in an ordering like AcquireLock, ChangeState, PrepareSync, Release lock we can't
+send the state changes before prepareSync, and so they can always include at least the seqId
+assosciated with changestate (or a later one).
+Since we only receive the SeqId with the State changes (requirement 1),
+and we wont draw state changes without passing through perform traversals (requirement 3) the first frame
+containing the state change must have been generated by a call to performTraversals which also observed
+the seqId change, and so it will appropriately configure the renderer.
+
+By the same argument it can't be sent too early! Since we only send seqIds we receive from the server, 
+and we only send seqIds after completing a drawing pass of the assosciated state.
+
+So we can see that no matter at what time the server makes syncable state changes, the first frame will
+always be delivered to the draw handler. Assuming that the client and server uphold this protocol and these
+requirements.
+
+The trickiest part of the implementation at the moment is due to assosciating seqId. Currently we send one of the most
+most important pieces of syncable state (configuration) over multiple channels. Namely ClientTransaction
+and MSG_RESIZED. The ordering of these relative to sync preparation in server code is undefined, in fact we have cases like
+this all the time:
+    acquireLock()
+    changeConfiguration()
+    // time passes, but still in critical section
+    prepareSync()
+    releaseLock()
+This is exactly the kind of case Guarantee 1 mentions as an example. In previous incarnations of the code this worked
+because relayoutWindow needed to acquire the same lock and relayoutWindow was a necessary part of completing sync.
+
+Now that we have no barrier, that could create issues, because at the time we change configuration (and send the change
+to the client via ClientTransaction), we haven't even incremented the seqId yet, and so how can the client observe it
+at the same time as the state? We solve this by pushing all client communication through a handler thread that has to
+acquire the lock. This ensures we uphold requirement 2.
+    
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 23f14a7..dbc0141 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -25,6 +25,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
+import android.os.Bundle;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
 import android.os.SystemProperties;
@@ -44,7 +45,11 @@
 class BackNavigationController {
 
     private static final String TAG = "BackNavigationController";
-    private static final String BACK_PREDICTABILITY_PROP = "persist.debug.back_predictability";
+    // By default, enable new back dispatching without any animations.
+    private static final int BACK_PREDICTABILITY_PROP =
+            SystemProperties.getInt("persist.debug.back_predictability", 1);
+    private static final int ANIMATIONS_MASK = 1 << 1;
+    private static final int SCREENSHOT_MASK = 1 << 2;
 
     @Nullable
     private TaskSnapshotController mTaskSnapshotController;
@@ -53,11 +58,15 @@
      * Returns true if the back predictability feature is enabled
      */
     static boolean isEnabled() {
-        return SystemProperties.getInt(BACK_PREDICTABILITY_PROP, 0) > 0;
+        return BACK_PREDICTABILITY_PROP > 0;
     }
 
     static boolean isScreenshotEnabled() {
-        return false;
+        return (BACK_PREDICTABILITY_PROP & SCREENSHOT_MASK) != 0;
+    }
+
+    private static boolean isAnimationEnabled() {
+        return (BACK_PREDICTABILITY_PROP & ANIMATIONS_MASK) != 0;
     }
 
     /**
@@ -93,14 +102,17 @@
         ActivityRecord prev;
         WindowContainer<?> removedWindowContainer;
         ActivityRecord activityRecord;
+        ActivityRecord prevTaskTopActivity = null;
         SurfaceControl animationLeashParent;
         WindowConfiguration taskWindowConfiguration;
         HardwareBuffer screenshotBuffer = null;
+        SurfaceControl screenshotSurface;
         int prevTaskId;
         int prevUserId;
         RemoteAnimationTarget topAppTarget;
         SurfaceControl animLeash;
-        IOnBackInvokedCallback callback = null;
+        IOnBackInvokedCallback applicationCallback = null;
+        IOnBackInvokedCallback systemCallback = null;
 
         synchronized (task.mWmService.mGlobalLock) {
 
@@ -116,15 +128,14 @@
                 removedWindowContainer = activityRecord;
                 taskWindowConfiguration = window.getWindowConfiguration();
             }
-            IOnBackInvokedCallback applicationCallback = null;
-            IOnBackInvokedCallback systemCallback = null;
             if (window != null) {
                 applicationCallback = window.getApplicationOnBackInvokedCallback();
-                callback = applicationCallback;
-                if (callback == null) {
-                    systemCallback = window.getSystemOnBackInvokedCallback();
-                    callback = systemCallback;
-                }
+                systemCallback = window.getSystemOnBackInvokedCallback();
+            }
+            if (applicationCallback == null && systemCallback == null) {
+                // Return null when either there's no window, or apps have just initialized and
+                // have not finished registering callbacks.
+                return null;
             }
 
             ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "startBackNavigation task=%s, "
@@ -133,24 +144,24 @@
                     task, activityRecord, applicationCallback, systemCallback);
 
             // TODO Temp workaround for Sysui until b/221071505 is fixed
-            if (activityRecord == null && callback != null) {
+            if (activityRecord == null && applicationCallback != null) {
                 return new BackNavigationInfo(BackNavigationInfo.TYPE_CALLBACK,
                         null /* topWindowLeash */, null /* screenshotSurface */,
                         null /* screenshotBuffer */, null /* taskWindowConfiguration */,
                         null /* onBackNavigationDone */,
-                        callback /* onBackInvokedCallback */);
+                        applicationCallback /* onBackInvokedCallback */);
             }
 
             // For IME and Home, either a callback is registered, or we do nothing. In both cases,
             // we don't need to pass the leashes below.
             if (activityRecord == null || task.getDisplayContent().getImeContainer().isVisible()
                     || activityRecord.isActivityTypeHome()) {
-                if (callback != null) {
+                if (applicationCallback != null) {
                     return new BackNavigationInfo(BackNavigationInfo.TYPE_CALLBACK,
                             null /* topWindowLeash */, null /* screenshotSurface */,
                             null /* screenshotBuffer */, null /* taskWindowConfiguration */,
                             null /* onBackNavigationDone */,
-                            callback /* onBackInvokedCallback */);
+                            applicationCallback /* onBackInvokedCallback */);
                 } else {
                     return null;
                 }
@@ -159,12 +170,12 @@
             prev = task.getActivity(
                     (r) -> !r.finishing && r.getTask() == task && !r.isTopRunningActivity());
 
-            if (callback != null) {
+            if (applicationCallback != null) {
                 return new BackNavigationInfo(BackNavigationInfo.TYPE_CALLBACK,
                         null /* topWindowLeash */, null /* screenshotSurface */,
                         null /* screenshotBuffer */, null /* taskWindowConfiguration */,
                         null /* onBackNavigationDone */,
-                        callback /* onBackInvokedCallback */);
+                        applicationCallback /* onBackInvokedCallback */);
             } else if (prev != null) {
                 backType = BackNavigationInfo.TYPE_CROSS_ACTIVITY;
             } else if (task.returnsToHomeRootTask()) {
@@ -188,8 +199,8 @@
             prevTaskId = prevTask != null ? prevTask.mTaskId : 0;
             prevUserId = prevTask != null ? prevTask.mUserId : 0;
 
-            ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Previous Activity is %s",
-                    prev != null ? prev.mActivityComponent : null);
+            ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Previous Activity is %s. "
+                    + "Back type is %s", prev != null ? prev.mActivityComponent : null, backType);
 
             //TODO(207481538) Remove once the infrastructure to support per-activity screenshot is
             // implemented. For now we simply have the mBackScreenshots hash map that dumbly
@@ -204,6 +215,7 @@
                 return null;
             }
             // Prepare a leash to animate the current top window
+            // TODO(b/220934562): Use surface animator to better manage animation conflicts.
             animLeash = removedWindowContainer.makeAnimationLeash()
                     .setName("BackPreview Leash for " + removedWindowContainer)
                     .setHidden(false)
@@ -231,12 +243,30 @@
                     activityRecord.windowType);
         }
 
-        SurfaceControl.Builder builder = new SurfaceControl.Builder()
+        screenshotSurface = new SurfaceControl.Builder()
                 .setName("BackPreview Screenshot for " + prev)
                 .setParent(animationLeashParent)
                 .setHidden(false)
-                .setBLASTLayer();
-        SurfaceControl screenshotSurface = builder.build();
+                .setBLASTLayer()
+                .build();
+        if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME && isAnimationEnabled()) {
+            task.mBackGestureStarted = true;
+            // Make launcher show from behind by marking its top activity as visible and
+            // launch-behind to bump its visibility for the duration of the back gesture.
+            prevTaskTopActivity = prevTask.getTopNonFinishingActivity();
+            if (prevTaskTopActivity != null) {
+                if (!prevTaskTopActivity.mVisibleRequested) {
+                    prevTaskTopActivity.setVisibility(true);
+                }
+                prevTaskTopActivity.mLaunchTaskBehind = true;
+                ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
+                        "Setting Activity.mLauncherTaskBehind to true. Activity=%s",
+                        prevTaskTopActivity);
+                prevTaskTopActivity.mRootWindowContainer.ensureActivitiesVisible(
+                        null /* starting */, 0 /* configChanges */,
+                        false /* preserveWindows */);
+            }
+        }
 
         // Find a screenshot of the previous activity
 
@@ -253,17 +283,20 @@
 
         WindowContainer<?> finalRemovedWindowContainer = removedWindowContainer;
         try {
-            activityRecord.token.linkToDeath(
-                    () -> resetSurfaces(finalRemovedWindowContainer), 0);
+            activityRecord.token.linkToDeath(() -> resetSurfaces(finalRemovedWindowContainer), 0);
         } catch (RemoteException e) {
             Slog.e(TAG, "Failed to link to death", e);
             resetSurfaces(removedWindowContainer);
             return null;
         }
 
-        RemoteCallback onBackNavigationDone = new RemoteCallback(
-                result -> resetSurfaces(finalRemovedWindowContainer
-                ));
+        int finalBackType = backType;
+        final IOnBackInvokedCallback callback =
+                applicationCallback != null ? applicationCallback : systemCallback;
+        ActivityRecord finalPrevTaskTopActivity = prevTaskTopActivity;
+        RemoteCallback onBackNavigationDone = new RemoteCallback(result -> onBackNavigationDone(
+                result, finalRemovedWindowContainer, finalBackType, task,
+                finalPrevTaskTopActivity));
         return new BackNavigationInfo(backType,
                 topAppTarget,
                 screenshotSurface,
@@ -273,6 +306,39 @@
                 callback);
     }
 
+    private void onBackNavigationDone(
+            Bundle result, WindowContainer windowContainer, int backType,
+            Task task, ActivityRecord prevTaskTopActivity) {
+        SurfaceControl surfaceControl = windowContainer.getSurfaceControl();
+        boolean triggerBack = result != null
+                ? result.getBoolean(BackNavigationInfo.KEY_TRIGGER_BACK)
+                : false;
+        ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "onBackNavigationDone backType=%s, "
+                + "task=%s, prevTaskTopActivity=%s", backType, task, prevTaskTopActivity);
+
+        if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME && isAnimationEnabled()) {
+            if (triggerBack) {
+                if (surfaceControl != null && surfaceControl.isValid()) {
+                    // When going back to home, hide the task surface before it is re-parented to
+                    // avoid flicker.
+                    SurfaceControl.Transaction t = windowContainer.getSyncTransaction();
+                    t.hide(surfaceControl);
+                    t.apply();
+                }
+            }
+            if (prevTaskTopActivity != null && !triggerBack) {
+                // Restore the launch-behind state.
+                task.mTaskSupervisor.scheduleLaunchTaskBehindComplete(prevTaskTopActivity.token);
+                prevTaskTopActivity.mLaunchTaskBehind = false;
+                ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
+                        "Setting Activity.mLauncherTaskBehind to false. Activity=%s",
+                        prevTaskTopActivity);
+            }
+        } else {
+            task.mBackGestureStarted = false;
+        }
+        resetSurfaces(windowContainer);
+    }
 
     private HardwareBuffer getActivitySnapshot(@NonNull Task task,
             ComponentName activityComponent) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 718a28d..73673202 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -131,6 +131,7 @@
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowContainerChildProto.DISPLAY_CONTENT;
@@ -144,7 +145,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.H.REPORT_HARD_KEYBOARD_STATUS_CHANGE;
 import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
-import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_ASSIGN_LAYERS;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
@@ -627,9 +627,6 @@
     @VisibleForTesting
     SurfaceControl mInputMethodSurfaceParent;
 
-    /** The screenshot IME surface to place on the task while transitioning to the next task. */
-    SurfaceControl mImeScreenshot;
-
     private final PointerEventDispatcher mPointerEventDispatcher;
 
     private final InsetsStateController mInsetsStateController;
@@ -3974,10 +3971,13 @@
         // If the IME target is the input target, before it changes, prepare the IME screenshot
         // for the last IME target when its task is applying app transition. This is for the
         // better IME transition to keep IME visibility when transitioning to the next task.
-        if (mImeLayeringTarget != null && mImeLayeringTarget.isAnimating(PARENTS | TRANSITION,
-                ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)
-                && mImeLayeringTarget == mImeInputTarget) {
-            attachAndShowImeScreenshotOnTarget();
+        if (mImeLayeringTarget != null && mImeLayeringTarget == mImeInputTarget) {
+            boolean nonAppImeTargetAnimatingExit = mImeLayeringTarget.mAnimatingExit
+                    && mImeLayeringTarget.mAttrs.type != TYPE_BASE_APPLICATION
+                    && mImeLayeringTarget.isSelfAnimating(0, ANIMATION_TYPE_WINDOW_ANIMATION);
+            if (mImeLayeringTarget.inAppOrRecentsTransition() || nonAppImeTargetAnimatingExit) {
+                showImeScreenshot();
+            }
         }
 
         ProtoLog.i(WM_DEBUG_IME, "setInputMethodTarget %s", target);
@@ -4025,8 +4025,117 @@
         mImeControlTarget = target;
     }
 
-    @VisibleForTesting
-    void attachAndShowImeScreenshotOnTarget() {
+    // ========== Begin of ImeScreenshot stuff ==========
+    /** The screenshot IME surface to place on the task while transitioning to the next task. */
+    ImeScreenshot mImeScreenshot;
+
+    static final class ImeScreenshot {
+        private WindowState mImeTarget;
+        private SurfaceControl.Builder mSurfaceBuilder;
+        private SurfaceControl mImeSurface;
+
+        ImeScreenshot(SurfaceControl.Builder surfaceBuilder, @NonNull WindowState imeTarget) {
+            mSurfaceBuilder = surfaceBuilder;
+            mImeTarget = imeTarget;
+        }
+
+        WindowState getImeTarget() {
+            return mImeTarget;
+        }
+
+        private SurfaceControl createImeSurface(SurfaceControl.ScreenshotHardwareBuffer b,
+                Transaction t) {
+            final HardwareBuffer buffer = b.getHardwareBuffer();
+            if (DEBUG_INPUT_METHOD) {
+                Slog.d(TAG, "create IME snapshot for "
+                        + mImeTarget + ", buff width=" + buffer.getWidth()
+                        + ", height=" + buffer.getHeight());
+            }
+            final WindowState imeWindow = mImeTarget.getDisplayContent().mInputMethodWindow;
+            final ActivityRecord activity = mImeTarget.mActivityRecord;
+            final SurfaceControl imeParent = mImeTarget.mAttrs.type == TYPE_BASE_APPLICATION
+                    ? activity.getSurfaceControl()
+                    : mImeTarget.getSurfaceControl();
+            final SurfaceControl imeSurface = mSurfaceBuilder
+                    .setName("IME-snapshot-surface")
+                    .setBLASTLayer()
+                    .setFormat(buffer.getFormat())
+                    // Attaching IME snapshot to the associated IME layering target on the
+                    // activity when:
+                    // - The target is activity main window: attaching on top of the activity.
+                    // - The target is non-activity main window (e.g. activity overlay or
+                    // dialog-themed activity): attaching on top of the target since the layer has
+                    // already above the activity.
+                    .setParent(imeParent)
+                    .setCallsite("DisplayContent.attachAndShowImeScreenshotOnTarget")
+                    .build();
+            // Make IME snapshot as trusted overlay
+            InputMonitor.setTrustedOverlayInputInfo(imeSurface, t, imeWindow.getDisplayId(),
+                    "IME-snapshot-surface");
+            t.setBuffer(imeSurface, buffer);
+            t.setColorSpace(activity.mSurfaceControl, ColorSpace.get(ColorSpace.Named.SRGB));
+            t.setLayer(imeSurface, 1);
+
+            final Point surfacePosition = new Point(
+                    imeWindow.getFrame().left - mImeTarget.getFrame().left,
+                    imeWindow.getFrame().top - mImeTarget.getFrame().top);
+            if (imeParent == activity.getSurfaceControl()) {
+                t.setPosition(imeSurface, surfacePosition.x, surfacePosition.y);
+            } else {
+                surfacePosition.offset(mImeTarget.mAttrs.surfaceInsets.left,
+                        mImeTarget.mAttrs.surfaceInsets.top);
+                t.setPosition(imeSurface, surfacePosition.x, surfacePosition.y);
+            }
+            return imeSurface;
+        }
+
+        private void removeImeSurface(Transaction t) {
+            if (mImeSurface != null) {
+                if (DEBUG_INPUT_METHOD) Slog.d(TAG, "remove IME snapshot");
+                t.remove(mImeSurface);
+                mImeSurface = null;
+            }
+        }
+
+        void attachAndShow(Transaction t) {
+            final DisplayContent dc = mImeTarget.getDisplayContent();
+            // Prepare IME screenshot for the target if it allows to attach into.
+            final Task task = mImeTarget.getTask();
+            // Re-new the IME screenshot when it does not exist or the size changed.
+            final boolean renewImeSurface = mImeSurface == null
+                    || mImeSurface.getWidth() != dc.mInputMethodWindow.getFrame().width()
+                    || mImeSurface.getHeight() != dc.mInputMethodWindow.getFrame().height();
+            if (task != null && !task.isActivityTypeHomeOrRecents()) {
+                SurfaceControl.ScreenshotHardwareBuffer imeBuffer = renewImeSurface
+                        ? dc.mWmService.mTaskSnapshotController.snapshotImeFromAttachedTask(task)
+                        : null;
+                if (imeBuffer != null) {
+                    // Remove the last IME surface when the surface needs to renew.
+                    removeImeSurface(t);
+                    mImeSurface = createImeSurface(imeBuffer, t);
+                }
+            }
+            final boolean isValidSnapshot = mImeSurface != null && mImeSurface.isValid();
+            // Showing the IME screenshot if the target has already in app transition stage.
+            // Note that if the current IME insets is not showing, no need to show IME screenshot
+            // to reflect the true IME insets visibility and the app task layout as possible.
+            if (isValidSnapshot
+                    && dc.getInsetsStateController().getImeSourceProvider().isImeShowing()) {
+                if (DEBUG_INPUT_METHOD) {
+                    Slog.d(TAG, "show IME snapshot, ime target=" + mImeTarget);
+                }
+                t.show(mImeSurface);
+            } else if (!isValidSnapshot) {
+                removeImeSurface(t);
+            }
+        }
+
+        void detach(Transaction t) {
+            removeImeSurface(t);
+        }
+    }
+
+    private void attachAndShowImeScreenshotOnTarget() {
         // No need to attach screenshot if the IME target not exists or screen is off.
         if (!shouldImeAttachedToApp() || !mWmService.mPolicy.isScreenOn()) {
             return;
@@ -4035,61 +4144,10 @@
         final SurfaceControl.Transaction t = getPendingTransaction();
         // Prepare IME screenshot for the target if it allows to attach into.
         if (mInputMethodWindow != null && mInputMethodWindow.isVisible()) {
-            final Task task = mImeLayeringTarget.getTask();
-            // Re-new the IME screenshot when it does not exist or the size changed.
-            final boolean renewImeSurface = mImeScreenshot == null
-                    || mImeScreenshot.getWidth() != mInputMethodWindow.getFrame().width()
-                    || mImeScreenshot.getHeight() != mInputMethodWindow.getFrame().height();
-            if (task != null && !task.isActivityTypeHomeOrRecents()) {
-                SurfaceControl.ScreenshotHardwareBuffer imeBuffer = renewImeSurface
-                        ? mWmService.mTaskSnapshotController.snapshotImeFromAttachedTask(task)
-                        : null;
-                if (imeBuffer != null) {
-                    // Remove the last IME surface when the surface needs to renew.
-                    removeImeSurfaceImmediately();
-                    mImeScreenshot = createImeSurface(imeBuffer, t);
-                }
-            }
+            mImeScreenshot = new ImeScreenshot(
+                    mWmService.mSurfaceControlFactory.apply(null), mImeLayeringTarget);
+            mImeScreenshot.attachAndShow(t);
         }
-
-        final boolean isValidSnapshot = mImeScreenshot != null && mImeScreenshot.isValid();
-        // Showing the IME screenshot if the target has already in app transition stage.
-        // Note that if the current IME insets is not showing, no need to show IME screenshot
-        // to reflect the true IME insets visibility and the app task layout as possible.
-        if (isValidSnapshot && getInsetsStateController().getImeSourceProvider().isImeShowing()) {
-            if (DEBUG_INPUT_METHOD) {
-                Slog.d(TAG, "show IME snapshot, ime target=" + mImeLayeringTarget);
-            }
-            t.show(mImeScreenshot);
-        } else if (!isValidSnapshot) {
-            removeImeSurfaceImmediately();
-        }
-    }
-
-    @VisibleForTesting
-    SurfaceControl createImeSurface(SurfaceControl.ScreenshotHardwareBuffer imeBuffer,
-            Transaction t) {
-        final HardwareBuffer buffer = imeBuffer.getHardwareBuffer();
-        if (DEBUG_INPUT_METHOD) Slog.d(TAG, "create IME snapshot for "
-                + mImeLayeringTarget + ", buff width=" + buffer.getWidth()
-                + ", height=" + buffer.getHeight());
-        final ActivityRecord activity = mImeLayeringTarget.mActivityRecord;
-        final SurfaceControl imeSurface = mWmService.mSurfaceControlFactory.apply(null)
-                .setName("IME-snapshot-surface")
-                .setBLASTLayer()
-                .setFormat(buffer.getFormat())
-                .setParent(activity.getSurfaceControl())
-                .setCallsite("DisplayContent.attachAndShowImeScreenshotOnTarget")
-                .build();
-        // Make IME snapshot as trusted overlay
-        InputMonitor.setTrustedOverlayInputInfo(imeSurface, t, getDisplayId(),
-                "IME-snapshot-surface");
-        t.setBuffer(imeSurface, buffer);
-        t.setColorSpace(mSurfaceControl, ColorSpace.get(ColorSpace.Named.SRGB));
-        t.setLayer(imeSurface, 1);
-        t.setPosition(imeSurface, mInputMethodWindow.getDisplayFrame().left,
-                mInputMethodWindow.getDisplayFrame().top);
-        return imeSurface;
     }
 
     /**
@@ -4111,8 +4169,7 @@
     void removeImeScreenshotIfPossible() {
         if (mImeLayeringTarget == null
                 || mImeLayeringTarget.mAttrs.type != TYPE_APPLICATION_STARTING
-                && !mImeLayeringTarget.isAnimating(PARENTS | TRANSITION,
-                ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)) {
+                && !mImeLayeringTarget.inAppOrRecentsTransition()) {
             removeImeSurfaceImmediately();
         }
     }
@@ -4120,11 +4177,11 @@
     /** Removes the IME screenshot immediately. */
     void removeImeSurfaceImmediately() {
         if (mImeScreenshot != null) {
-            if (DEBUG_INPUT_METHOD) Slog.d(TAG, "remove IME snapshot");
-            getSyncTransaction().remove(mImeScreenshot);
+            mImeScreenshot.detach(getSyncTransaction());
             mImeScreenshot = null;
         }
     }
+ // ========== End of ImeScreenshot stuff ==========
 
     /**
      * The IME input target is the window which receives input from IME. It is also a candidate
@@ -4212,17 +4269,17 @@
      */
     @VisibleForTesting
     SurfaceControl computeImeParent() {
+        if (mImeLayeringTarget != null && mImeInputTarget != null
+                && mImeLayeringTarget.mActivityRecord != mImeInputTarget.getActivityRecord()) {
+            // Do not change parent if the window hasn't requested IME.
+            return null;
+        }
         // Attach it to app if the target is part of an app and such app is covering the entire
         // screen. If it's not covering the entire screen the IME might extend beyond the apps
         // bounds.
         if (shouldImeAttachedToApp()) {
-            if (mImeLayeringTarget.mActivityRecord != mImeInputTarget.getActivityRecord()) {
-                // Do not change parent if the window hasn't requested IME.
-                return null;
-            }
             return mImeLayeringTarget.mActivityRecord.getSurfaceControl();
         }
-
         // Otherwise, we just attach it to where the display area policy put it.
         return mImeWindowsContainer.getParent() != null
                 ? mImeWindowsContainer.getParent().getSurfaceControl() : null;
@@ -4433,7 +4490,9 @@
      * hierarchy.
      */
     void onWindowAnimationFinished(@NonNull WindowContainer wc, int type) {
-        if (type == ANIMATION_TYPE_APP_TRANSITION || type == ANIMATION_TYPE_RECENTS) {
+        if (mImeScreenshot != null && (wc == mImeScreenshot.getImeTarget()
+                || wc.getWindow(w -> w == mImeScreenshot.getImeTarget()) != null)
+                && (type & WindowState.EXIT_ANIMATING_TYPES) != 0) {
             removeImeSurfaceImmediately();
         }
     }
@@ -4444,56 +4503,38 @@
 
         mTmpUpdateAllDrawn.clear();
 
-        int repeats = 0;
-        do {
-            repeats++;
-            if (repeats > 6) {
-                Slog.w(TAG, "Animation repeat aborted after too many iterations");
-                clearLayoutNeeded();
-                break;
-            }
+        if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("On entry to LockedInner",
+                pendingLayoutChanges);
 
-            if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("On entry to LockedInner",
-                    pendingLayoutChanges);
+        if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
+            mWallpaperController.adjustWallpaperWindows();
+        }
 
-            if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
-                mWallpaperController.adjustWallpaperWindows();
-            }
-
-            if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
-                if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
-                if (updateOrientation()) {
-                    setLayoutNeeded();
-                    sendNewConfiguration();
-                }
-            }
-
-            if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
+        if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
+            if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
+            if (updateOrientation()) {
                 setLayoutNeeded();
+                sendNewConfiguration();
             }
+        }
 
-            // FIRST LOOP: Perform a layout, if needed.
-            if (repeats < LAYOUT_REPEAT_THRESHOLD) {
-                performLayout(repeats == 1, false /* updateInputWindows */);
-            } else {
-                Slog.w(TAG, "Layout repeat skipped after too many iterations");
-            }
+        if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
+            setLayoutNeeded();
+        }
 
-            // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think it is animating.
-            pendingLayoutChanges = 0;
+        // Perform a layout, if needed.
+        performLayout(true /* initial */, false /* updateInputWindows */);
+        pendingLayoutChanges = 0;
 
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy");
-            try {
-                mDisplayPolicy.beginPostLayoutPolicyLw();
-                forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */);
-                pendingLayoutChanges |= mDisplayPolicy.finishPostLayoutPolicyLw();
-            } finally {
-                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-            }
-            if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
-                    "after finishPostLayoutPolicyLw", pendingLayoutChanges);
-            mInsetsStateController.onPostLayout();
-        } while (pendingLayoutChanges != 0);
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy");
+        try {
+            mDisplayPolicy.beginPostLayoutPolicyLw();
+            forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */);
+            mDisplayPolicy.finishPostLayoutPolicyLw();
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+        mInsetsStateController.onPostLayout();
 
         mTmpApplySurfaceChangesTransactionState.reset();
 
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 4148d8b..bb5dacc 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -42,11 +42,9 @@
 import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -79,7 +77,6 @@
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
 import static com.android.server.policy.PhoneWindowManager.TOAST_WINDOW_TIMEOUT;
-import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static com.android.server.policy.WindowManagerPolicy.TRANSIT_ENTER;
 import static com.android.server.policy.WindowManagerPolicy.TRANSIT_EXIT;
 import static com.android.server.policy.WindowManagerPolicy.TRANSIT_HIDE;
@@ -136,6 +133,7 @@
 import android.view.WindowManagerGlobal;
 import android.view.WindowManagerPolicyConstants;
 import android.view.accessibility.AccessibilityManager;
+import android.window.ClientWindowFrames;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -340,15 +338,12 @@
     private static final Rect sTmpRect2 = new Rect();
     private static final Rect sTmpLastParentFrame = new Rect();
     private static final Rect sTmpDisplayCutoutSafe = new Rect();
-    private static final Rect sTmpDisplayFrame = new Rect();
-    private static final Rect sTmpParentFrame = new Rect();
-    private static final Rect sTmpFrame = new Rect();
+    private static final ClientWindowFrames sTmpClientFrames = new ClientWindowFrames();
 
     private final WindowLayout mWindowLayout = new WindowLayout();
 
     private WindowState mTopFullscreenOpaqueWindowState;
     private boolean mTopIsFullscreen;
-    private boolean mForceStatusBar;
     private int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED;
     private boolean mForceShowSystemBars;
 
@@ -940,6 +935,26 @@
                 break;
         }
 
+        if (LayoutParams.isSystemAlertWindowType(attrs.type)) {
+            float maxOpacity = mService.mMaximumObscuringOpacityForTouch;
+            if (attrs.alpha > maxOpacity
+                    && (attrs.flags & FLAG_NOT_TOUCHABLE) != 0
+                    && (attrs.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) == 0) {
+                // The app is posting a SAW with the intent of letting touches pass through, but
+                // they are going to be deemed untrusted and will be blocked. Try to honor the
+                // intent of letting touches pass through at the cost of 0.2 opacity for app
+                // compatibility reasons. More details on b/218777508.
+                Slog.w(TAG, String.format(
+                        "App %s has a system alert window (type = %d) with FLAG_NOT_TOUCHABLE and "
+                                + "LayoutParams.alpha = %.2f > %.2f, setting alpha to %.2f to "
+                                + "let touches pass through (if this is isn't desirable, remove "
+                                + "flag FLAG_NOT_TOUCHABLE).",
+                        attrs.packageName, attrs.type, attrs.alpha, maxOpacity, maxOpacity));
+                attrs.alpha = maxOpacity;
+                win.mWinAnimator.mAlpha = maxOpacity;
+            }
+        }
+
         // Check if alternate bars positions were updated.
         if (mStatusBarAlt == win) {
             mStatusBarAltPosition = getAltBarPosition(attrs);
@@ -1474,8 +1489,8 @@
                     displayFrames.mUnrestricted, win.getWindowingMode(), UNSPECIFIED_LENGTH,
                     UNSPECIFIED_LENGTH, win.getRequestedVisibilities(),
                     null /* attachedWindowFrame */, win.mGlobalScale,
-                    sTmpDisplayFrame, sTmpParentFrame, sTmpFrame);
-            controller.computeSimulatedState(win, displayFrames, sTmpFrame);
+                    sTmpClientFrames);
+            controller.computeSimulatedState(win, displayFrames, sTmpClientFrames.frame);
         }
     }
 
@@ -1518,12 +1533,12 @@
 
         sTmpLastParentFrame.set(pf);
 
-        final boolean clippedByDisplayCutout = mWindowLayout.computeFrames(attrs,
-                win.getInsetsState(), displayFrames.mDisplayCutoutSafe,
+        mWindowLayout.computeFrames(attrs, win.getInsetsState(), displayFrames.mDisplayCutoutSafe,
                 win.getBounds(), win.getWindowingMode(), requestedWidth, requestedHeight,
                 win.getRequestedVisibilities(), attachedWindowFrame, win.mGlobalScale,
-                df, pf, f);
-        windowFrames.setParentFrameWasClippedByDisplayCutout(clippedByDisplayCutout);
+                sTmpClientFrames);
+        windowFrames.setParentFrameWasClippedByDisplayCutout(
+                sTmpClientFrames.isParentFrameClippedByDisplayCutout);
 
         if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
                 + ": sim=#" + Integer.toHexString(attrs.softInputMode)
@@ -1536,7 +1551,7 @@
             windowFrames.setContentChanged(true);
         }
 
-        win.setFrame();
+        win.setFrames(sTmpClientFrames);
     }
 
     WindowState getTopFullscreenOpaqueWindow() {
@@ -1558,7 +1573,6 @@
         mStatusBarBackgroundWindows.clear();
         mStatusBarColorCheckedBounds.setEmpty();
         mStatusBarBackgroundCheckedBounds.setEmpty();
-        mForceStatusBar = false;
 
         mAllowLockscreenWhenOn = false;
         mShowingDream = false;
@@ -1599,9 +1613,6 @@
                 && attrs.type < FIRST_SYSTEM_WINDOW;
         if (mTopFullscreenOpaqueWindowState == null) {
             final int fl = attrs.flags;
-            if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
-                mForceStatusBar = true;
-            }
             if (win.isDreamWindow()) {
                 // If the lockscreen was showing when the dream started then wait
                 // for the dream to draw before hiding the lockscreen.
@@ -1710,21 +1721,9 @@
     }
 
     /**
-     * Called following layout of all windows and after policy has been applied
-     * to each window. If in this function you do
-     * something that may have modified the animation state of another window,
-     * be sure to return non-zero in order to perform another pass through layout.
-     *
-     * @return Return any bit set of
-     *         {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_LAYOUT},
-     *         {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_CONFIG},
-     *         {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_WALLPAPER}, or
-     *         {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_ANIM}.
+     * Called following layout of all windows and after policy has been applied to each window.
      */
-    public int finishPostLayoutPolicyLw() {
-        int changes = 0;
-        boolean topIsFullscreen = false;
-
+    public void finishPostLayoutPolicyLw() {
         // If we are not currently showing a dream then remember the current
         // lockscreen state.  We will use this to determine whether the dream
         // started while the lockscreen was showing and remember this state
@@ -1733,41 +1732,6 @@
             mDreamingLockscreen = mService.mPolicy.isKeyguardShowingAndNotOccluded();
         }
 
-        if (getStatusBar() != null) {
-            if (DEBUG_LAYOUT) Slog.i(TAG, "force=" + mForceStatusBar
-                    + " top=" + mTopFullscreenOpaqueWindowState);
-            final boolean forceShowStatusBar = (getStatusBar().getAttrs().privateFlags
-                    & PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR) != 0;
-
-            boolean topAppHidesStatusBar = topAppHidesStatusBar();
-            if (mForceStatusBar || forceShowStatusBar) {
-                if (DEBUG_LAYOUT) Slog.v(TAG, "Showing status bar: forced");
-                // Maintain fullscreen layout until incoming animation is complete.
-                topIsFullscreen = mTopIsFullscreen && mStatusBar.isAnimatingLw();
-            } else if (mTopFullscreenOpaqueWindowState != null) {
-                topIsFullscreen = topAppHidesStatusBar;
-                // The subtle difference between the window for mTopFullscreenOpaqueWindowState
-                // and mTopIsFullscreen is that mTopIsFullscreen is set only if the window
-                // requests to hide the status bar.  Not sure if there is another way that to be the
-                // case though.
-                if (!topIsFullscreen) {
-                    topAppHidesStatusBar = false;
-                }
-            }
-            StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
-            if (statusBar != null) {
-                statusBar.setTopAppHidesStatusBar(topAppHidesStatusBar);
-            }
-        }
-
-        if (mTopIsFullscreen != topIsFullscreen) {
-            if (!topIsFullscreen) {
-                // Force another layout when status bar becomes fully shown.
-                changes |= FINISH_LAYOUT_REDO_LAYOUT;
-            }
-            mTopIsFullscreen = topIsFullscreen;
-        }
-
         updateSystemBarAttributes();
 
         if (mShowingDream != mLastShowingDream) {
@@ -1777,7 +1741,6 @@
         }
 
         mService.mPolicy.setAllowLockscreenWhenOn(getDisplayId(), mAllowLockscreenWhenOn);
-        return changes;
     }
 
     /**
@@ -2441,6 +2404,18 @@
         mForceShowSystemBars = multiWindowTaskVisible || freeformRootTaskVisible;
         mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);
 
+        final boolean topAppHidesStatusBar = topAppHidesStatusBar();
+        if (getStatusBar() != null) {
+            final StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
+            if (statusBar != null) {
+                statusBar.setTopAppHidesStatusBar(topAppHidesStatusBar);
+            }
+        }
+
+        // If the top app is not fullscreen, only the default rotation animation is allowed.
+        mTopIsFullscreen = topAppHidesStatusBar
+                && (mNotificationShade == null || !mNotificationShade.isVisible());
+
         int appearance = APPEARANCE_OPAQUE_NAVIGATION_BARS | APPEARANCE_OPAQUE_STATUS_BARS;
         appearance = configureStatusBarOpacity(appearance);
         appearance = configureNavBarOpacity(appearance, multiWindowTaskVisible,
@@ -2781,7 +2756,6 @@
             }
         }
         pw.print(prefix); pw.print("mTopIsFullscreen="); pw.println(mTopIsFullscreen);
-        pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar);
         pw.print(prefix); pw.print("mForceShowNavigationBarEnabled=");
         pw.print(mForceShowNavigationBarEnabled);
         pw.print(" mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn);
diff --git a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
index 60d2a5d..27d46ec 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.WindowConfiguration;
 import android.content.pm.ActivityInfo;
 import android.os.UserHandle;
 import android.util.ArraySet;
@@ -63,13 +64,14 @@
     }
 
     /**
-     * @see DisplayWindowPolicyController#canContainActivities(List)
+     * @see DisplayWindowPolicyController#canContainActivities(List, int)
      */
-    public boolean canContainActivities(@NonNull List<ActivityInfo> activities) {
+    public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
+            @WindowConfiguration.WindowingMode int windowingMode) {
         if (mDisplayWindowPolicyController == null) {
             return true;
         }
-        return mDisplayWindowPolicyController.canContainActivities(activities);
+        return mDisplayWindowPolicyController.canContainActivities(activities, windowingMode);
     }
 
     /**
@@ -126,6 +128,17 @@
         }
     }
 
+    /**
+     * @see DisplayWindowPolicyController#isWindowingModeSupported(int)
+     */
+    public final boolean isWindowingModeSupported(
+            @WindowConfiguration.WindowingMode int windowingMode) {
+        if (mDisplayWindowPolicyController == null) {
+            return true;
+        }
+        return mDisplayWindowPolicyController.isWindowingModeSupported(windowingMode);
+    }
+
     void dump(String prefix, PrintWriter pw) {
         if (mDisplayWindowPolicyController != null) {
             pw.println();
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 00380bb..c47d778 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -44,6 +44,7 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.IBinder;
+import android.os.InputConfig;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -127,7 +128,7 @@
 
     @Nullable private ValueAnimator mAnimator;
     private final Interpolator mCubicEaseOutInterpolator = new DecelerateInterpolator(1.5f);
-    private Point mDisplaySize = new Point();
+    private final Point mDisplaySize = new Point();
 
     // A surface used to catch input events for the drag-and-drop operation.
     SurfaceControl mInputSurface;
@@ -160,8 +161,7 @@
 
     private void showInputSurface() {
         if (mInputSurface == null) {
-            mInputSurface = mService.makeSurfaceBuilder(
-                    mService.mRoot.getDisplayContent(mDisplayContent.getDisplayId()).getSession())
+            mInputSurface = mService.makeSurfaceBuilder(mDisplayContent.getSession())
                     .setContainerLayer()
                     .setName("Drag and Drop Input Consumer")
                     .setCallsite("DragState.showInputSurface")
@@ -174,17 +174,18 @@
             return;
         }
 
-        mTransaction.show(mInputSurface);
-        mTransaction.setInputWindowInfo(mInputSurface, h);
-        mTransaction.setLayer(mInputSurface, Integer.MAX_VALUE);
-
+        // Crop the input surface to the display size.
         mTmpClipRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
-        mTransaction.setWindowCrop(mInputSurface, mTmpClipRect);
+
+        mTransaction.show(mInputSurface)
+                .setInputWindowInfo(mInputSurface, h)
+                .setLayer(mInputSurface, Integer.MAX_VALUE)
+                .setCrop(mInputSurface, mTmpClipRect);
 
         // syncInputWindows here to ensure the input window info is sent before the
         // transferTouchFocus is called.
-        mTransaction.syncInputWindows();
-        mTransaction.apply(true);
+        mTransaction.syncInputWindows()
+                .apply(true /*sync*/);
     }
 
     /**
@@ -361,29 +362,20 @@
                     display.getDisplayId());
             mDragWindowHandle.name = "drag";
             mDragWindowHandle.token = mClientChannel.getToken();
-            mDragWindowHandle.layoutParamsFlags = 0;
             mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
             mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-            mDragWindowHandle.visible = true;
-            // Allows the system to consume keys when dragging is active. This can also be used to
-            // modify the drag state on key press. Example, cancel drag on escape key.
-            mDragWindowHandle.focusable = true;
-            mDragWindowHandle.hasWallpaper = false;
-            mDragWindowHandle.paused = false;
             mDragWindowHandle.ownerPid = Process.myPid();
             mDragWindowHandle.ownerUid = Process.myUid();
-            mDragWindowHandle.inputFeatures = 0;
             mDragWindowHandle.scaleFactor = 1.0f;
 
+            // Keep the default behavior of this window to be focusable, which allows the system
+            // to consume keys when dragging is active. This can also be used to modify the drag
+            // state on key press. For example, cancel drag on escape key.
+            mDragWindowHandle.inputConfig = InputConfig.PREVENT_SPLITTING;
+
             // The drag window cannot receive new touches.
             mDragWindowHandle.touchableRegion.setEmpty();
 
-            // The drag window covers the entire display
-            mDragWindowHandle.frameLeft = 0;
-            mDragWindowHandle.frameTop = 0;
-            mDragWindowHandle.frameRight = mDisplaySize.x;
-            mDragWindowHandle.frameBottom = mDisplaySize.y;
-
             // Pause rotations before a drag.
             ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during drag");
             mService.mRoot.forAllDisplays(dc -> {
diff --git a/services/core/java/com/android/server/wm/InputConfigAdapter.java b/services/core/java/com/android/server/wm/InputConfigAdapter.java
new file mode 100644
index 0000000..2dcde4e
--- /dev/null
+++ b/services/core/java/com/android/server/wm/InputConfigAdapter.java
@@ -0,0 +1,138 @@
+/*
+ * 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.wm;
+
+import android.os.InputConfig;
+import android.view.InputWindowHandle.InputConfigFlags;
+import android.view.WindowManager.LayoutParams;
+
+import java.util.List;
+
+/**
+ * A helper to determine the {@link InputConfigFlags} that control the behavior of an input window
+ * from several WM attributes.
+ */
+class InputConfigAdapter {
+    private InputConfigAdapter() {}
+
+    /** Describes a mapping from a flag value to a {@link InputConfigFlags} value. */
+    private static class FlagMapping {
+        final int mFlag;
+        final int mInputConfig;
+        final boolean mInverted;
+
+        FlagMapping(int flag, int inputConfig, boolean inverted) {
+            mFlag = flag;
+            mInputConfig = inputConfig;
+            mInverted = inverted;
+        }
+    }
+
+    /**
+     * A mapping from {@link LayoutParams.InputFeatureFlags} to {@link InputConfigFlags} for
+     * input configurations that can be mapped directly from a corresponding LayoutParams input
+     * feature.
+     */
+    private static final List<FlagMapping> INPUT_FEATURE_TO_CONFIG_MAP = List.of(
+            new FlagMapping(
+                    LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL,
+                    InputConfig.NO_INPUT_CHANNEL, false /* inverted */),
+            new FlagMapping(
+                    LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY,
+                    InputConfig.DISABLE_USER_ACTIVITY, false /* inverted */),
+            new FlagMapping(
+                    LayoutParams.INPUT_FEATURE_SPY,
+                    InputConfig.SPY, false /* inverted */));
+
+    @InputConfigFlags
+    private static final int INPUT_FEATURE_TO_CONFIG_MASK =
+            computeMask(INPUT_FEATURE_TO_CONFIG_MAP);
+
+    /**
+     * A mapping from {@link LayoutParams.Flags} to {@link InputConfigFlags} for input
+     * configurations that can be mapped directly from a corresponding LayoutParams flag.
+     *
+     * NOTE: The layout params flag {@link LayoutParams#FLAG_NOT_FOCUSABLE} is not handled by this
+     * adapter, and must be handled explicitly.
+     */
+    private static final List<FlagMapping> LAYOUT_PARAM_FLAG_TO_CONFIG_MAP = List.of(
+            new FlagMapping(
+                    LayoutParams.FLAG_NOT_TOUCHABLE,
+                    InputConfig.NOT_TOUCHABLE, false /* inverted */),
+            new FlagMapping(
+                    LayoutParams.FLAG_SPLIT_TOUCH,
+                    InputConfig.PREVENT_SPLITTING, true /* inverted */),
+            new FlagMapping(
+                    LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
+                    InputConfig.WATCH_OUTSIDE_TOUCH, false /* inverted */),
+            new FlagMapping(
+                    LayoutParams.FLAG_SLIPPERY,
+                    InputConfig.SLIPPERY, false /* inverted */));
+
+    @InputConfigFlags
+    private static final int LAYOUT_PARAM_FLAG_TO_CONFIG_MASK =
+            computeMask(LAYOUT_PARAM_FLAG_TO_CONFIG_MAP);
+
+    /**
+     * Returns a mask of all the input config flags configured by
+     * {@link #getInputConfigFromWindowParams(int, int, int)}.
+     */
+    @InputConfigFlags
+    static int getMask() {
+        return LAYOUT_PARAM_FLAG_TO_CONFIG_MASK | INPUT_FEATURE_TO_CONFIG_MASK
+                | InputConfig.IS_WALLPAPER;
+    }
+
+    /**
+     * Get the {@link InputConfigFlags} value that provides the input window behavior specified by
+     * the given WindowManager attributes.
+     *
+     * Use {@link #getMask()} to get the mask of all the input config flags set by this method.
+     *
+     * @param type the window type
+     * @param flags the window flags
+     * @param inputFeatures the input feature flags
+     */
+    @InputConfigFlags
+    static int getInputConfigFromWindowParams(@LayoutParams.WindowType int type,
+            @LayoutParams.Flags int flags, @LayoutParams.InputFeatureFlags int inputFeatures) {
+        return (type == LayoutParams.TYPE_WALLPAPER ? InputConfig.IS_WALLPAPER : 0)
+                | applyMapping(flags, LAYOUT_PARAM_FLAG_TO_CONFIG_MAP)
+                | applyMapping(inputFeatures, INPUT_FEATURE_TO_CONFIG_MAP);
+    }
+
+    @InputConfigFlags
+    private static int applyMapping(int flags, List<FlagMapping> flagToConfigMap) {
+        int inputConfig = 0;
+        for (final FlagMapping mapping : flagToConfigMap) {
+            final boolean flagSet = (flags & mapping.mFlag) != 0;
+            if (flagSet != mapping.mInverted) {
+                inputConfig |= mapping.mInputConfig;
+            }
+        }
+        return inputConfig;
+    }
+
+    @InputConfigFlags
+    private static int computeMask(List<FlagMapping> flagToConfigMap) {
+        int mask = 0;
+        for (final FlagMapping mapping : flagToConfigMap) {
+            mask |= mapping.mInputConfig;
+        }
+        return mask;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index cbd5646..59be3e0 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -22,6 +22,7 @@
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.InputConfig;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -70,19 +71,14 @@
         mWindowHandle.name = name;
         mWindowHandle.token = mClientChannel.getToken();
         mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
-        mWindowHandle.layoutParamsFlags = 0;
         mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-        mWindowHandle.visible = true;
-        mWindowHandle.focusable = false;
-        mWindowHandle.hasWallpaper = false;
-        mWindowHandle.paused = false;
         mWindowHandle.ownerPid = Process.myPid();
         mWindowHandle.ownerUid = Process.myUid();
-        mWindowHandle.inputFeatures = 0;
         mWindowHandle.scaleFactor = 1.0f;
-        mWindowHandle.trustedOverlay = true;
+        mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.TRUSTED_OVERLAY;
 
-        mInputSurface = mService.makeSurfaceBuilder(mService.mRoot.getDisplayContent(displayId).getSession())
+        mInputSurface = mService.makeSurfaceBuilder(
+                        mService.mRoot.getDisplayContent(displayId).getSession())
                 .setContainerLayer()
                 .setName("Input Consumer " + name)
                 .setCallsite("InputConsumerImpl")
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index c4f685b..8038f44 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -21,7 +21,6 @@
 import static android.view.WindowManager.INPUT_CONSUMER_PIP;
 import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
 import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
 import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
@@ -53,6 +52,7 @@
 import android.graphics.Region;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.InputConfig;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.util.ArrayMap;
@@ -61,6 +61,7 @@
 import android.view.InputChannel;
 import android.view.InputWindowHandle;
 import android.view.SurfaceControl;
+import android.view.WindowManager;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.ProtoLog;
@@ -221,15 +222,13 @@
                 inputChannel, clientPid, clientUser, mDisplayId);
         switch (name) {
             case INPUT_CONSUMER_WALLPAPER:
-                consumer.mWindowHandle.hasWallpaper = true;
+                consumer.mWindowHandle.inputConfig |= InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER;
                 break;
             case INPUT_CONSUMER_PIP:
-                // The touchable region of the Pip input window is cropped to the bounds of the
-                // stack, and we need FLAG_NOT_TOUCH_MODAL to ensure other events fall through
-                consumer.mWindowHandle.layoutParamsFlags |= FLAG_NOT_TOUCH_MODAL;
+                // This is a valid consumer type, but we don't need any additional configurations.
                 break;
             case INPUT_CONSUMER_RECENTS_ANIMATION:
-                consumer.mWindowHandle.focusable = true;
+                consumer.mWindowHandle.inputConfig &= ~InputConfig.NOT_FOCUSABLE;
                 break;
             default:
                 throw new IllegalArgumentException("Illegal input consumer : " + name
@@ -247,11 +246,24 @@
         inputWindowHandle.setToken(w.mInputChannelToken);
         inputWindowHandle.setDispatchingTimeoutMillis(w.getInputDispatchingTimeoutMillis());
         inputWindowHandle.setTouchOcclusionMode(w.getTouchOcclusionMode());
-        inputWindowHandle.setInputFeatures(w.mAttrs.inputFeatures);
         inputWindowHandle.setPaused(w.mActivityRecord != null && w.mActivityRecord.paused);
-        inputWindowHandle.setVisible(w.isVisible());
         inputWindowHandle.setWindowToken(w.mClient);
 
+        // Update layout params flags to force the window to be not touch modal. We do this to
+        // restrict the window's touchable region to the task even if it requests touches outside
+        // its window bounds. An example is a dialog in primary split should get touches outside its
+        // window within the primary task but should not get any touches going to the secondary
+        // task.
+        int flags = w.mAttrs.flags;
+        if (w.mAttrs.isModal()) {
+            flags = flags | FLAG_NOT_TOUCH_MODAL;
+        }
+        inputWindowHandle.setLayoutParamsFlags(flags);
+        inputWindowHandle.setInputConfigMasked(
+                InputConfigAdapter.getInputConfigFromWindowParams(
+                        w.mAttrs.type, flags, w.mAttrs.inputFeatures),
+                InputConfigAdapter.getMask());
+
         final boolean focusable = w.canReceiveKeys()
                 && (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop());
         inputWindowHandle.setFocusable(focusable);
@@ -270,17 +282,6 @@
         // what is on screen to what is actually being touched in the UI.
         inputWindowHandle.setScaleFactor(w.mGlobalScale != 1f ? (1f / w.mGlobalScale) : 1f);
 
-        // Update layout params flags to force the window to be not touch modal. We do this to
-        // restrict the window's touchable region to the task even if it request touches outside its
-        // window bounds. An example is a dialog in primary split should get touches outside its
-        // window within the primary task but should not get any touches going to the secondary
-        // task.
-        int flags = w.mAttrs.flags;
-        if (w.mAttrs.isModal()) {
-            flags = flags | FLAG_NOT_TOUCH_MODAL;
-        }
-        inputWindowHandle.setLayoutParamsFlags(flags);
-
         boolean useSurfaceBoundsAsTouchRegion = false;
         SurfaceControl touchableRegionCrop = null;
         final Task task = w.getTask();
@@ -590,6 +591,8 @@
 
             if (mAddWallpaperInputConsumerHandle) {
                 if (w.mAttrs.type == TYPE_WALLPAPER && w.isVisible()) {
+                    mWallpaperInputConsumer.mWindowHandle
+                            .replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
                     // Add the wallpaper input consumer above the first visible wallpaper.
                     mWallpaperInputConsumer.show(mInputTransaction, w);
                     mAddWallpaperInputConsumerHandle = false;
@@ -631,24 +634,27 @@
 
     static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle,
             WindowState w) {
-        populateOverlayInputInfo(inputWindowHandle, w.isVisible());
+        populateOverlayInputInfo(inputWindowHandle);
         inputWindowHandle.setTouchOcclusionMode(w.getTouchOcclusionMode());
     }
 
     // This would reset InputWindowHandle fields to prevent it could be found by input event.
     // We need to check if any new field of InputWindowHandle could impact the result.
     @VisibleForTesting
-    static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle,
-            boolean isVisible) {
+    static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle) {
         inputWindowHandle.setDispatchingTimeoutMillis(0); // It should never receive input.
-        inputWindowHandle.setVisible(isVisible);
         inputWindowHandle.setFocusable(false);
-        inputWindowHandle.setInputFeatures(INPUT_FEATURE_NO_INPUT_CHANNEL);
         // The input window handle without input channel must not have a token.
         inputWindowHandle.setToken(null);
         inputWindowHandle.setScaleFactor(1f);
-        inputWindowHandle.setLayoutParamsFlags(
-                FLAG_NOT_TOUCH_MODAL | FLAG_NOT_TOUCHABLE | FLAG_NOT_FOCUSABLE);
+        final int defaultType = WindowManager.LayoutParams.TYPE_APPLICATION;
+        inputWindowHandle.setLayoutParamsType(defaultType);
+        inputWindowHandle.setInputConfigMasked(
+                InputConfigAdapter.getInputConfigFromWindowParams(
+                        defaultType,
+                        FLAG_NOT_TOUCHABLE,
+                        INPUT_FEATURE_NO_INPUT_CHANNEL),
+                InputConfigAdapter.getMask());
         inputWindowHandle.clearTouchableRegion();
         inputWindowHandle.setTouchableRegionCrop(null);
     }
@@ -666,7 +672,7 @@
         inputWindowHandle.setName(name);
         inputWindowHandle.setLayoutParamsType(TYPE_SECURE_SYSTEM_OVERLAY);
         inputWindowHandle.setTrustedOverlay(true);
-        populateOverlayInputInfo(inputWindowHandle, true /* isVisible */);
+        populateOverlayInputInfo(inputWindowHandle);
         setInputWindowInfoIfNeeded(t, sc, inputWindowHandle);
     }
 
diff --git a/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
index 142d293..301c184 100644
--- a/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
+++ b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
@@ -20,10 +20,13 @@
 import android.annotation.Nullable;
 import android.graphics.Region;
 import android.os.IBinder;
+import android.os.InputConfig;
 import android.view.IWindow;
 import android.view.InputApplicationHandle;
 import android.view.InputWindowHandle;
+import android.view.InputWindowHandle.InputConfigFlags;
 import android.view.SurfaceControl;
+import android.view.WindowManager;
 
 import java.util.Objects;
 
@@ -31,8 +34,10 @@
  * The wrapper of {@link InputWindowHandle} with field change detection to reduce unnecessary
  * updates to surface, e.g. if there are no changes, then skip invocation of
  * {@link SurfaceControl.Transaction#setInputWindowInfo(SurfaceControl, InputWindowHandle)}.
+ * It also sets the {@link InputConfigFlags} values for the input window.
  */
 class InputWindowHandleWrapper {
+
     /** The wrapped handle should not be directly exposed to avoid untracked changes. */
     private final @NonNull InputWindowHandle mHandle;
 
@@ -65,7 +70,20 @@
     }
 
     boolean isFocusable() {
-        return mHandle.focusable;
+        return (mHandle.inputConfig & InputConfig.NOT_FOCUSABLE) == 0;
+    }
+
+    boolean isPaused() {
+        return (mHandle.inputConfig & InputConfig.PAUSE_DISPATCHING) != 0;
+    }
+
+    boolean isTrustedOverlay() {
+        return (mHandle.inputConfig & InputConfig.TRUSTED_OVERLAY) != 0;
+    }
+
+    boolean hasWallpaper() {
+        return (mHandle.inputConfig & InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER)
+                != 0;
     }
 
     InputApplicationHandle getInputApplicationHandle() {
@@ -96,7 +114,7 @@
         mChanged = true;
     }
 
-    void setLayoutParamsFlags(int flags) {
+    void setLayoutParamsFlags(@WindowManager.LayoutParams.Flags int flags) {
         if (mHandle.layoutParamsFlags == flags) {
             return;
         }
@@ -136,19 +154,11 @@
         mChanged = true;
     }
 
-    void setVisible(boolean visible) {
-        if (mHandle.visible == visible) {
-            return;
-        }
-        mHandle.visible = visible;
-        mChanged = true;
-    }
-
     void setFocusable(boolean focusable) {
-        if (mHandle.focusable == focusable) {
+        if (isFocusable() == focusable) {
             return;
         }
-        mHandle.focusable = focusable;
+        mHandle.setInputConfig(InputConfig.NOT_FOCUSABLE, !focusable);
         mChanged = true;
     }
 
@@ -161,26 +171,27 @@
     }
 
     void setHasWallpaper(boolean hasWallpaper) {
-        if (mHandle.hasWallpaper == hasWallpaper) {
+        if (this.hasWallpaper() == hasWallpaper) {
             return;
         }
-        mHandle.hasWallpaper = hasWallpaper;
+        mHandle.setInputConfig(InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER,
+                hasWallpaper);
         mChanged = true;
     }
 
     void setPaused(boolean paused) {
-        if (mHandle.paused == paused) {
+        if (isPaused() == paused) {
             return;
         }
-        mHandle.paused = paused;
+        mHandle.setInputConfig(InputConfig.PAUSE_DISPATCHING, paused);
         mChanged = true;
     }
 
     void setTrustedOverlay(boolean trustedOverlay) {
-        if (mHandle.trustedOverlay == trustedOverlay) {
+        if (isTrustedOverlay() == trustedOverlay) {
             return;
         }
-        mHandle.trustedOverlay = trustedOverlay;
+        mHandle.setInputConfig(InputConfig.TRUSTED_OVERLAY, trustedOverlay);
         mChanged = true;
     }
 
@@ -208,14 +219,6 @@
         mChanged = true;
     }
 
-    void setInputFeatures(int features) {
-        if (mHandle.inputFeatures == features) {
-            return;
-        }
-        mHandle.inputFeatures = features;
-        mChanged = true;
-    }
-
     void setDisplayId(int displayId) {
         if (mHandle.displayId == displayId) {
             return;
@@ -276,8 +279,14 @@
         mChanged = true;
     }
 
-    boolean isTrustedOverlay() {
-        return mHandle.trustedOverlay;
+    void setInputConfigMasked(@InputConfigFlags int inputConfig, @InputConfigFlags int mask) {
+        final int inputConfigMasked = inputConfig & mask;
+        if (inputConfigMasked == (mHandle.inputConfig & mask)) {
+            return;
+        }
+        mHandle.inputConfig &= ~mask;
+        mHandle.inputConfig |= inputConfigMasked;
+        mChanged = true;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 398816b..3951c56 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -424,14 +424,12 @@
                 return state;
             }
         } else if (w.mActivityRecord != null && w.mActivityRecord.mImeInsetsFrozenUntilStartInput) {
-            // During switching tasks with gestural navigation, if the IME is attached to
-            // one app window on that time, even the next app window is behind the IME window,
-            // conceptually the window should not receive the IME insets if the next window is
-            // not eligible IME requester and ready to show IME on top of it.
-            final boolean shouldImeAttachedToApp = mDisplayContent.shouldImeAttachedToApp();
+            // During switching tasks with gestural navigation, before the next IME input target
+            // starts the input, we should adjust and freeze the last IME visibility of the window
+            // in case delivering obsoleted IME insets state during transitioning.
             final InsetsSource originalImeSource = originalState.peekSource(ITYPE_IME);
 
-            if (shouldImeAttachedToApp && originalImeSource != null) {
+            if (originalImeSource != null) {
                 final boolean imeVisibility =
                         w.mActivityRecord.mLastImeShown || w.getRequestedVisibility(ITYPE_IME);
                 final InsetsState state = copyState ? new InsetsState(originalState)
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index c55af9b..7bf150b 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -443,6 +443,13 @@
                 || !mWindowManager.isKeyguardSecure(mService.getCurrentUserId());
     }
 
+    /**
+     * @return Whether the dream activity is on top of default display.
+     */
+    boolean isShowingDream() {
+        return getDisplayState(DEFAULT_DISPLAY).mShowingDream;
+    }
+
     private void dismissMultiWindowModeForTaskIfNeeded(int displayId,
             @Nullable Task currentTaskControllingOcclusion) {
         // TODO(b/113840485): Handle docked stack for individual display.
@@ -501,6 +508,7 @@
         private boolean mKeyguardGoingAway;
         private boolean mDismissalRequested;
         private boolean mOccluded;
+        private boolean mShowingDream;
 
         private ActivityRecord mTopOccludesActivity;
         private ActivityRecord mDismissingKeyguardActivity;
@@ -536,6 +544,7 @@
 
             mRequestDismissKeyguard = false;
             mOccluded = false;
+            mShowingDream = false;
 
             mTopOccludesActivity = null;
             mDismissingKeyguardActivity = null;
@@ -570,9 +579,9 @@
                 }
             }
 
-            final boolean dreaming = display.getDisplayPolicy().isShowingDreamLw() && (top != null
+            mShowingDream = display.getDisplayPolicy().isShowingDreamLw() && (top != null
                     && top.getActivityType() == ACTIVITY_TYPE_DREAM);
-            mOccluded = dreaming || occludedByActivity;
+            mOccluded = mShowingDream || occludedByActivity;
             mRequestDismissKeyguard = lastDismissKeyguardActivity != mDismissingKeyguardActivity
                     && !mOccluded
                     && mDismissingKeyguardActivity != null
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 4b98013..40df02c 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -24,6 +24,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.IBinder;
+import android.os.InputConfig;
 import android.os.Process;
 import android.view.GestureDetector;
 import android.view.InputChannel;
@@ -290,16 +291,12 @@
                     win.getDisplayId());
             mWindowHandle.name = name;
             mWindowHandle.token = mToken;
-            mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
-                    | WindowManager.LayoutParams.FLAG_SLIPPERY;
             mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
             mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-            mWindowHandle.visible = true;
             mWindowHandle.ownerPid = Process.myPid();
             mWindowHandle.ownerUid = Process.myUid();
             mWindowHandle.scaleFactor = 1.0f;
+            mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.SLIPPERY;
         }
 
         void updateTouchableRegion(Rect frame) {
diff --git a/services/core/java/com/android/server/wm/MirrorActiveUids.java b/services/core/java/com/android/server/wm/MirrorActiveUids.java
index 4e7f1d4..b9aa959 100644
--- a/services/core/java/com/android/server/wm/MirrorActiveUids.java
+++ b/services/core/java/com/android/server/wm/MirrorActiveUids.java
@@ -19,7 +19,7 @@
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
 
 import android.app.ActivityManager.ProcessState;
-import android.util.SparseArray;
+import android.util.SparseIntArray;
 
 import java.io.PrintWriter;
 
@@ -29,15 +29,14 @@
  * adjustment) or getting state from window manager (background start check).
  */
 class MirrorActiveUids {
-    private final SparseArray<UidRecord> mUidStates = new SparseArray<>();
+    /** Uid -> process state. */
+    private final SparseIntArray mUidStates = new SparseIntArray();
+
+    /** Uid -> number of non-app visible windows belong to the uid. */
+    private final SparseIntArray mNumNonAppVisibleWindowMap = new SparseIntArray();
 
     synchronized void onUidActive(int uid, int procState) {
-        UidRecord r = mUidStates.get(uid);
-        if (r == null) {
-            r = new UidRecord();
-            mUidStates.put(uid, r);
-        }
-        r.mProcState = procState;
+        mUidStates.put(uid, procState);
     }
 
     synchronized void onUidInactive(int uid) {
@@ -45,22 +44,28 @@
     }
 
     synchronized void onUidProcStateChanged(int uid, int procState) {
-        final UidRecord r = mUidStates.get(uid);
-        if (r != null) {
-            r.mProcState = procState;
+        final int index = mUidStates.indexOfKey(uid);
+        if (index >= 0) {
+            mUidStates.setValueAt(index, procState);
         }
     }
 
     synchronized @ProcessState int getUidState(int uid) {
-        final UidRecord r = mUidStates.get(uid);
-        return r != null ? r.mProcState : PROCESS_STATE_NONEXISTENT;
+        return mUidStates.get(uid, PROCESS_STATE_NONEXISTENT);
     }
 
     /** Called when the surface of non-application (exclude toast) window is shown or hidden. */
     synchronized void onNonAppSurfaceVisibilityChanged(int uid, boolean visible) {
-        final UidRecord r = mUidStates.get(uid);
-        if (r != null) {
-            r.mNumNonAppVisibleWindow += visible ? 1 : -1;
+        final int index = mNumNonAppVisibleWindowMap.indexOfKey(uid);
+        if (index >= 0) {
+            final int num = mNumNonAppVisibleWindowMap.valueAt(index) + (visible ? 1 : -1);
+            if (num > 0) {
+                mNumNonAppVisibleWindowMap.setValueAt(index, num);
+            } else {
+                mNumNonAppVisibleWindowMap.removeAt(index);
+            }
+        } else if (visible) {
+            mNumNonAppVisibleWindowMap.append(uid, 1);
         }
     }
 
@@ -70,23 +75,15 @@
      * {@link VisibleActivityProcessTracker}.
      */
     synchronized boolean hasNonAppVisibleWindow(int uid) {
-        final UidRecord r = mUidStates.get(uid);
-        return r != null && r.mNumNonAppVisibleWindow > 0;
+        return mNumNonAppVisibleWindowMap.get(uid) > 0;
     }
 
     synchronized void dump(PrintWriter pw, String prefix) {
-        pw.print(prefix + "NumNonAppVisibleWindowByUid:[");
-        for (int i = mUidStates.size() - 1; i >= 0; i--) {
-            final UidRecord r = mUidStates.valueAt(i);
-            if (r.mNumNonAppVisibleWindow > 0) {
-                pw.print(" " + mUidStates.keyAt(i) + ":" + r.mNumNonAppVisibleWindow);
-            }
+        pw.print(prefix + "NumNonAppVisibleWindowUidMap:[");
+        for (int i = mNumNonAppVisibleWindowMap.size() - 1; i >= 0; i--) {
+            pw.print(" " + mNumNonAppVisibleWindowMap.keyAt(i) + ":"
+                    + mNumNonAppVisibleWindowMap.valueAt(i));
         }
         pw.println("]");
     }
-
-    private static final class UidRecord {
-        @ProcessState int mProcState;
-        int mNumNonAppVisibleWindow;
-    }
 }
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index a407021..a4d338c 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -553,10 +553,6 @@
 
             mPendingStart = false;
 
-            // Perform layout if it was scheduled before to make sure that we get correct content
-            // insets for the target app window after a rotation
-            mDisplayContent.performLayout(false /* initial */, false /* updateInputWindows */);
-
             final Rect contentInsets;
             final WindowState targetAppMainWindow = getTargetAppMainWindow();
             if (targetAppMainWindow != null) {
diff --git a/services/core/java/com/android/server/wm/RefreshRatePolicy.java b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
index 7bddb62..f3713eb 100644
--- a/services/core/java/com/android/server/wm/RefreshRatePolicy.java
+++ b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
@@ -19,20 +19,46 @@
 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 
-import android.util.ArraySet;
+import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
 import android.view.Display;
 import android.view.Display.Mode;
 import android.view.DisplayInfo;
 
+import java.util.HashMap;
+
 /**
  * Policy to select a lower refresh rate for the display if applicable.
  */
 class RefreshRatePolicy {
 
+    class PackageRefreshRate {
+        private final HashMap<String, RefreshRateRange> mPackages = new HashMap<>();
+
+        public void add(String s, float minRefreshRate, float maxRefreshRate) {
+            float minSupportedRefreshRate =
+                    Math.max(RefreshRatePolicy.this.mMinSupportedRefreshRate, minRefreshRate);
+            float maxSupportedRefreshRate =
+                    Math.min(RefreshRatePolicy.this.mMaxSupportedRefreshRate, maxRefreshRate);
+
+            mPackages.put(s,
+                    new RefreshRateRange(minSupportedRefreshRate, maxSupportedRefreshRate));
+        }
+
+        public RefreshRateRange get(String s) {
+            return mPackages.get(s);
+        }
+
+        public void remove(String s) {
+            mPackages.remove(s);
+        }
+    }
+
     private final Mode mLowRefreshRateMode;
-    private final ArraySet<String> mNonHighRefreshRatePackages = new ArraySet<>();
+    private final PackageRefreshRate mNonHighRefreshRatePackages = new PackageRefreshRate();
     private final HighRefreshRateDenylist mHighRefreshRateDenylist;
     private final WindowManagerService mWmService;
+    private float mMinSupportedRefreshRate;
+    private float mMaxSupportedRefreshRate;
 
     /**
      * The following constants represent priority of the window. SF uses this information when
@@ -70,7 +96,12 @@
         Mode mode = displayInfo.getDefaultMode();
         float[] refreshRates = displayInfo.getDefaultRefreshRates();
         float bestRefreshRate = mode.getRefreshRate();
+        mMinSupportedRefreshRate = bestRefreshRate;
+        mMaxSupportedRefreshRate = bestRefreshRate;
         for (int i = refreshRates.length - 1; i >= 0; i--) {
+            mMinSupportedRefreshRate = Math.min(mMinSupportedRefreshRate, refreshRates[i]);
+            mMaxSupportedRefreshRate = Math.max(mMaxSupportedRefreshRate, refreshRates[i]);
+
             if (refreshRates[i] >= 60f && refreshRates[i] < bestRefreshRate) {
                 bestRefreshRate = refreshRates[i];
             }
@@ -78,12 +109,13 @@
         return displayInfo.findDefaultModeByRefreshRate(bestRefreshRate);
     }
 
-    void addNonHighRefreshRatePackage(String packageName) {
-        mNonHighRefreshRatePackages.add(packageName);
+    void addRefreshRateRangeForPackage(String packageName,
+            float minRefreshRate, float maxRefreshRate) {
+        mNonHighRefreshRatePackages.add(packageName, minRefreshRate, maxRefreshRate);
         mWmService.requestTraversal();
     }
 
-    void removeNonHighRefreshRatePackage(String packageName) {
+    void removeRefreshRateRangeForPackage(String packageName) {
         mNonHighRefreshRatePackages.remove(packageName);
         mWmService.requestTraversal();
     }
@@ -172,8 +204,9 @@
         // If app is using Camera, we set both the min and max refresh rate to the camera's
         // preferred refresh rate to make sure we don't end up with a refresh rate lower
         // than the camera capture rate, which will lead to dropping camera frames.
-        if (mNonHighRefreshRatePackages.contains(packageName)) {
-            return mLowRefreshRateMode.getRefreshRate();
+        RefreshRateRange range = mNonHighRefreshRatePackages.get(packageName);
+        if (range != null) {
+            return range.min;
         }
 
         return 0;
@@ -192,8 +225,9 @@
 
         final String packageName = w.getOwningPackage();
         // If app is using Camera, force it to default (lower) refresh rate.
-        if (mNonHighRefreshRatePackages.contains(packageName)) {
-            return mLowRefreshRateMode.getRefreshRate();
+        RefreshRateRange range = mNonHighRefreshRatePackages.get(packageName);
+        if (range != null) {
+            return range.max;
         }
 
         return 0;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index b9cd657..94fc51d 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -149,6 +149,7 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.am.AppTimeTracker;
 import com.android.server.am.UserState;
+import com.android.server.policy.PermissionPolicyInternal;
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.FileDescriptor;
@@ -2727,9 +2728,9 @@
         return false;
     }
 
-    Task getLaunchRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
+    Task getOrCreateRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
             @Nullable Task candidateTask, boolean onTop) {
-        return getLaunchRootTask(r, options, candidateTask, null /* sourceTask */, onTop,
+        return getOrCreateRootTask(r, options, candidateTask, null /* sourceTask */, onTop,
                 null /* launchParams */, 0 /* launchFlags */);
     }
 
@@ -2744,63 +2745,68 @@
      * @param launchFlags    The launch flags for this launch.
      * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
      * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
-     * @return The root task to use for the launch or INVALID_TASK_ID.
+     * @return The root task to use for the launch.
      */
-    Task getLaunchRootTask(@Nullable ActivityRecord r,
+    Task getOrCreateRootTask(@Nullable ActivityRecord r,
             @Nullable ActivityOptions options, @Nullable Task candidateTask,
             @Nullable Task sourceTask, boolean onTop,
             @Nullable LaunchParamsController.LaunchParams launchParams, int launchFlags) {
-        int taskId = INVALID_TASK_ID;
-        int displayId = INVALID_DISPLAY;
-        TaskDisplayArea taskDisplayArea = null;
-
-        // We give preference to the launch preference in activity options.
+        // First preference goes to the launch root task set in the activity options.
         if (options != null) {
-            taskId = options.getLaunchTaskId();
-            displayId = options.getLaunchDisplayId();
-            final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
-            taskDisplayArea = daToken != null
-                    ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null;
-
-            final Task rootTask = Task.fromWindowContainerToken(options.getLaunchRootTask());
-            if (rootTask != null) {
-                return rootTask;
+            final Task candidateRoot = Task.fromWindowContainerToken(options.getLaunchRootTask());
+            if (canLaunchOnDisplay(r, candidateRoot)) {
+                return candidateRoot;
             }
         }
 
-        // First preference for root task goes to the task Id set in the activity options. Use
-        // the root task associated with that if possible.
-        if (taskId != INVALID_TASK_ID) {
-            // Temporarily set the task id to invalid in case in re-entry.
-            options.setLaunchTaskId(INVALID_TASK_ID);
-            final Task task = anyTaskForId(taskId,
-                    MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
-            options.setLaunchTaskId(taskId);
-            if (task != null) {
-                return task.getRootTask();
+        // Next preference goes to the task id set in the activity options.
+        if (options != null) {
+            final int candidateTaskId = options.getLaunchTaskId();
+            if (candidateTaskId != INVALID_TASK_ID) {
+                // Temporarily set the task id to invalid in case in re-entry.
+                options.setLaunchTaskId(INVALID_TASK_ID);
+                final Task task = anyTaskForId(candidateTaskId,
+                        MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
+                options.setLaunchTaskId(candidateTaskId);
+                if (canLaunchOnDisplay(r, task)) {
+                    return task.getRootTask();
+                }
+            }
+        }
+
+        // Next preference goes to the TaskDisplayArea candidate from launchParams
+        // or activity options.
+        TaskDisplayArea taskDisplayArea = null;
+        if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null) {
+            taskDisplayArea = launchParams.mPreferredTaskDisplayArea;
+        } else if (options != null) {
+            final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
+            taskDisplayArea = daToken != null
+                    ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null;
+            if (taskDisplayArea == null) {
+                final int launchDisplayId = options.getLaunchDisplayId();
+                if (launchDisplayId != INVALID_DISPLAY) {
+                    final DisplayContent displayContent = getDisplayContent(launchDisplayId);
+                    if (displayContent != null) {
+                        taskDisplayArea = displayContent.getDefaultTaskDisplayArea();
+                    }
+                }
             }
         }
 
         final int activityType = resolveActivityType(r, options, candidateTask);
-        Task rootTask = null;
-
-        // Next preference for root task goes to the taskDisplayArea candidate.
-        if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null
-                && canLaunchOnDisplay(r, launchParams.mPreferredTaskDisplayArea.getDisplayId())) {
-            taskDisplayArea = launchParams.mPreferredTaskDisplayArea;
-        }
-        if (taskDisplayArea == null && displayId != INVALID_DISPLAY
-                && canLaunchOnDisplay(r, displayId)) {
-            taskDisplayArea = getDisplayContent(displayId).getDefaultTaskDisplayArea();
-        }
         if (taskDisplayArea != null) {
-            return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,
-                    sourceTask, launchParams, launchFlags, activityType, onTop);
+            if (canLaunchOnDisplay(r, taskDisplayArea.getDisplayId())) {
+                return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,
+                        sourceTask, launchParams, launchFlags, activityType, onTop);
+            } else {
+                taskDisplayArea = null;
+            }
         }
 
         // Give preference to the root task and display of the input task and activity if they
         // match the mode we want to launch into.
-        TaskDisplayArea container = null;
+        Task rootTask = null;
         if (candidateTask != null) {
             rootTask = candidateTask.getRootTask();
         }
@@ -2810,10 +2816,11 @@
         int windowingMode = launchParams != null ? launchParams.mWindowingMode
                 : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
         if (rootTask != null) {
-            container = rootTask.getDisplayArea();
-            if (container != null && canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
+            taskDisplayArea = rootTask.getDisplayArea();
+            if (taskDisplayArea != null
+                    && canLaunchOnDisplay(r, taskDisplayArea.mDisplayContent.mDisplayId)) {
                 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
-                    windowingMode = container.resolveWindowingMode(r, options, candidateTask);
+                    windowingMode = taskDisplayArea.resolveWindowingMode(r, options, candidateTask);
                 }
                 // Always allow organized tasks that created by organizer since the activity type
                 // of an organized task is decided by the activity type of its top child, which
@@ -2822,19 +2829,32 @@
                         || rootTask.mCreatedByOrganizer) {
                     return rootTask;
                 }
+            } else {
+                taskDisplayArea = null;
             }
+
         }
 
-        if (container == null
-                || !canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
-            container = getDefaultTaskDisplayArea();
-            if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
-                windowingMode = container.resolveWindowingMode(r, options, candidateTask);
-            }
+        // Falling back to default task container
+        if (taskDisplayArea == null) {
+            taskDisplayArea = getDefaultTaskDisplayArea();
+        }
+        return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask, sourceTask,
+                launchParams, launchFlags, activityType, onTop);
+    }
+
+    private boolean canLaunchOnDisplay(ActivityRecord r, Task task) {
+        if (task == null) {
+            Slog.w(TAG, "canLaunchOnDisplay(), invalid task: " + task);
+            return false;
         }
 
-        return container.getOrCreateRootTask(r, options, candidateTask, sourceTask, launchParams,
-                launchFlags, activityType, onTop);
+        if (!task.isAttached()) {
+            Slog.w(TAG, "canLaunchOnDisplay(), Task is not attached: " + task);
+            return false;
+        }
+
+        return canLaunchOnDisplay(r, task.getTaskDisplayArea().getDisplayId());
     }
 
     /** @return true if activity record is null or can be launched on provided display. */
@@ -2842,7 +2862,11 @@
         if (r == null) {
             return true;
         }
-        return r.canBeLaunchedOnDisplay(displayId);
+        if (!r.canBeLaunchedOnDisplay(displayId)) {
+            Slog.w(TAG, "Not allow to launch " + r + " on display " + displayId);
+            return false;
+        }
+        return true;
     }
 
     int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
@@ -3212,12 +3236,12 @@
             if (aOptions != null) {
                 // Resolve the root task the task should be placed in now based on options
                 // and reparent if needed.
-                final Task launchRootTask =
-                        getLaunchRootTask(null, aOptions, task, onTop);
-                if (launchRootTask != null && task.getRootTask() != launchRootTask) {
+                final Task targetRootTask =
+                        getOrCreateRootTask(null, aOptions, task, onTop);
+                if (targetRootTask != null && task.getRootTask() != targetRootTask) {
                     final int reparentMode = onTop
                             ? REPARENT_MOVE_ROOT_TASK_TO_FRONT : REPARENT_LEAVE_ROOT_TASK_IN_PLACE;
-                    task.reparent(launchRootTask, onTop, reparentMode, ANIMATE, DEFER_RESUME,
+                    task.reparent(targetRootTask, onTop, reparentMode, ANIMATE, DEFER_RESUME,
                             "anyTaskForId");
                 }
             }
@@ -3309,6 +3333,36 @@
     }
 
     /**
+     * Iterate over all task fragments, to see if there exists one that meets the
+     * PermissionPolicyService's criteria to show a permission dialog.
+     */
+    public int getTaskToShowPermissionDialogOn(String pkgName, int uid) {
+        PermissionPolicyInternal pPi = mService.getPermissionPolicyInternal();
+        if (pPi == null) {
+            return INVALID_TASK_ID;
+        }
+
+        final int[] validTaskId = {INVALID_TASK_ID};
+        forAllLeafTaskFragments(fragment -> {
+            ActivityRecord record = fragment.getActivity((r) -> {
+                // skip hidden (or about to hide) apps, or the permission dialog
+                return r.canBeTopRunning() && r.isVisibleRequested()
+                        && !pPi.isIntentToPermissionDialog(r.intent);
+            });
+            if (record != null && record.isUid(uid)
+                    && Objects.equals(pkgName, record.packageName)
+                    && pPi.shouldShowNotificationDialogForTask(record.getTask().getTaskInfo(),
+                    pkgName, record.intent)) {
+                validTaskId[0] = record.getTask().mTaskId;
+                return true;
+            }
+            return false;
+        });
+
+        return validTaskId[0];
+    }
+
+    /**
      * Dumps the activities matching the given {@param name} in the either the focused root task
      * or all visible root tasks if {@param dumpVisibleRootTasksOnly} is true.
      */
@@ -3322,11 +3376,17 @@
                 return new ArrayList<>();
             }
         } else {
+            final RecentTasks recentTasks = mWindowManager.mAtmService.getRecentTasks();
+            final int recentsComponentUid = recentTasks != null
+                    ? recentTasks.getRecentsComponentUid()
+                    : -1;
             final ArrayList<ActivityRecord> activities = new ArrayList<>();
-            forAllRootTasks(rootTask -> {
-                if (!dumpVisibleRootTasksOnly || rootTask.shouldBeVisible(null)) {
-                    activities.addAll(rootTask.getDumpActivitiesLocked(name, userId));
+            forAllLeafTasks(task -> {
+                final boolean isRecents = (task.effectiveUid == recentsComponentUid);
+                if (!dumpVisibleRootTasksOnly || task.shouldBeVisible(null) || isRecents) {
+                    activities.addAll(task.getDumpActivitiesLocked(name, userId));
                 }
+                return false;
             });
             return activities;
         }
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 3d6d182..1ec191e 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -57,8 +57,6 @@
     private ArraySet<Integer> mProfileIds;
     private boolean mAllowed;
     private boolean mFilterOnlyVisibleRecents;
-    private Task mTopDisplayFocusRootTask;
-    private Task mTopDisplayAdjacentTask;
     private RecentTasks mRecentTasks;
     private boolean mKeepIntentExtra;
 
@@ -78,17 +76,9 @@
         mAllowed = (flags & FLAG_ALLOWED) == FLAG_ALLOWED;
         mFilterOnlyVisibleRecents =
                 (flags & FLAG_FILTER_ONLY_VISIBLE_RECENTS) == FLAG_FILTER_ONLY_VISIBLE_RECENTS;
-        mTopDisplayFocusRootTask = root.getTopDisplayFocusedRootTask();
         mRecentTasks = root.mService.getRecentTasks();
         mKeepIntentExtra = (flags & FLAG_KEEP_INTENT_EXTRA) == FLAG_KEEP_INTENT_EXTRA;
 
-        if (mTopDisplayFocusRootTask != null
-                && mTopDisplayFocusRootTask.getAdjacentTaskFragment() != null) {
-            mTopDisplayAdjacentTask = mTopDisplayFocusRootTask.getAdjacentTaskFragment().asTask();
-        } else {
-            mTopDisplayAdjacentTask = null;
-        }
-
         final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this,
                 PooledLambda.__(Task.class));
         root.forAllLeafTasks(c, false);
@@ -132,18 +122,15 @@
             return;
         }
 
-        final Task rootTask = task.getRootTask();
-        if (rootTask == mTopDisplayFocusRootTask && rootTask.getTopMostTask() == task) {
-            // For the focused top root task, update the last root task active time so that it
-            // can be used to determine the order of the tasks (it may not be set for newly
-            // created tasks)
+        if (task.isVisible()) {
+            // For the visible task, update the last active time so that it can be used to determine
+            // the order of the tasks (it may not be set for newly created tasks)
             task.touchActiveTime();
-        } else if (rootTask == mTopDisplayAdjacentTask && rootTask.getTopMostTask() == task) {
-            // The short-term workaround for launcher could get suitable running task info in
-            // split screen.
-            task.touchActiveTime();
-            // TreeSet doesn't allow same value and make sure this task is lower than focus one.
-            task.lastActiveTime--;
+            if (!task.isFocused()) {
+                // TreeSet doesn't allow the same value and make sure this task is lower than the
+                // focused one.
+                task.lastActiveTime -= mTmpSortedSet.size();
+            }
         }
 
         mTmpSortedSet.add(task);
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 0c609191..9ad25ac8 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -232,14 +232,14 @@
             int requestedWidth, int requestedHeight, int viewFlags, int flags,
             ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
             SurfaceControl outSurfaceControl, InsetsState outInsetsState,
-            InsetsSourceControl[] outActiveControls) {
+            InsetsSourceControl[] outActiveControls, Bundle outSyncSeqIdBundle) {
         if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
                 + Binder.getCallingPid());
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);
         int res = mService.relayoutWindow(this, window, attrs,
                 requestedWidth, requestedHeight, viewFlags, flags,
                 outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
-                outActiveControls);
+                outActiveControls, outSyncSeqIdBundle);
         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
                 + Binder.getCallingPid());
@@ -265,9 +265,9 @@
 
     @Override
     public void finishDrawing(IWindow window,
-            @Nullable SurfaceControl.Transaction postDrawTransaction) {
+            @Nullable SurfaceControl.Transaction postDrawTransaction, int seqId) {
         if (DEBUG) Slog.v(TAG_WM, "IWindow finishDrawing called for " + window);
-        mService.finishDrawingWindow(this, window, postDrawTransaction);
+        mService.finishDrawingWindow(this, window, postDrawTransaction, seqId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7fe34f4..f71bd72 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -72,6 +72,7 @@
 import static com.android.internal.policy.DecorView.DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP;
 import static com.android.internal.policy.DecorView.DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BACK_PREVIEW;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
@@ -504,13 +505,6 @@
      */
     boolean mInRemoveTask;
 
-    // When non-null, this is a transaction that will get applied on the next frame returned after
-    // a relayout is requested from the client. While this is only valid on a leaf task; since the
-    // transaction can effect an ancestor task, this also needs to keep track of the ancestor task
-    // that this transaction manipulates because deferUntilFrame acts on individual surfaces.
-    SurfaceControl.Transaction mMainWindowSizeChangeTransaction;
-    Task mMainWindowSizeChangeTask;
-
     private final AnimatingActivityRegistry mAnimatingActivityRegistry =
             new AnimatingActivityRegistry();
 
@@ -616,6 +610,12 @@
 
     boolean mLastSurfaceShowing = true;
 
+    /**
+     * Tracks if a back gesture is in progress.
+     * Skips any system transition animations if this is set to {@code true}.
+     */
+    boolean mBackGestureStarted = false;
+
     private Task(ActivityTaskManagerService atmService, int _taskId, Intent _intent,
             Intent _affinityIntent, String _affinity, String _rootAffinity,
             ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
@@ -1530,7 +1530,7 @@
                 mTaskSupervisor.removeTask(this, false /* killProcess */,
                         !REMOVE_FROM_RECENTS, reason);
             }
-        } else if (!mReuseTask && !mCreatedByOrganizer) {
+        } else if (!mReuseTask && shouldRemoveSelfOnLastChildRemoval()) {
             // Remove entire task if it doesn't have any activity left and it isn't marked for reuse
             // or created by task organizer.
             if (!isRootTask()) {
@@ -1630,12 +1630,16 @@
     }
 
     ActivityRecord performClearTop(ActivityRecord newR, int launchFlags) {
+        // The task should be preserved for putting new activity in case the last activity is
+        // finished if it is normal launch mode and not single top ("clear-task-top").
+        mReuseTask = true;
         mTaskSupervisor.beginDeferResume();
         final ActivityRecord result;
         try {
             result = clearTopActivities(newR, launchFlags);
         } finally {
             mTaskSupervisor.endDeferResume();
+            mReuseTask = false;
         }
         return result;
     }
@@ -2043,8 +2047,10 @@
         Rect outOverrideBounds = getResolvedOverrideConfiguration().windowConfiguration.getBounds();
 
         if (windowingMode == WINDOWING_MODE_FULLSCREEN) {
-            // Use empty bounds to indicate "fill parent".
-            outOverrideBounds.setEmpty();
+            if (!mCreatedByOrganizer) {
+                // Use empty bounds to indicate "fill parent".
+                outOverrideBounds.setEmpty();
+            }
             // The bounds for fullscreen mode shouldn't be adjusted by minimal size. Otherwise if
             // the parent or display is smaller than the size, the content may be cropped.
             return;
@@ -3327,6 +3333,14 @@
                     }
                 });
             }
+        } else if (mBackGestureStarted) {
+            // Cancel playing transitions if a back navigation animation is in progress.
+            // This bit is set by {@link BackNavigationController} when a back gesture is started.
+            // It is used as a one-off transition overwrite that is cleared when the back gesture
+            // is committed and triggers a transition, or when the gesture is cancelled.
+            mBackGestureStarted = false;
+            mDisplayContent.mSkipAppTransitionAnimation = true;
+            ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Skipping app transition animation. task=%s", this);
         } else {
             super.applyAnimationUnchecked(lp, enter, transit, isVoiceInteraction, sources);
         }
@@ -3408,7 +3422,7 @@
         info.positionInParent = getRelativePosition();
 
         info.pictureInPictureParams = getPictureInPictureParams(top);
-        info.preferDockBigOverlays = getPreferDockBigOverlays();
+        info.shouldDockBigOverlays = shouldDockBigOverlays();
         if (info.pictureInPictureParams != null
                 && info.pictureInPictureParams.isLaunchIntoPip()
                 && top.getTopMostActivity().getLastParentBeforePip() != null) {
@@ -3461,9 +3475,9 @@
                 ? null : new PictureInPictureParams(topMostActivity.pictureInPictureArgs);
     }
 
-    private boolean getPreferDockBigOverlays() {
+    private boolean shouldDockBigOverlays() {
         final ActivityRecord topMostActivity = getTopMostActivity();
-        return topMostActivity != null && topMostActivity.preferDockBigOverlays;
+        return topMostActivity != null && topMostActivity.shouldDockBigOverlays;
     }
 
     Rect getDisplayCutoutInsets() {
@@ -4287,7 +4301,7 @@
     /**
      * @return true if the task is currently focused.
      */
-    private boolean isFocused() {
+    boolean isFocused() {
         if (mDisplayContent == null || mDisplayContent.mFocusedApp == null) {
             return false;
         }
@@ -4359,7 +4373,7 @@
         }
     }
 
-    void onPreferDockBigOverlaysChanged() {
+    void onShouldDockBigOverlaysChanged() {
         dispatchTaskInfoChangedIfNeeded(true /* force */);
     }
 
@@ -4390,17 +4404,16 @@
             leaf.setMainWindowSizeChangeTransaction(t, origin);
             return;
         }
-        mMainWindowSizeChangeTransaction = t;
-        mMainWindowSizeChangeTask = t == null ? null : origin;
+        final WindowState w = getTopVisibleAppMainWindow();
+        if (w != null) {
+            w.applyWithNextDraw((d) -> {
+                d.merge(t);
+            });
+        } else {
+            t.apply();
+        }
     }
 
-    SurfaceControl.Transaction getMainWindowSizeChangeTransaction() {
-        return mMainWindowSizeChangeTransaction;
-    }
-
-    Task getMainWindowSizeChangeTask() {
-        return mMainWindowSizeChangeTask;
-    }
 
     void setActivityWindowingMode(int windowingMode) {
         PooledConsumer c = PooledLambda.obtainConsumer(ActivityRecord::setWindowingMode,
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index afc3087..597d29f 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -242,7 +242,7 @@
 
     /** Client assigned unique token for this TaskFragment if this is created by an organizer. */
     @Nullable
-    private IBinder mFragmentToken;
+    private final IBinder mFragmentToken;
 
     /**
      * Whether to delay the last activity of TaskFragment being immediately removed while finishing.
@@ -516,12 +516,13 @@
      * @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord)
      */
     boolean isAllowedToEmbedActivity(@NonNull ActivityRecord a) {
-        if ((a.info.flags & FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING)
-                == FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING) {
-            return true;
-        }
+        return isAllowedToEmbedActivityInUntrustedMode(a)
+                || isAllowedToEmbedActivityInTrustedMode(a);
+    }
 
-        return isAllowedToEmbedActivityInTrustedMode(a);
+    boolean isAllowedToEmbedActivityInUntrustedMode(@NonNull ActivityRecord a) {
+        return (a.info.flags & FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING)
+                == FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING;
     }
 
     /**
@@ -531,7 +532,7 @@
      * <li>the activity has declared the organizer host as trusted explicitly via known
      * certificate.</li>
      */
-    private boolean isAllowedToEmbedActivityInTrustedMode(@NonNull ActivityRecord a) {
+    boolean isAllowedToEmbedActivityInTrustedMode(@NonNull ActivityRecord a) {
         if (UserHandle.getAppId(mTaskFragmentOrganizerUid) == SYSTEM_UID) {
             // The system is trusted to embed other apps securely and for all users.
             return true;
@@ -2303,6 +2304,10 @@
         mMinHeight = minHeight;
     }
 
+    boolean shouldRemoveSelfOnLastChildRemoval() {
+        return !mCreatedByOrganizer || mIsRemovalRequested;
+    }
+
     @Override
     void removeChild(WindowContainer child) {
         removeChild(child, true /* removeSelfIfPossible */);
@@ -2318,7 +2323,7 @@
                 mBackScreenshots.remove(r.mActivityComponent.flattenToString());
             }
         }
-        if (removeSelfIfPossible && (!mCreatedByOrganizer || mIsRemovalRequested) && !hasChild()) {
+        if (removeSelfIfPossible && shouldRemoveSelfOnLastChildRemoval() && !hasChild()) {
             removeImmediately("removeLastChild " + child);
         }
     }
@@ -2336,13 +2341,18 @@
             return;
         }
         mIsRemovalRequested = true;
-        forAllActivities(r -> {
-            if (withTransition) {
+        // The task order may be changed by finishIfPossible() for adjusting focus if there are
+        // nested tasks, so add all activities into a list to avoid missed removals.
+        final ArrayList<ActivityRecord> removingActivities = new ArrayList<>();
+        forAllActivities((Consumer<ActivityRecord>) removingActivities::add);
+        for (int i = removingActivities.size() - 1; i >= 0; --i) {
+            final ActivityRecord r = removingActivities.get(i);
+            if (withTransition && r.isVisible()) {
                 r.finishIfPossible(reason, false /* oomAdj */);
             } else {
                 r.destroyIfPossible(reason);
             }
-        });
+        }
     }
 
     void setDelayLastActivityRemoval(boolean delay) {
@@ -2382,10 +2392,18 @@
     void removeImmediately() {
         mIsRemovalRequested = false;
         resetAdjacentTaskFragment();
+        cleanUp();
         super.removeImmediately();
         sendTaskFragmentVanished();
     }
 
+    /** Called on remove to cleanup. */
+    private void cleanUp() {
+        if (mIsEmbedded) {
+            mAtmService.mWindowOrganizerController.cleanUpEmbeddedTaskFragment(this);
+        }
+    }
+
     @Override
     Dimmer getDimmer() {
         // If the window is in an embedded TaskFragment, we want to dim at the TaskFragment.
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 19f921d..bdec49e 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -140,7 +140,7 @@
                 mLastSentTaskFragmentInfos.put(tf, info);
                 tf.mTaskFragmentAppearedSent = true;
             } catch (RemoteException e) {
-                Slog.e(TAG, "Exception sending onTaskFragmentAppeared callback", e);
+                Slog.d(TAG, "Exception sending onTaskFragmentAppeared callback", e);
             }
             onTaskFragmentParentInfoChanged(organizer, tf);
         }
@@ -150,7 +150,7 @@
             try {
                 organizer.onTaskFragmentVanished(tf.getTaskFragmentInfo());
             } catch (RemoteException e) {
-                Slog.e(TAG, "Exception sending onTaskFragmentVanished callback", e);
+                Slog.d(TAG, "Exception sending onTaskFragmentVanished callback", e);
             }
             tf.mTaskFragmentAppearedSent = false;
             mLastSentTaskFragmentInfos.remove(tf);
@@ -175,7 +175,7 @@
                 organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo());
                 mLastSentTaskFragmentInfos.put(tf, info);
             } catch (RemoteException e) {
-                Slog.e(TAG, "Exception sending onTaskFragmentInfoChanged callback", e);
+                Slog.d(TAG, "Exception sending onTaskFragmentInfoChanged callback", e);
             }
         }
 
@@ -198,7 +198,7 @@
                 organizer.onTaskFragmentParentInfoChanged(tf.getFragmentToken(), parentConfig);
                 mLastSentTaskFragmentParentConfigs.put(tf, new Configuration(parentConfig));
             } catch (RemoteException e) {
-                Slog.e(TAG, "Exception sending onTaskFragmentParentInfoChanged callback", e);
+                Slog.d(TAG, "Exception sending onTaskFragmentParentInfoChanged callback", e);
             }
         }
 
@@ -210,7 +210,7 @@
             try {
                 organizer.onTaskFragmentError(errorCallbackToken, exceptionBundle);
             } catch (RemoteException e) {
-                Slog.e(TAG, "Exception sending onTaskFragmentError callback", e);
+                Slog.d(TAG, "Exception sending onTaskFragmentError callback", e);
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 331f124..ff5bfbe 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -800,17 +800,24 @@
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                DisplayContent dc = mService.mWindowManager.mRoot
+                final DisplayContent dc = mService.mWindowManager.mRoot
                         .getDisplayContent(displayId);
-                if (dc == null || dc.getImeTarget(IME_TARGET_LAYERING) == null) {
+                if (dc == null) {
                     return null;
                 }
+
+                final InsetsControlTarget imeLayeringTarget = dc.getImeTarget(IME_TARGET_LAYERING);
+                if (imeLayeringTarget == null || imeLayeringTarget.getWindow() == null) {
+                    return null;
+                }
+
                 // Avoid WindowState#getRootTask() so we don't attribute system windows to a task.
-                final Task task = dc.getImeTarget(IME_TARGET_LAYERING).getWindow().getTask();
+                final Task task = imeLayeringTarget.getWindow().asTask();
                 if (task == null) {
                     return null;
                 }
-                return task.getRootTask().mRemoteToken.toWindowContainerToken();
+
+                return task.mRemoteToken.toWindowContainerToken();
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 348cfb6..47c397d 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -40,6 +40,7 @@
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.InputConfig;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.Trace;
@@ -219,30 +220,17 @@
                 displayContent.getDisplayId());
         mDragWindowHandle.name = TAG;
         mDragWindowHandle.token = mClientChannel.getToken();
-        mDragWindowHandle.layoutParamsFlags = 0;
         mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
         mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-        mDragWindowHandle.visible = true;
-        // When dragging the window around, we do not want to steal focus for the window.
-        mDragWindowHandle.focusable = false;
-        mDragWindowHandle.hasWallpaper = false;
-        mDragWindowHandle.paused = false;
         mDragWindowHandle.ownerPid = Process.myPid();
         mDragWindowHandle.ownerUid = Process.myUid();
-        mDragWindowHandle.inputFeatures = 0;
         mDragWindowHandle.scaleFactor = 1.0f;
+        // When dragging the window around, we do not want to steal focus for the window.
+        mDragWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE;
 
         // The drag window cannot receive new touches.
         mDragWindowHandle.touchableRegion.setEmpty();
 
-        // The drag window covers the entire display.
-        final Rect displayBounds = mTmpRect;
-        displayContent.getBounds(mTmpRect);
-        mDragWindowHandle.frameLeft = displayBounds.left;
-        mDragWindowHandle.frameTop = displayBounds.top;
-        mDragWindowHandle.frameRight = displayBounds.right;
-        mDragWindowHandle.frameBottom = displayBounds.bottom;
-
         // Pause rotations before a drag.
         ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during re-position");
         mDisplayContent.getDisplayRotation().pause();
@@ -250,6 +238,8 @@
         // Notify InputMonitor to take mDragWindowHandle.
         mService.mTaskPositioningController.showInputSurface(win.getDisplayId());
 
+        final Rect displayBounds = mTmpRect;
+        displayContent.getBounds(displayBounds);
         final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics();
         mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics);
         mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics);
diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java
index 8f24f26..68bf2b2 100644
--- a/services/core/java/com/android/server/wm/TaskPositioningController.java
+++ b/services/core/java/com/android/server/wm/TaskPositioningController.java
@@ -83,17 +83,18 @@
             return;
         }
 
-        mTransaction.show(mInputSurface);
-        mTransaction.setInputWindowInfo(mInputSurface, h);
-        mTransaction.setLayer(mInputSurface, Integer.MAX_VALUE);
-
         final Display display = dc.getDisplay();
         final Point p = new Point();
         display.getRealSize(p);
-
         mTmpClipRect.set(0, 0, p.x, p.y);
-        mTransaction.setWindowCrop(mInputSurface, mTmpClipRect);
-        mTransaction.syncInputWindows().apply();
+
+        mTransaction.show(mInputSurface)
+                .setInputWindowInfo(mInputSurface, h)
+                .setLayer(mInputSurface, Integer.MAX_VALUE)
+                .setPosition(mInputSurface, 0, 0)
+                .setCrop(mInputSurface, mTmpClipRect)
+                .syncInputWindows()
+                .apply();
     }
 
     boolean startMovingTask(IWindow window, float startX, float startY) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 29d1742..21ca4bb 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -216,6 +216,7 @@
     }
 
     Task getTransientLaunchRestoreTarget(@NonNull WindowContainer container) {
+        if (mTransientLaunches == null) return null;
         for (int i = 0; i < mTransientLaunches.size(); ++i) {
             if (mTransientLaunches.keyAt(i).isDescendantOf(container)) {
                 return mTransientLaunches.valueAt(i);
@@ -491,7 +492,8 @@
                             // Avoid commit visibility to false here, or else we will get a sudden
                             // "flash" / surface going invisible for a split second.
                             commitVisibility = false;
-                        } else {
+                        } else if (ar.getDeferHidingClient()) {
+                            // Legacy PIP-enter requires pause event with user-leaving.
                             mController.mAtm.mTaskSupervisor.mUserLeaving = true;
                             ar.getTaskFragment().startPausing(false /* uiSleeping */,
                                     null /* resuming */, "finishTransition");
@@ -574,6 +576,7 @@
                             false /* disableImeIcon */);
                 }
             }
+            dc.removeImeSurfaceImmediately();
             dc.handleCompleteDeferredRemoval();
         }
     }
@@ -1526,6 +1529,9 @@
             if (task != null && task.voiceSession != null) {
                 flags |= FLAG_IS_VOICE_INTERACTION;
             }
+            if (task != null && task.isTranslucent(null)) {
+                flags |= FLAG_TRANSLUCENT;
+            }
             final ActivityRecord record = wc.asActivityRecord();
             if (record != null) {
                 if (record.mUseTransferredAnimation) {
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 0436233..8840cd5 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -61,7 +61,7 @@
 
     /** Whether to use shell-transitions rotation instead of fixed-rotation. */
     private static final boolean SHELL_TRANSITIONS_ROTATION =
-            SystemProperties.getBoolean("persist.debug.shell_transit_rotate", false);
+            SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false);
 
     /** The same as legacy APP_TRANSITION_TIMEOUT_MS. */
     private static final int DEFAULT_TIMEOUT_MS = 5000;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 56014ad..dab02de 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -73,6 +73,7 @@
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
+import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Debug;
@@ -3807,7 +3808,7 @@
         private void setTaskBackgroundColor(@ColorInt int backgroundColor) {
             TaskDisplayArea taskDisplayArea = getTaskDisplayArea();
 
-            if (taskDisplayArea != null) {
+            if (taskDisplayArea != null && backgroundColor != Color.TRANSPARENT) {
                 taskDisplayArea.setBackgroundColor(backgroundColor);
 
                 // Atomic counter to make sure the clearColor callback is only called one.
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 9585a4b..0a3c3f0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -725,17 +725,18 @@
     public abstract void hideIme(IBinder imeTargetWindowToken, int displayId);
 
     /**
-     * Tell window manager about a package that should not be running with high refresh rate
-     * setting until removeNonHighRefreshRatePackage is called for the same package.
+     * Tell window manager about a package that should be running with a restricted range of
+     * refresh rate setting until removeRefreshRateRangeForPackage is called for the same package.
      *
      * This must not be called again for the same package.
      */
-    public abstract void addNonHighRefreshRatePackage(@NonNull String packageName);
+    public abstract void addRefreshRateRangeForPackage(@NonNull String packageName,
+            float minRefreshRate, float maxRefreshRate);
 
     /**
      * Tell window manager to stop constraining refresh rate for the given package.
      */
-    public abstract void removeNonHighRefreshRatePackage(@NonNull String packageName);
+    public abstract void removeRefreshRateRangeForPackage(@NonNull String packageName);
 
     /**
      * Checks if the device supports touch or faketouch.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 555128b..d5f7a22 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -141,6 +141,7 @@
 import static com.android.server.wm.WindowManagerServiceDumpProto.INPUT_METHOD_WINDOW;
 import static com.android.server.wm.WindowManagerServiceDumpProto.POLICY;
 import static com.android.server.wm.WindowManagerServiceDumpProto.ROOT_WINDOW_CONTAINER;
+import static com.android.server.wm.WindowManagerServiceDumpProto.WINDOW_FRAMES_VALID;
 
 import android.Manifest;
 import android.Manifest.permission;
@@ -191,6 +192,7 @@
 import android.os.HandlerExecutor;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
+import android.os.InputConfig;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
@@ -404,7 +406,7 @@
     /**
      * Use WMShell for app transition.
      */
-    public static final String ENABLE_SHELL_TRANSITIONS = "persist.debug.shell_transit";
+    public static final String ENABLE_SHELL_TRANSITIONS = "persist.wm.debug.shell_transit";
 
     /**
      * @see #ENABLE_SHELL_TRANSITIONS
@@ -743,6 +745,9 @@
 
     private final DisplayHashController mDisplayHashController;
 
+    volatile float mMaximumObscuringOpacityForTouch =
+            InputManager.DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH;
+
     @VisibleForTesting
     final WindowContextListenerController mWindowContextListenerController =
             new WindowContextListenerController();
@@ -780,6 +785,8 @@
                 DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR);
         private final Uri mDisplaySettingsPathUri = Settings.Global.getUriFor(
                 DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH);
+        private final Uri mMaximumObscuringOpacityForTouchUri = Settings.Global.getUriFor(
+                Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH);
 
         public SettingsObserver() {
             super(new Handler());
@@ -804,6 +811,8 @@
                     UserHandle.USER_ALL);
             resolver.registerContentObserver(mDisplaySettingsPathUri, false, this,
                     UserHandle.USER_ALL);
+            resolver.registerContentObserver(mMaximumObscuringOpacityForTouchUri, false, this,
+                    UserHandle.USER_ALL);
         }
 
         @Override
@@ -847,6 +856,11 @@
                 return;
             }
 
+            if (mMaximumObscuringOpacityForTouchUri.equals(uri)) {
+                updateMaximumObscuringOpacityForTouch();
+                return;
+            }
+
             @UpdateAnimationScaleMode
             final int mode;
             if (mWindowAnimationScaleUri.equals(uri)) {
@@ -866,6 +880,14 @@
         void loadSettings() {
             updateSystemUiSettings(false /* handleChange */);
             updatePointerLocation();
+            updateMaximumObscuringOpacityForTouch();
+        }
+
+        void updateMaximumObscuringOpacityForTouch() {
+            ContentResolver resolver = mContext.getContentResolver();
+            mMaximumObscuringOpacityForTouch = Settings.Global.getFloat(resolver,
+                    Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH,
+                    InputManager.DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH);
         }
 
         void updateSystemUiSettings(boolean handleChange) {
@@ -2190,7 +2212,7 @@
             int requestedWidth, int requestedHeight, int viewVisibility, int flags,
             ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
             SurfaceControl outSurfaceControl, InsetsState outInsetsState,
-            InsetsSourceControl[] outActiveControls) {
+            InsetsSourceControl[] outActiveControls, Bundle outSyncIdBundle) {
         Arrays.fill(outActiveControls, null);
         int result = 0;
         boolean configChanged;
@@ -2615,7 +2637,7 @@
     }
 
     void finishDrawingWindow(Session session, IWindow client,
-            @Nullable SurfaceControl.Transaction postDrawTransaction) {
+            @Nullable SurfaceControl.Transaction postDrawTransaction, int seqId) {
         if (postDrawTransaction != null) {
             postDrawTransaction.sanitize();
         }
@@ -2626,7 +2648,7 @@
                 WindowState win = windowForClientLocked(session, client, false);
                 ProtoLog.d(WM_DEBUG_ADD_REMOVE, "finishDrawingWindow: %s mDrawState=%s",
                         win, (win != null ? win.mWinAnimator.drawStateToString() : "null"));
-                if (win != null && win.finishDrawing(postDrawTransaction)) {
+                if (win != null && win.finishDrawing(postDrawTransaction, seqId)) {
                     if (win.hasWallpaper()) {
                         win.getDisplayContent().pendingLayoutChanges |=
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -3231,8 +3253,8 @@
         if (!checkCallingPermission(permission.CONTROL_KEYGUARD, "dismissKeyguard")) {
             throw new SecurityException("Requires CONTROL_KEYGUARD permission");
         }
-        if (mAtmService.isDreaming()) {
-            mAtmService.mTaskSupervisor.wakeUp("dismissKeyguard");
+        if (mAtmService.mKeyguardController.isShowingDream()) {
+            mAtmService.mTaskSupervisor.wakeUp("leaveDream");
         }
         synchronized (mGlobalLock) {
             mPolicy.dismissKeyguardLw(callback, message);
@@ -6437,9 +6459,13 @@
             imeWindow.writeIdentifierToProto(proto, INPUT_METHOD_WINDOW);
         }
         proto.write(DISPLAY_FROZEN, mDisplayFrozen);
-        final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
         proto.write(FOCUSED_DISPLAY_ID, topFocusedDisplayContent.getDisplayId());
         proto.write(HARD_KEYBOARD_AVAILABLE, mHardKeyboardAvailable);
+
+        // This is always true for now since we still update the window frames at the server side.
+        // Once we move the window layout to the client side, this can be false when we are waiting
+        // for the frames.
+        proto.write(WINDOW_FRAMES_VALID, true);
     }
 
     private void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
@@ -7963,18 +7989,20 @@
         }
 
         @Override
-        public void addNonHighRefreshRatePackage(@NonNull String packageName) {
+        public void addRefreshRateRangeForPackage(@NonNull String packageName,
+                float minRefreshRate, float maxRefreshRate) {
             synchronized (mGlobalLock) {
                 mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().getRefreshRatePolicy()
-                        .addNonHighRefreshRatePackage(packageName));
+                        .addRefreshRateRangeForPackage(
+                                packageName, minRefreshRate, maxRefreshRate));
             }
         }
 
         @Override
-        public void removeNonHighRefreshRatePackage(@NonNull String packageName) {
+        public void removeRefreshRateRangeForPackage(@NonNull String packageName) {
             synchronized (mGlobalLock) {
                 mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().getRefreshRatePolicy()
-                        .removeNonHighRefreshRatePackage(packageName));
+                        .removeRefreshRateRangeForPackage(packageName));
             }
         }
 
@@ -8447,43 +8475,48 @@
     }
 
     private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,
-                                    int displayId, SurfaceControl surface, String name,
-                                    InputApplicationHandle applicationHandle, int flags,
-                                    int privateFlags, int type, Region region, IWindow window) {
-        InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
+            int displayId, SurfaceControl surface, String name,
+            InputApplicationHandle applicationHandle, int flags,
+            int privateFlags, int type, Region region, IWindow window) {
+        final InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
         h.token = channelToken;
         h.setWindowToken(window);
         h.name = name;
 
         flags = sanitizeFlagSlippery(flags, name, callingUid, callingPid);
 
-        final int sanitizedFlags = flags & (FLAG_NOT_TOUCHABLE
-                | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE);
-        h.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | sanitizedFlags;
+        final int sanitizedLpFlags =
+                (flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE))
+                | LayoutParams.FLAG_NOT_TOUCH_MODAL;
         h.layoutParamsType = type;
-        h.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-        h.focusable = (flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0;
-        h.hasWallpaper = false;
-        h.paused = false;
-
-        h.ownerUid = callingUid;
-        h.ownerPid = callingPid;
+        h.layoutParamsFlags = sanitizedLpFlags;
 
         // Do not allow any input features to be set without sanitizing them first.
-        h.inputFeatures = 0;
+        h.inputConfig = InputConfigAdapter.getInputConfigFromWindowParams(
+                        type, sanitizedLpFlags, 0 /*inputFeatures*/);
 
-        if (region == null) {
-            h.replaceTouchableRegionWithCrop(null);
-        } else {
-            h.touchableRegion.set(region);
-            h.replaceTouchableRegionWithCrop = false;
-            h.setTouchableRegionCrop(surface);
+
+        if ((flags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
+            h.inputConfig |= InputConfig.NOT_FOCUSABLE;
         }
 
         //  Check private trusted overlay flag to set trustedOverlay field of input window handle.
-        h.trustedOverlay = (privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0;
+        if ((privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0) {
+            h.inputConfig |= InputConfig.TRUSTED_OVERLAY;
+        }
 
-        SurfaceControl.Transaction t = mTransactionFactory.get();
+        h.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
+        h.ownerUid = callingUid;
+        h.ownerPid = callingPid;
+
+        if (region == null) {
+            h.replaceTouchableRegionWithCrop = true;
+        } else {
+            h.touchableRegion.set(region);
+        }
+        h.setTouchableRegionCrop(null /* use the input surface's bounds */);
+
+        final SurfaceControl.Transaction t = mTransactionFactory.get();
         t.setInputWindowInfo(surface, h);
         t.apply();
         t.close();
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 1cf4c1b..5a2f28f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -566,9 +566,14 @@
         try (ZipOutputStream out = new ZipOutputStream(getRawOutputStream())) {
             ArrayList<Pair<String, ByteTransferPipe>> requestList = new ArrayList<>();
             synchronized (mInternal.mGlobalLock) {
+                final RecentTasks recentTasks = mInternal.mAtmService.getRecentTasks();
+                final int recentsComponentUid = recentTasks != null
+                        ? recentTasks.getRecentsComponentUid()
+                        : -1;
                 // Request dump from all windows parallelly before writing to disk.
                 mInternal.mRoot.forAllWindows(w -> {
-                    if (w.isVisible()) {
+                    final boolean isRecents = (w.getUid() == recentsComponentUid);
+                    if (w.isVisible() || isRecents) {
                         ByteTransferPipe pipe = null;
                         try {
                             pipe = new ByteTransferPipe();
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index ce27d73..d862012 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -701,6 +701,8 @@
                     sendTaskFragmentOperationFailure(tf.getTaskFragmentOrganizer(),
                             errorCallbackToken,
                             convertStartFailureToThrowable(result, activityIntent));
+                } else {
+                    effects |= TRANSACT_EFFECTS_LIFECYCLE;
                 }
                 break;
             }
@@ -1468,6 +1470,10 @@
         return mLaunchTaskFragments.get(tfToken);
     }
 
+    void cleanUpEmbeddedTaskFragment(TaskFragment taskFragment) {
+        mLaunchTaskFragments.remove(taskFragment.getFragmentToken());
+    }
+
     static class CallerInfo {
         final int mPid;
         final int mUid;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 8ee6feb..f667392 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1190,6 +1190,7 @@
                 mActivityRecord != null
                         ? mActivityRecord.getInputApplicationHandle(false /* update */) : null,
                 getDisplayId()));
+        mInputWindowHandle.setFocusable(false);
         mInputWindowHandle.setOwnerPid(s.mPid);
         mInputWindowHandle.setOwnerUid(s.mUid);
         mInputWindowHandle.setName(getName());
@@ -1392,13 +1393,13 @@
     }
 
     // TODO(b/161810301): Make the frame be passed from the client side.
-    void setFrame() {
-        // TODO(b/161810301): Set the window frame here. We don't have to do it now because
-        //                    DisplayPolicy has already done it for the window.
-
+    void setFrames(ClientWindowFrames clientWindowFrames) {
         mHaveFrame = true;
 
         final WindowFrames windowFrames = mWindowFrames;
+        windowFrames.mDisplayFrame.set(clientWindowFrames.displayFrame);
+        windowFrames.mParentFrame.set(clientWindowFrames.parentFrame);
+        windowFrames.mFrame.set(clientWindowFrames.frame);
 
         if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
             mLastRequestedWidth = mRequestedWidth;
@@ -3945,7 +3946,7 @@
 
         try {
             mClient.resized(mClientWindowFrames, reportDraw, mLastReportedConfiguration,
-                    forceRelayout, alwaysConsumeSystemBars, displayId);
+                forceRelayout, alwaysConsumeSystemBars, displayId, Integer.MAX_VALUE);
             if (drawPending && reportOrientation && mOrientationChanging) {
                 mOrientationChangeRedrawRequestTime = SystemClock.elapsedRealtime();
                 ProtoLog.v(WM_DEBUG_ORIENTATION,
@@ -5937,7 +5938,7 @@
         super.finishSync(outMergedTransaction, cancel);
     }
 
-    boolean finishDrawing(SurfaceControl.Transaction postDrawTransaction) {
+    boolean finishDrawing(SurfaceControl.Transaction postDrawTransaction, int syncSeqId) {
         if (mOrientationChangeRedrawRequestTime > 0) {
             final long duration =
                     SystemClock.elapsedRealtime() - mOrientationChangeRedrawRequestTime;
@@ -5984,18 +5985,9 @@
 
     void immediatelyNotifyBlastSync() {
         prepareDrawHandlers();
-        finishDrawing(null);
+        finishDrawing(null, Integer.MAX_VALUE);
         mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this);
         if (!useBLASTSync()) return;
-
-        final Task task = getTask();
-        if (task != null) {
-            final SurfaceControl.Transaction t = task.getMainWindowSizeChangeTransaction();
-            if (t != null) {
-                mSyncTransaction.merge(t);
-            }
-            task.setMainWindowSizeChangeTransaction(null);
-        }
     }
 
     @Override
@@ -6032,10 +6024,6 @@
         if (mRedrawForSyncReported) {
             return false;
         }
-        final Task task = getTask();
-        if (task != null && task.getMainWindowSizeChangeTransaction() != null) {
-            return true;
-        }
         return useBLASTSync();
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index c17961e..285a6d5 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -442,50 +442,6 @@
         return mService.useBLASTSync() && mWin.useBLASTSync();
     }
 
-    private boolean shouldConsumeMainWindowSizeTransaction() {
-        // We only consume the transaction when the client is calling relayout
-        // because this is the only time we know the frameNumber will be valid
-        // due to the client renderer being paused. Put otherwise, only when
-        // mInRelayout is true can we guarantee the next frame will contain
-        // the most recent configuration.
-        if (!mWin.mInRelayout) return false;
-        // Since we can only do this for one window, we focus on the main application window
-        if (mAttrType != TYPE_BASE_APPLICATION) return false;
-        final Task task = mWin.getTask();
-        if (task == null) return false;
-        if (task.getMainWindowSizeChangeTransaction() == null) return false;
-        // Likewise we only focus on the task root, since we can only use one window
-        if (!mWin.mActivityRecord.isRootOfTask()) return false;
-        return true;
-    }
-
-    void setSurfaceBoundariesLocked(SurfaceControl.Transaction t) {
-        if (mSurfaceController == null) {
-            return;
-        }
-
-        final WindowState w = mWin;
-        final Task task = w.getTask();
-        if (shouldConsumeMainWindowSizeTransaction()) {
-            if (isInBlastSync()) {
-                // If we're in a sync transaction, there's no need to call defer transaction.
-                // The sync transaction will contain the buffer so the bounds change transaction
-                // will only be applied with the buffer.
-                t.merge(task.getMainWindowSizeChangeTransaction());
-                task.setMainWindowSizeChangeTransaction(null);
-            } else {
-                mWin.applyWithNextDraw(finishedFrame -> {
-                      final SurfaceControl.Transaction sizeChangedTransaction =
-                          task.getMainWindowSizeChangeTransaction();
-                      if (sizeChangedTransaction != null) {
-                          finishedFrame.merge(sizeChangedTransaction);
-                          task.setMainWindowSizeChangeTransaction(null);
-                      }
-                });
-            }
-        }
-    }
-
     void prepareSurfaceLocked(SurfaceControl.Transaction t) {
         final WindowState w = mWin;
         if (!hasSurface()) {
@@ -501,8 +457,6 @@
 
         computeShownFrameLocked();
 
-        setSurfaceBoundariesLocked(t);
-
         if (w.isParentWindowHidden() || !w.isOnScreen()) {
             hide(t, "prepareSurfaceLocked");
             mWallpaperControllerLocked.hideWallpapers(w);
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 1c6a3b5..0cd9494 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -106,7 +106,6 @@
     register_android_server_HardwarePropertiesManagerService(env);
     register_android_server_storage_AppFuse(env);
     register_android_server_SyntheticPasswordManager(env);
-    register_android_graphics_GraphicsStatsService(env);
     register_android_hardware_display_DisplayViewport(env);
     register_android_server_am_CachedAppOptimizer(env);
     register_android_server_am_LowMemDetector(env);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
index 2090ab3..2f5ab0b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
@@ -307,8 +307,8 @@
     public boolean mAdminCanGrantSensorsPermissions;
     public boolean mPreferentialNetworkServiceEnabled =
             DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT;
-    public PreferentialNetworkServiceConfig mPreferentialNetworkServiceConfig =
-            PreferentialNetworkServiceConfig.DEFAULT;
+    public List<PreferentialNetworkServiceConfig> mPreferentialNetworkServiceConfigs =
+            List.of(PreferentialNetworkServiceConfig.DEFAULT);
 
     private static final boolean USB_DATA_SIGNALING_ENABLED_DEFAULT = true;
     boolean mUsbDataSignalingEnabled = USB_DATA_SIGNALING_ENABLED_DEFAULT;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 236f663..3d40f48 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -87,6 +87,7 @@
 import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_SET_ERROR_FAILURE_SETTING;
 import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_SET_NO_ERROR;
 import static android.app.admin.DevicePolicyManager.PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER;
+import static android.app.admin.DevicePolicyManager.STATE_USER_SETUP_FINALIZED;
 import static android.app.admin.DevicePolicyManager.STATE_USER_UNMANAGED;
 import static android.app.admin.DevicePolicyManager.STATUS_ACCOUNTS_NOT_EMPTY;
 import static android.app.admin.DevicePolicyManager.STATUS_CANNOT_ADD_MANAGED_PROFILE;
@@ -132,7 +133,6 @@
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
-import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
 import static android.provider.Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED;
@@ -140,6 +140,7 @@
 import static android.provider.Telephony.Carriers.DPC_URI;
 import static android.provider.Telephony.Carriers.ENFORCE_KEY;
 import static android.provider.Telephony.Carriers.ENFORCE_MANAGED_URI;
+import static android.provider.Telephony.Carriers.INVALID_APN_ID;
 import static android.security.keystore.AttestationUtils.USE_INDIVIDUAL_ATTESTATION;
 
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_ENTRY_POINT_ADB;
@@ -3356,14 +3357,14 @@
         updatePermissionPolicyCache(userId);
         updateAdminCanGrantSensorsPermissionCache(userId);
 
-        final PreferentialNetworkServiceConfig preferentialNetworkServiceConfig;
+        final List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs;
         synchronized (getLockObject()) {
             ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(userId);
-            preferentialNetworkServiceConfig = owner != null
-                    ? owner.mPreferentialNetworkServiceConfig
-                    : PreferentialNetworkServiceConfig.DEFAULT;
+            preferentialNetworkServiceConfigs = owner != null
+                    ? owner.mPreferentialNetworkServiceConfigs
+                    : List.of(PreferentialNetworkServiceConfig.DEFAULT);
         }
-        updateNetworkPreferenceForUser(userId, preferentialNetworkServiceConfig);
+        updateNetworkPreferenceForUser(userId, preferentialNetworkServiceConfigs);
 
         startOwnerService(userId, "start-user");
     }
@@ -3380,7 +3381,7 @@
 
     @Override
     void handleStopUser(int userId) {
-        updateNetworkPreferenceForUser(userId, PreferentialNetworkServiceConfig.DEFAULT);
+        updateNetworkPreferenceForUser(userId, List.of(PreferentialNetworkServiceConfig.DEFAULT));
         stopOwnerService(userId, "stop-user");
     }
 
@@ -9183,10 +9184,10 @@
     }
 
     @Override
-    public void setUserProvisioningState(int newState, int userHandle) {
+    public void setUserProvisioningState(int newState, int userId) {
         if (!mHasFeature) {
             logMissingFeatureAction("Cannot set provisioning state " + newState + " for user "
-                    + userHandle);
+                    + userId);
             return;
         }
 
@@ -9196,12 +9197,24 @@
         final CallerIdentity caller = getCallerIdentity();
         final long id = mInjector.binderClearCallingIdentity();
         try {
-            if (userHandle != mOwners.getDeviceOwnerUserId() && !mOwners.hasProfileOwner(userHandle)
-                    && getManagedUserId(userHandle) == -1
-                    && newState != STATE_USER_UNMANAGED) {
-                // No managed device, user or profile, so setting provisioning state makes no sense.
-                throw new IllegalStateException("Not allowed to change provisioning state unless a "
-                        + "device or profile owner is set.");
+            int deviceOwnerUserId = mOwners.getDeviceOwnerUserId();
+            // NOTE: multiple if statements are nested below so it can log more info on error
+            if (userId != deviceOwnerUserId) {
+                boolean hasProfileOwner = mOwners.hasProfileOwner(userId);
+                if (!hasProfileOwner) {
+                    int managedUserId = getManagedUserId(userId);
+                    if (managedUserId == -1 && newState != STATE_USER_UNMANAGED) {
+                        // No managed device, user or profile, so setting provisioning state makes
+                        // no sense.
+                        String error = "Not allowed to change provisioning state unless a "
+                                + "device or profile owner is set.";
+                        Slogf.w(LOG_TAG, "setUserProvisioningState(newState=%d, userId=%d) failed: "
+                                + "deviceOwnerId=%d, hasProfileOwner=%b, managedUserId=%d, err=%s",
+                                newState, userId, deviceOwnerUserId, hasProfileOwner,
+                                managedUserId, error);
+                        throw new IllegalStateException(error);
+                    }
+                }
             }
 
             synchronized (getLockObject()) {
@@ -9211,9 +9224,9 @@
                 if (isAdb(caller)) {
                     // ADB shell can only move directly from un-managed to finalized as part of
                     // directly setting profile-owner or device-owner.
-                    if (getUserProvisioningState(userHandle)
+                    if (getUserProvisioningState(userId)
                             != DevicePolicyManager.STATE_USER_UNMANAGED
-                            || newState != DevicePolicyManager.STATE_USER_SETUP_FINALIZED) {
+                            || newState != STATE_USER_SETUP_FINALIZED) {
                         throw new IllegalStateException("Not allowed to change provisioning state "
                                 + "unless current provisioning state is unmanaged, and new state"
                                 + "is finalized.");
@@ -9221,14 +9234,14 @@
                     transitionCheckNeeded = false;
                 }
 
-                final DevicePolicyData policyData = getUserData(userHandle);
+                final DevicePolicyData policyData = getUserData(userId);
                 if (transitionCheckNeeded) {
                     // Optional state transition check for non-ADB case.
                     checkUserProvisioningStateTransition(policyData.mUserProvisioningState,
                             newState);
                 }
                 policyData.mUserProvisioningState = newState;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(userId);
             }
         } finally {
             mInjector.binderRestoreCallingIdentity(id);
@@ -9247,7 +9260,7 @@
             case DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE:
             case DevicePolicyManager.STATE_USER_SETUP_COMPLETE:
                 // Can only move to finalized from these states.
-                if (newState == DevicePolicyManager.STATE_USER_SETUP_FINALIZED) {
+                if (newState == STATE_USER_SETUP_FINALIZED) {
                     return;
                 }
                 break;
@@ -9259,7 +9272,7 @@
                     return;
                 }
                 break;
-            case DevicePolicyManager.STATE_USER_SETUP_FINALIZED:
+            case STATE_USER_SETUP_FINALIZED:
                 // Cannot transition out of finalized.
                 break;
             case DevicePolicyManager.STATE_USER_PROFILE_FINALIZED:
@@ -12245,87 +12258,50 @@
     }
 
     @Override
-    public void setPreferentialNetworkServiceEnabled(boolean enabled) {
+    public void setPreferentialNetworkServiceConfigs(
+            List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs) {
         if (!mHasFeature) {
             return;
         }
         final CallerIdentity caller = getCallerIdentity();
-        Preconditions.checkCallAuthorization(isProfileOwner(caller),
-                "Caller is not profile owner;"
-                        + " only profile owner may control the preferential network service");
+        Preconditions.checkCallAuthorization(isProfileOwner(caller)
+                        || isDefaultDeviceOwner(caller),
+                "Caller is not profile owner or device owner;"
+                        + " only profile owner or device owner may control the preferential"
+                        + " network service");
         synchronized (getLockObject()) {
             final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(
                     caller.getUserId());
-            if (requiredAdmin != null
-                    && requiredAdmin.mPreferentialNetworkServiceEnabled != enabled) {
-                requiredAdmin.mPreferentialNetworkServiceEnabled = enabled;
+            if (!requiredAdmin.mPreferentialNetworkServiceConfigs.equals(
+                    preferentialNetworkServiceConfigs)) {
+                requiredAdmin.mPreferentialNetworkServiceConfigs =
+                        new ArrayList<>(preferentialNetworkServiceConfigs);
                 saveSettingsLocked(caller.getUserId());
             }
         }
-        updateNetworkPreferenceForUser(caller.getUserId(), enabled);
+        updateNetworkPreferenceForUser(caller.getUserId(), preferentialNetworkServiceConfigs);
         DevicePolicyEventLogger
                 .createEvent(DevicePolicyEnums.SET_PREFERENTIAL_NETWORK_SERVICE_ENABLED)
-                .setBoolean(enabled)
+                .setBoolean(preferentialNetworkServiceConfigs
+                        .stream().anyMatch(c -> c.isEnabled()))
                 .write();
     }
 
     @Override
-    public boolean isPreferentialNetworkServiceEnabled(int userHandle) {
+    public List<PreferentialNetworkServiceConfig> getPreferentialNetworkServiceConfigs() {
         if (!mHasFeature) {
-            return false;
+            return List.of(PreferentialNetworkServiceConfig.DEFAULT);
         }
 
         final CallerIdentity caller = getCallerIdentity();
-        Preconditions.checkCallAuthorization(isProfileOwner(caller),
-                "Caller is not profile owner");
-        synchronized (getLockObject()) {
-            final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(userHandle);
-            if (requiredAdmin != null) {
-                return requiredAdmin.mPreferentialNetworkServiceEnabled;
-            } else {
-                return false;
-            }
-        }
-    }
-
-    @Override
-    public void setPreferentialNetworkServiceConfig(
-            PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) {
-        if (!mHasFeature) {
-            return;
-        }
-        final CallerIdentity caller = getCallerIdentity();
-        Preconditions.checkCallAuthorization(isProfileOwner(caller),
-                "Caller is not profile owner;"
-                        + " only profile owner may control the preferential network service");
-        synchronized (getLockObject()) {
-            final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(
-                    caller.getUserId());
-            if (!requiredAdmin.mPreferentialNetworkServiceConfig.equals(
-                    preferentialNetworkServiceConfig)) {
-                requiredAdmin.mPreferentialNetworkServiceConfig = preferentialNetworkServiceConfig;
-                saveSettingsLocked(caller.getUserId());
-            }
-        }
-        updateNetworkPreferenceForUser(caller.getUserId(), preferentialNetworkServiceConfig);
-        DevicePolicyEventLogger
-                .createEvent(DevicePolicyEnums.SET_PREFERENTIAL_NETWORK_SERVICE_ENABLED)
-                .setBoolean(preferentialNetworkServiceConfig.isEnabled())
-                .write();
-    }
-
-    @Override
-    public PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig() {
-        if (!mHasFeature) {
-            return PreferentialNetworkServiceConfig.DEFAULT;
-        }
-
-        final CallerIdentity caller = getCallerIdentity();
-        Preconditions.checkCallAuthorization(isProfileOwner(caller),
-                "Caller is not profile owner");
+        Preconditions.checkCallAuthorization(isProfileOwner(caller)
+                        || isDefaultDeviceOwner(caller),
+                "Caller is not profile owner or device owner;"
+                        + " only profile owner or device owner may retrieve the preferential"
+                        + " network service configurations");
         synchronized (getLockObject()) {
             final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(caller.getUserId());
-            return requiredAdmin.mPreferentialNetworkServiceConfig;
+            return requiredAdmin.mPreferentialNetworkServiceConfigs;
         }
     }
 
@@ -16446,7 +16422,12 @@
         Objects.requireNonNull(who, "ComponentName is null");
         Objects.requireNonNull(apnSetting, "ApnSetting is null in addOverrideApn");
         final CallerIdentity caller = getCallerIdentity(who);
-        Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller));
+        if (apnSetting.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
+            Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller)
+                    || isProfileOwner(caller));
+        } else {
+            Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller));
+        }
 
         TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
         if (tm != null) {
@@ -16454,7 +16435,7 @@
                     () -> tm.addDevicePolicyOverrideApn(mContext, apnSetting));
         } else {
             Slogf.w(LOG_TAG, "TelephonyManager is null when trying to add override apn");
-            return Telephony.Carriers.INVALID_APN_ID;
+            return INVALID_APN_ID;
         }
     }
 
@@ -16467,7 +16448,14 @@
         Objects.requireNonNull(who, "ComponentName is null");
         Objects.requireNonNull(apnSetting, "ApnSetting is null in updateOverrideApn");
         final CallerIdentity caller = getCallerIdentity(who);
-        Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller));
+        ApnSetting apn = getApnSetting(apnId);
+        if (apn != null && apn.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE
+                && apnSetting.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
+            Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller)
+                    || isProfileOwner(caller));
+        } else {
+            Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller));
+        }
 
         if (apnId < 0) {
             return false;
@@ -16489,7 +16477,13 @@
         }
         Objects.requireNonNull(who, "ComponentName is null");
         final CallerIdentity caller = getCallerIdentity(who);
-        Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller));
+        ApnSetting apn = getApnSetting(apnId);
+        if (apn != null && apn.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
+            Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller)
+                    || isProfileOwner(caller));
+        } else {
+            Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller));
+        }
         return removeOverrideApnUnchecked(apnId);
     }
 
@@ -16503,6 +16497,27 @@
         return numDeleted > 0;
     }
 
+    private ApnSetting getApnSetting(int apnId) {
+        if (apnId < 0) {
+            return null;
+        }
+        ApnSetting apnSetting = null;
+        Cursor cursor = mInjector.binderWithCleanCallingIdentity(
+                () -> mContext.getContentResolver().query(
+                        Uri.withAppendedPath(DPC_URI, Integer.toString(apnId)), null, null, null,
+                        Telephony.Carriers.DEFAULT_SORT_ORDER));
+        if (cursor != null) {
+            while (cursor.moveToNext()) {
+                apnSetting = ApnSetting.makeApnSetting(cursor);
+                if (apnSetting != null) {
+                    break;
+                }
+            }
+            cursor.close();
+        }
+        return apnSetting;
+    }
+
     @Override
     public List<ApnSetting> getOverrideApns(@NonNull ComponentName who) {
         if (!mHasFeature || !mHasTelephonyFeature) {
@@ -18080,7 +18095,9 @@
 
         final CallerIdentity caller = getCallerIdentity();
         Preconditions.checkCallAuthorization(
-                hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+                hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
+                        || (hasCallingOrSelfPermission(permission.PROVISION_DEMO_DEVICE)
+                        && provisioningParams.isDemoDevice()));
 
         provisioningParams.logParams(callerPackage);
 
@@ -18117,8 +18134,9 @@
             }
 
             disallowAddUser();
-            setAdminCanGrantSensorsPermissionForUserUnchecked(deviceOwnerUserId,
-                    provisioningParams.canDeviceOwnerGrantSensorsPermissions());
+            setAdminCanGrantSensorsPermissionForUserUnchecked(
+                    deviceOwnerUserId, provisioningParams.canDeviceOwnerGrantSensorsPermissions());
+            setDemoDeviceStateUnchecked(deviceOwnerUserId, provisioningParams.isDemoDevice());
             onProvisionFullyManagedDeviceCompleted(provisioningParams);
             sendProvisioningCompletedBroadcast(
                     deviceOwnerUserId,
@@ -18317,6 +18335,19 @@
         }
     }
 
+    private void setDemoDeviceStateUnchecked(@UserIdInt int userId, boolean isDemoDevice) {
+        Slogf.d(LOG_TAG, "setDemoDeviceStateUnchecked(%d, %b)",
+                userId, isDemoDevice);
+        if (!isDemoDevice) {
+            return;
+        }
+        synchronized (getLockObject()) {
+            mInjector.settingsGlobalPutStringForUser(
+                    Settings.Global.DEVICE_DEMO_MODE, Integer.toString(/* value= */ 1), userId);
+        }
+        setUserProvisioningState(STATE_USER_SETUP_FINALIZED, userId);
+    }
+
     private void updateAdminCanGrantSensorsPermissionCache(@UserIdInt int userId) {
         synchronized (getLockObject()) {
 
@@ -18334,54 +18365,38 @@
     }
 
     private void updateNetworkPreferenceForUser(int userId,
-            boolean preferentialNetworkServiceEnabled) {
+            List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs) {
         if (!isManagedProfile(userId)) {
             return;
         }
-        ProfileNetworkPreference.Builder preferenceBuilder =
-                new ProfileNetworkPreference.Builder();
-        if (preferentialNetworkServiceEnabled) {
-            preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
-            preferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
-        } else {
-            preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT);
-        }
         List<ProfileNetworkPreference> preferences = new ArrayList<>();
-        preferences.add(preferenceBuilder.build());
-        mInjector.binderWithCleanCallingIdentity(() ->
-                mInjector.getConnectivityManager().setProfileNetworkPreferences(
-                        UserHandle.of(userId), preferences,
-                        null /* executor */, null /* listener */));
-    }
-
-    private void updateNetworkPreferenceForUser(int userId,
-            PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) {
-        if (!isManagedProfile(userId)) {
-            return;
-        }
-        ProfileNetworkPreference.Builder preferenceBuilder =
-                new ProfileNetworkPreference.Builder();
-        if (preferentialNetworkServiceConfig.isEnabled()) {
-            if (preferentialNetworkServiceConfig.isFallbackToDefaultConnectionAllowed()) {
-                preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+        for (PreferentialNetworkServiceConfig preferentialNetworkServiceConfig :
+                preferentialNetworkServiceConfigs) {
+            ProfileNetworkPreference.Builder preferenceBuilder =
+                    new ProfileNetworkPreference.Builder();
+            if (preferentialNetworkServiceConfig.isEnabled()) {
+                if (preferentialNetworkServiceConfig.isFallbackToDefaultConnectionAllowed()) {
+                    preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+                } else {
+                    preferenceBuilder.setPreference(
+                            PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
+                }
             } else {
-                preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
+                preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT);
             }
-        } else {
-            preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT);
+            List<Integer> allowedUids = Arrays.stream(
+                    preferentialNetworkServiceConfig.getIncludedUids()).boxed().collect(
+                    Collectors.toList());
+            List<Integer> excludedUids = Arrays.stream(
+                    preferentialNetworkServiceConfig.getExcludedUids()).boxed().collect(
+                    Collectors.toList());
+            preferenceBuilder.setIncludedUids(allowedUids);
+            preferenceBuilder.setExcludedUids(excludedUids);
+            preferenceBuilder.setPreferenceEnterpriseId(
+                    preferentialNetworkServiceConfig.getNetworkId());
+
+            preferences.add(preferenceBuilder.build());
         }
-        List<Integer> allowedUids = Arrays.stream(
-                preferentialNetworkServiceConfig.getIncludedUids()).boxed().collect(
-                        Collectors.toList());
-        List<Integer> excludedUids = Arrays.stream(
-                preferentialNetworkServiceConfig.getExcludedUids()).boxed().collect(
-                Collectors.toList());
-        preferenceBuilder.setIncludedUids(allowedUids);
-        preferenceBuilder.setExcludedUids(excludedUids);
-        preferenceBuilder.setPreferenceEnterpriseId(
-                preferentialNetworkServiceConfig.getNetworkId());
-        List<ProfileNetworkPreference> preferences = new ArrayList<>();
-        preferences.add(preferenceBuilder.build());
         mInjector.binderWithCleanCallingIdentity(() ->
                 mInjector.getConnectivityManager().setProfileNetworkPreferences(
                         UserHandle.of(userId), preferences,
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 294dc89..f7c66c5 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -41,6 +41,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.IPackageManager;
 import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
@@ -292,8 +293,6 @@
             "com.android.server.wifi.p2p.WifiP2pService";
     private static final String LOWPAN_SERVICE_CLASS =
             "com.android.server.lowpan.LowpanService";
-    private static final String ETHERNET_SERVICE_CLASS =
-            "com.android.server.ethernet.EthernetService";
     private static final String JOB_SCHEDULER_SERVICE_CLASS =
             "com.android.server.job.JobSchedulerService";
     private static final String LOCK_SETTINGS_SERVICE_CLASS =
@@ -422,6 +421,8 @@
 
     private static final String SDK_SANDBOX_MANAGER_SERVICE_CLASS =
             "com.android.server.sdksandbox.SdkSandboxManagerService$Lifecycle";
+    private static final String AD_SERVICES_MANAGER_SERVICE_CLASS =
+            "com.android.server.adservices.AdServicesManagerService$Lifecycle";
 
     private static final String TETHERING_CONNECTOR_CLASS = "android.net.ITetheringConnector";
 
@@ -1225,12 +1226,15 @@
         mSystemServiceManager.startService(domainVerificationService);
         t.traceEnd();
 
+        IPackageManager iPackageManager;
         t.traceBegin("StartPackageManagerService");
         try {
             Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
-            mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
-                    domainVerificationService, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF,
-                    mOnlyCore);
+            Pair<PackageManagerService, IPackageManager> pmsPair = PackageManagerService.main(
+                    mSystemContext, installer, domainVerificationService,
+                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
+            mPackageManagerService = pmsPair.first;
+            iPackageManager = pmsPair.second;
         } finally {
             Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
         }
@@ -1238,7 +1242,7 @@
         // Now that the package manager has started, register the dex load reporter to capture any
         // dex files loaded by system server.
         // These dex files will be optimized by the BackgroundDexOptService.
-        SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService);
+        SystemServerDexLoadReporter.configureSystemServerDexReporter(iPackageManager);
 
         mFirstBoot = mPackageManagerService.isFirstBoot();
         mPackageManager = mSystemContext.getPackageManager();
@@ -1989,13 +1993,6 @@
                 t.traceEnd();
             }
 
-            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
-                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
-                t.traceBegin("StartEthernet");
-                mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
-                t.traceEnd();
-            }
-
             t.traceBegin("StartPacProxyService");
             try {
                 pacProxyService = new PacProxyService(context);
@@ -2604,6 +2601,11 @@
         mSystemServiceManager.startService(SDK_SANDBOX_MANAGER_SERVICE_CLASS);
         t.traceEnd();
 
+        // AdServicesManagerService (PP API service)
+        t.traceBegin("StartAdServicesManagerService");
+        mSystemServiceManager.startService(AD_SERVICES_MANAGER_SERVICE_CLASS);
+        t.traceEnd();
+
         if (safeMode) {
             mActivityManagerService.enterSafeMode();
         }
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index c5f990d..66e840b 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -112,7 +112,7 @@
         try {
             mIProfcollect.registerProviderStatusCallback(mProviderStatusCallback);
         } catch (RemoteException e) {
-            Log.e(LOG_TAG, e.getMessage());
+            Log.e(LOG_TAG, "Failed to register provider status callback: " + e.getMessage());
         }
     }
 
@@ -123,7 +123,7 @@
         try {
             return !mIProfcollect.get_supported_provider().isEmpty();
         } catch (RemoteException e) {
-            Log.e(LOG_TAG, e.getMessage());
+            Log.e(LOG_TAG, "Failed to get supported provider: " + e.getMessage());
             return false;
         }
     }
@@ -219,7 +219,8 @@
                         try {
                             sSelfService.mIProfcollect.process();
                         } catch (RemoteException e) {
-                            Log.e(LOG_TAG, e.getMessage());
+                            Log.e(LOG_TAG, "Failed to process profiles in background: "
+                                    + e.getMessage());
                         }
                     });
             return true;
@@ -234,8 +235,11 @@
 
     // Event observers
     private void registerObservers() {
-        registerAppLaunchObserver();
-        registerOTAObserver();
+        BackgroundThread.get().getThreadHandler().post(
+                () -> {
+                    registerAppLaunchObserver();
+                    registerOTAObserver();
+                });
     }
 
     private final AppLaunchObserver mAppLaunchObserver = new AppLaunchObserver();
@@ -264,7 +268,7 @@
                 try {
                     mIProfcollect.trace_once("applaunch");
                 } catch (RemoteException e) {
-                    Log.e(LOG_TAG, e.getMessage());
+                    Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage());
                 }
             });
         }
@@ -348,7 +352,7 @@
                         .putExtra("filename", reportName);
                 context.sendBroadcast(intent);
             } catch (RemoteException e) {
-                Log.e(LOG_TAG, e.getMessage());
+                Log.e(LOG_TAG, "Failed to upload report: " + e.getMessage());
             }
         });
     }
diff --git a/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java b/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java
index b7f8c00..8a9845b 100644
--- a/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java
@@ -16,6 +16,10 @@
 
 package com.android.server.backup;
 
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+
 import static com.android.server.backup.testing.TransportData.genericTransport;
 import static com.android.server.backup.testing.TransportTestUtils.mockTransport;
 import static com.android.server.backup.testing.TransportTestUtils.setUpTransportsForTransportManager;
@@ -312,6 +316,86 @@
     }
 
     @Test
+    public void testOnPackageChanged_whenPackageChanged_packageDisabledUnregistersTransport()
+            throws Exception {
+        TransportManager transportManager =
+                createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1);
+        reset(mListener);
+
+        mContext.getPackageManager()
+                .setApplicationEnabledSetting(
+                        PACKAGE_A,
+                        Integer.valueOf(COMPONENT_ENABLED_STATE_DISABLED),
+                        0 /*flags*/);
+        transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A);
+
+        assertRegisteredTransports(transportManager, singletonList(mTransportB1));
+        verify(mListener, never()).onTransportRegistered(any(), any());
+    }
+
+    @Test
+    public void testOnPackageChanged_whenPackageChanged_packageEnabledRegistersTransport()
+            throws Exception {
+        TransportManager transportManager =
+                createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1);
+        reset(mListener);
+
+        mContext.getPackageManager()
+                .setApplicationEnabledSetting(
+                        PACKAGE_A,
+                        Integer.valueOf(COMPONENT_ENABLED_STATE_DISABLED),
+                        0 /*flags*/);
+        transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A);
+
+        assertRegisteredTransports(transportManager, singletonList(mTransportB1));
+        verify(mListener, never()).onTransportRegistered(any(), any());
+
+        mContext.getPackageManager()
+                .setApplicationEnabledSetting(
+                        PACKAGE_A,
+                        Integer.valueOf(COMPONENT_ENABLED_STATE_ENABLED),
+                        0 /*flags*/);
+        transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A);
+
+        assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1));
+        verify(mListener)
+                .onTransportRegistered(mTransportA1.transportName, mTransportA1.transportDirName);
+    }
+
+    @Test
+    public void testOnPackageChanged_whenPackageChanged_unknownComponentStateIsIgnored()
+            throws Exception {
+        TransportManager transportManager =
+                createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1);
+        reset(mListener);
+
+        mContext.getPackageManager()
+                .setApplicationEnabledSetting(
+                        PACKAGE_A,
+                        Integer.valueOf(COMPONENT_ENABLED_STATE_DEFAULT),
+                        0 /*flags*/);
+        transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A);
+
+        assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1));
+        verify(mListener, never()).onTransportRegistered(any(), any());
+    }
+
+    @Test
+    public void testOnPackageChanged_whenPackageChanged_unknownPackageExceptionIsIgnored()
+            throws Exception {
+        TransportManager transportManager =
+                createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1);
+        reset(mListener);
+
+        // empty packageName triggers Robolectric ApplicationPackageManager to throw
+        // exception as if package does not exist.
+        transportManager.onPackageChanged("", "");
+
+        assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1));
+        verify(mListener, never()).onTransportRegistered(any(), any());
+    }
+
+    @Test
     public void testRegisterAndSelectTransport_whenTransportRegistered() throws Exception {
         TransportManager transportManager =
                 createTransportManagerWithRegisteredTransports(null, mTransportA1);
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
index aea36e5..4a99486 100644
--- a/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
@@ -16,6 +16,7 @@
 
 package com.android.server.testing.shadows;
 
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
 import static android.content.pm.PackageManager.NameNotFoundException;
 
 import android.app.ApplicationPackageManager;
@@ -44,6 +45,7 @@
     private static final List<PackageInfo> sInstalledPackages = new ArrayList<>();
     private static final Map<String, Integer> sPackageUids = new ArrayMap<>();
     private static final Map<Integer, Map<String, Integer>> sUserPackageUids = new ArrayMap<>();
+    private static final Map<String, Integer> sPackageAppEnabledStates = new ArrayMap<>();
 
     /**
      * Registers the package {@code packageName} to be returned when invoking {@link
@@ -53,6 +55,7 @@
     public static void addInstalledPackage(String packageName, PackageInfo packageInfo) {
         sPackageInfos.put(packageName, packageInfo);
         sInstalledPackages.add(packageInfo);
+        sPackageAppEnabledStates.put(packageName, Integer.valueOf(COMPONENT_ENABLED_STATE_DEFAULT));
     }
 
     /**
@@ -77,6 +80,22 @@
     }
 
     @Override
+    protected int getApplicationEnabledSetting(String packageName) {
+        if (packageName.isEmpty()) {
+            throw new IllegalArgumentException("Robo: Package '' does not exist.");
+        }
+        if (!sPackageAppEnabledStates.containsKey(packageName)) {
+            return COMPONENT_ENABLED_STATE_DEFAULT;
+        }
+        return sPackageAppEnabledStates.get(packageName);
+    }
+
+    @Override
+    protected void setApplicationEnabledSetting(String packageName, int newState, int flags) {
+        sPackageAppEnabledStates.put(packageName, Integer.valueOf(newState));  // flags unused here.
+    }
+
+    @Override
     protected PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
             throws NameNotFoundException {
         if (!sPackageInfos.containsKey(packageName)) {
@@ -115,6 +134,7 @@
     public static void reset() {
         sPackageInfos.clear();
         sInstalledPackages.clear();
+        sPackageAppEnabledStates.clear();
         org.robolectric.shadows.ShadowApplicationPackageManager.reset();
     }
 }
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 dcc461b..7017440 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
@@ -221,11 +221,14 @@
     @After
     fun verifyExpectedResult() {
         assertServiceInitialized() ?: return
-        if (params.componentName != null) {
-            val activityInfo = service.getActivityInfo(params.componentName, 0, userId)
-            if (activityInfo != null) {
-                assertThat(activityInfo.nonLocalizedLabel).isEqualTo(params.expectedLabel)
-                assertThat(activityInfo.icon).isEqualTo(params.expectedIcon)
+        if (params.componentName != null && params.result !is Result.Exception) {
+            // Suppress so that failures in @After don't override the actual test failure
+            @Suppress("UNNECESSARY_SAFE_CALL")
+            service?.let {
+                val activityInfo = it.snapshotComputer()
+                    .getActivityInfo(params.componentName, 0, userId)
+                assertThat(activityInfo?.nonLocalizedLabel).isEqualTo(params.expectedLabel)
+                assertThat(activityInfo?.icon).isEqualTo(params.expectedIcon)
             }
         }
     }
@@ -237,9 +240,12 @@
             Result.Changed, Result.ChangedWithoutNotify -> {
                 // Suppress so that failures in @After don't override the actual test failure
                 @Suppress("UNNECESSARY_SAFE_CALL")
-                val activityInfo = service?.getActivityInfo(params.componentName, 0, userIdDifferent)
-                assertThat(activityInfo?.nonLocalizedLabel).isEqualTo(DEFAULT_LABEL)
-                assertThat(activityInfo?.icon).isEqualTo(DEFAULT_ICON)
+                service?.let {
+                    val activityInfo = it.snapshotComputer()
+                        ?.getActivityInfo(params.componentName, 0, userIdDifferent)
+                    assertThat(activityInfo?.nonLocalizedLabel).isEqualTo(DEFAULT_LABEL)
+                    assertThat(activityInfo?.icon).isEqualTo(DEFAULT_ICON)
+                }
             }
             Result.NotChanged, is Result.Exception -> {}
         }.run { /*exhaust*/ }
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
index 83ccabf..8f81e93 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
@@ -505,11 +505,6 @@
                 )
             }
         ),
-        getSetByValue(
-            AndroidPackage::shouldInheritKeyStoreKeys,
-            ParsingPackage::setInheritKeyStoreKeys,
-            true
-        ),
         getter(AndroidPackage::getKnownActivityEmbeddingCerts, setOf("TESTEMBEDDINGCERT")),
         getSetByValue(
             AndroidPackage::isOnBackInvokedCallbackEnabled,
diff --git a/services/tests/mockingservicestests/src/android/service/games/GameSessionTest.java b/services/tests/mockingservicestests/src/android/service/games/GameSessionTest.java
index e89c812..4fe9cd3 100644
--- a/services/tests/mockingservicestests/src/android/service/games/GameSessionTest.java
+++ b/services/tests/mockingservicestests/src/android/service/games/GameSessionTest.java
@@ -28,7 +28,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 
-import android.graphics.Bitmap;
 import android.platform.test.annotations.Presubmit;
 import android.service.games.GameSession.ScreenshotCallback;
 import android.testing.AndroidTestingRunner;
@@ -61,7 +60,6 @@
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 public final class GameSessionTest {
     private static final long WAIT_FOR_CALLBACK_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(1);
-    private static final Bitmap TEST_BITMAP = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
 
     @Mock
     private IGameSessionController mMockGameSessionController;
@@ -101,7 +99,7 @@
                         }
 
                         @Override
-                        public void onSuccess(Bitmap bitmap) {
+                        public void onSuccess() {
                             fail();
                         }
                     });
@@ -131,7 +129,7 @@
                     }
 
                     @Override
-                    public void onSuccess(Bitmap bitmap) {
+                    public void onSuccess() {
                         fail();
                     }
                 });
@@ -160,7 +158,7 @@
                     }
 
                     @Override
-                    public void onSuccess(Bitmap bitmap) {
+                    public void onSuccess() {
                         fail();
                     }
                 });
@@ -170,10 +168,10 @@
     }
 
     @Test
-    public void takeScreenshot_gameManagerSuccess_returnsBitmap() throws Exception {
+    public void takeScreenshot_gameManagerSuccess() throws Exception {
         doAnswer(invocation -> {
             AndroidFuture result = invocation.getArgument(1);
-            result.complete(GameScreenshotResult.createSuccessResult(TEST_BITMAP));
+            result.complete(GameScreenshotResult.createSuccessResult());
             return null;
         }).when(mMockGameSessionController).takeScreenshot(anyInt(), any());
 
@@ -187,8 +185,7 @@
                     }
 
                     @Override
-                    public void onSuccess(Bitmap bitmap) {
-                        assertEquals(TEST_BITMAP, bitmap);
+                    public void onSuccess() {
                         countDownLatch.countDown();
                     }
                 });
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index f05658b..e096687 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -494,9 +494,9 @@
 
         final ArgumentCaptor<AlarmManagerService.UninstallReceiver> packageReceiverCaptor =
                 ArgumentCaptor.forClass(AlarmManagerService.UninstallReceiver.class);
-        verify(mMockContext).registerReceiver(packageReceiverCaptor.capture(),
+        verify(mMockContext).registerReceiverForAllUsers(packageReceiverCaptor.capture(),
                 argThat((filter) -> filter.hasAction(Intent.ACTION_PACKAGE_ADDED)
-                        && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)));
+                        && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)), isNull(), isNull());
         mPackageChangesReceiver = packageReceiverCaptor.getValue();
 
         assertEquals(mService.mExactAlarmCandidates, Collections.emptySet());
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 32a31d0..319a769 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
@@ -19,6 +19,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMoreInteractions;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 import static com.android.server.app.GameServiceProviderInstanceImplTest.FakeGameService.GameServiceState;
 
@@ -26,19 +27,21 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verifyZeroInteractions;
 
 import android.Manifest;
 import android.annotation.Nullable;
 import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityManagerInternal;
 import android.app.ActivityTaskManager;
 import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
+import android.app.IProcessObserver;
 import android.app.ITaskStackListener;
 import android.content.ComponentName;
 import android.content.Context;
@@ -46,7 +49,12 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Picture;
 import android.graphics.Rect;
+import android.net.Uri;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
@@ -71,6 +79,7 @@
 import com.android.internal.util.ConcurrentUtils;
 import com.android.internal.util.FunctionalUtils.ThrowingConsumer;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.ScreenshotHelper;
 import com.android.server.wm.WindowManagerInternal;
 import com.android.server.wm.WindowManagerInternal.TaskSystemBarsListener;
 import com.android.server.wm.WindowManagerService;
@@ -87,6 +96,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Objects;
+import java.util.function.Consumer;
 
 
 /**
@@ -114,11 +124,22 @@
             new ComponentName(GAME_B_PACKAGE, "com.package.game.b.MainActivity");
 
 
-    private static final Bitmap TEST_BITMAP = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888);
+    private static final Bitmap TEST_BITMAP;
+    static {
+        Picture picture = new Picture();
+        Canvas canvas = picture.beginRecording(200, 100);
+        Paint p = new Paint();
+        p.setColor(Color.BLACK);
+        canvas.drawCircle(10, 10, 10, p);
+        picture.endRecording();
+        TEST_BITMAP = Bitmap.createBitmap(picture);
+    }
 
     private MockitoSession mMockingSession;
     private GameServiceProviderInstance mGameServiceProviderInstance;
     @Mock
+    private ActivityManagerInternal mMockActivityManagerInternal;
+    @Mock
     private IActivityTaskManager mMockActivityTaskManager;
     @Mock
     private WindowManagerService mMockWindowManagerService;
@@ -126,6 +147,8 @@
     private WindowManagerInternal mMockWindowManagerInternal;
     @Mock
     private IActivityManager mMockActivityManager;
+    @Mock
+    private ScreenshotHelper mMockScreenshotHelper;
     private MockContext mMockContext;
     private FakeGameClassifier mFakeGameClassifier;
     private FakeGameService mFakeGameService;
@@ -133,6 +156,7 @@
     private FakeGameSessionService mFakeGameSessionService;
     private FakeServiceConnector<IGameSessionService> mFakeGameSessionServiceConnector;
     private ArrayList<ITaskStackListener> mTaskStackListeners;
+    private ArrayList<IProcessObserver> mProcessObservers;
     private ArrayList<TaskSystemBarsListener> mTaskSystemBarsListeners;
     private ArrayList<RunningTaskInfo> mRunningTaskInfos;
 
@@ -167,6 +191,16 @@
             return null;
         }).when(mMockActivityTaskManager).unregisterTaskStackListener(any());
 
+        mProcessObservers = new ArrayList<>();
+        doAnswer(invocation -> {
+            mProcessObservers.add(invocation.getArgument(0));
+            return null;
+        }).when(mMockActivityManager).registerProcessObserver(any());
+        doAnswer(invocation -> {
+            mProcessObservers.remove(invocation.getArgument(0));
+            return null;
+        }).when(mMockActivityManager).unregisterProcessObserver(any());
+
         mTaskSystemBarsListeners = new ArrayList<>();
         doAnswer(invocation -> {
             mTaskSystemBarsListeners.add(invocation.getArgument(0));
@@ -188,11 +222,13 @@
                 mMockContext,
                 mFakeGameClassifier,
                 mMockActivityManager,
+                mMockActivityManagerInternal,
                 mMockActivityTaskManager,
                 mMockWindowManagerService,
                 mMockWindowManagerInternal,
                 mFakeGameServiceConnector,
-                mFakeGameSessionServiceConnector);
+                mFakeGameSessionServiceConnector,
+                mMockScreenshotHelper);
     }
 
     @After
@@ -410,6 +446,214 @@
     }
 
     @Test
+    public void gameProcessStopped_soleProcess_destroysGameSession() throws Exception {
+        int gameProcessId = 1000;
+
+        mGameServiceProviderInstance.start();
+
+        startTask(10, GAME_A_MAIN_ACTIVITY);
+        startProcessForPackage(gameProcessId, GAME_A_PACKAGE);
+
+        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));
+        assertThat(gameSession10.mIsDestroyed).isFalse();
+
+        // Death of the sole game process destroys the game session.
+        dispatchProcessDied(gameProcessId);
+        assertThat(gameSession10.mIsDestroyed).isTrue();
+    }
+
+    @Test
+    public void gameProcessStopped_soleProcess_destroysMultipleGameSessionsForSamePackage()
+            throws Exception {
+        int gameProcessId = 1000;
+
+        mGameServiceProviderInstance.start();
+
+        // Multiple tasks exist for the same package.
+        startTask(10, GAME_A_MAIN_ACTIVITY);
+        startTask(11, GAME_A_MAIN_ACTIVITY);
+        startProcessForPackage(gameProcessId, GAME_A_PACKAGE);
+
+        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
+        mFakeGameService.requestCreateGameSession(10);
+        mFakeGameService.requestCreateGameSession(11);
+
+        FakeGameSession gameSession10 = new FakeGameSession();
+        SurfacePackage mockSurfacePackage10 = Mockito.mock(SurfacePackage.class);
+        mFakeGameSessionService.removePendingFutureForTaskId(10)
+                .complete(new CreateGameSessionResult(gameSession10, mockSurfacePackage10));
+        FakeGameSession gameSession11 = new FakeGameSession();
+        SurfacePackage mockSurfacePackage11 = Mockito.mock(SurfacePackage.class);
+        mFakeGameSessionService.removePendingFutureForTaskId(11)
+                .complete(new CreateGameSessionResult(gameSession11, mockSurfacePackage11));
+
+        assertThat(gameSession10.mIsDestroyed).isFalse();
+        assertThat(gameSession11.mIsDestroyed).isFalse();
+
+        // Death of the sole game process destroys both game sessions.
+        dispatchProcessDied(gameProcessId);
+        assertThat(gameSession10.mIsDestroyed).isTrue();
+        assertThat(gameSession11.mIsDestroyed).isTrue();
+    }
+
+    @Test
+    public void gameProcessStopped_multipleProcesses_gameSessionDestroyedWhenAllDead()
+            throws Exception {
+        int firstGameProcessId = 1000;
+        int secondGameProcessId = 1001;
+
+        mGameServiceProviderInstance.start();
+
+        startTask(10, GAME_A_MAIN_ACTIVITY);
+        startProcessForPackage(firstGameProcessId, GAME_A_PACKAGE);
+        startProcessForPackage(secondGameProcessId, GAME_A_PACKAGE);
+
+        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));
+        assertThat(gameSession10.mIsDestroyed).isFalse();
+
+        // Death of the first process (with the second one still alive) does not destroy the game
+        // session.
+        dispatchProcessDied(firstGameProcessId);
+        assertThat(gameSession10.mIsDestroyed).isFalse();
+
+        // Death of the second process does destroy the game session.
+        dispatchProcessDied(secondGameProcessId);
+        assertThat(gameSession10.mIsDestroyed).isTrue();
+    }
+
+    @Test
+    public void gameProcessCreatedAfterInitialProcessDead_newGameSessionCreated() throws Exception {
+        int firstGameProcessId = 1000;
+        int secondGameProcessId = 1000;
+
+        mGameServiceProviderInstance.start();
+
+        startTask(10, GAME_A_MAIN_ACTIVITY);
+        startProcessForPackage(firstGameProcessId, GAME_A_PACKAGE);
+
+        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));
+        assertThat(gameSession10.mIsDestroyed).isFalse();
+
+        // After the first game process dies, the game session should be destroyed.
+        dispatchProcessDied(firstGameProcessId);
+        assertThat(gameSession10.mIsDestroyed).isTrue();
+
+        // However, when a new process for the game starts, a new game session should be created.
+        startProcessForPackage(secondGameProcessId, GAME_A_PACKAGE);
+        // Verify that a new pending game session is created for the game's taskId.
+        assertNotNull(mFakeGameSessionService.removePendingFutureForTaskId(10));
+    }
+
+    @Test
+    public void gameProcessCreatedAfterInitialProcessDead_multipleGameSessionsCreatedSamePackage()
+            throws Exception {
+        int firstGameProcessId = 1000;
+        int secondGameProcessId = 1000;
+
+        mGameServiceProviderInstance.start();
+
+        // Multiple tasks exist for the same package.
+        startTask(10, GAME_A_MAIN_ACTIVITY);
+        startTask(11, GAME_A_MAIN_ACTIVITY);
+        startProcessForPackage(firstGameProcessId, GAME_A_PACKAGE);
+
+        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
+
+        mFakeGameService.requestCreateGameSession(10);
+        mFakeGameService.requestCreateGameSession(11);
+
+        FakeGameSession gameSession10 = new FakeGameSession();
+        SurfacePackage mockSurfacePackage10 = Mockito.mock(SurfacePackage.class);
+        mFakeGameSessionService.removePendingFutureForTaskId(10)
+                .complete(new CreateGameSessionResult(gameSession10, mockSurfacePackage10));
+        FakeGameSession gameSession11 = new FakeGameSession();
+        SurfacePackage mockSurfacePackage11 = Mockito.mock(SurfacePackage.class);
+        mFakeGameSessionService.removePendingFutureForTaskId(11)
+                .complete(new CreateGameSessionResult(gameSession11, mockSurfacePackage11));
+
+        assertThat(gameSession10.mIsDestroyed).isFalse();
+        assertThat(gameSession11.mIsDestroyed).isFalse();
+
+        // After the first game process dies, both game sessions for the package should be
+        // destroyed.
+        dispatchProcessDied(firstGameProcessId);
+        assertThat(gameSession10.mIsDestroyed).isTrue();
+        assertThat(gameSession11.mIsDestroyed).isTrue();
+
+        // However, when a new process for the game starts, new game sessions for the same
+        // package should be created.
+        startProcessForPackage(secondGameProcessId, GAME_A_PACKAGE);
+        // Verify that new pending game sessions were created for each of the game's taskIds.
+        assertNotNull(mFakeGameSessionService.removePendingFutureForTaskId(10));
+        assertNotNull(mFakeGameSessionService.removePendingFutureForTaskId(11));
+    }
+
+    @Test
+    public void gameProcessStarted_gameSessionNotRequested_doesNothing() throws Exception {
+        int gameProcessId = 1000;
+
+        mGameServiceProviderInstance.start();
+
+        // A game task and process are started, but requestCreateGameSession is never called.
+        startTask(10, GAME_A_MAIN_ACTIVITY);
+        startProcessForPackage(gameProcessId, GAME_A_PACKAGE);
+
+        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
+
+        // No game session should be created.
+        assertThat(mFakeGameSessionService.getCapturedCreateInvocations()).isEmpty();
+    }
+
+    @Test
+    public void processActivityAndDeath_notForGame_gameSessionUnaffected() 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));
+
+        // Process activity for a process without a known package is ignored.
+        startProcessForPackage(1000, /*packageName=*/ null);
+        dispatchProcessActivity(1000);
+        dispatchProcessDied(1000);
+
+        // Process activity for a process with a different package is ignored
+        startProcessForPackage(1001, GAME_B_PACKAGE);
+        dispatchProcessActivity(1001);
+        dispatchProcessDied(1001);
+
+        // Death of a process for which there was no activity is ignored
+        dispatchProcessDied(1002);
+
+        // Despite all the process activity and death, the game session is not destroyed.
+        assertThat(gameSession10.mIsDestroyed).isFalse();
+    }
+
+    @Test
     public void taskSystemBarsListenerChanged_noAssociatedGameSession_doesNothing() {
         mGameServiceProviderInstance.start();
 
@@ -425,6 +669,7 @@
     public void systemBarsTransientShownDueToGesture_hasGameSession_propagatesToGameSession() {
         mGameServiceProviderInstance.start();
         startTask(10, GAME_A_MAIN_ACTIVITY);
+        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -446,6 +691,7 @@
     public void systemBarsTransientShownButNotGesture_hasGameSession_notPropagatedToGameSession() {
         mGameServiceProviderInstance.start();
         startTask(10, GAME_A_MAIN_ACTIVITY);
+        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -799,27 +1045,32 @@
         SurfaceControl mockOverlaySurfaceControl = Mockito.mock(SurfaceControl.class);
         SurfaceControl[] excludeLayers = new SurfaceControl[1];
         excludeLayers[0] = mockOverlaySurfaceControl;
+        int taskId = 10;
         when(mMockWindowManagerService.captureTaskBitmap(eq(10), any())).thenReturn(TEST_BITMAP);
-
+        doAnswer(invocation -> {
+            Consumer<Uri> consumer = invocation.getArgument(invocation.getArguments().length - 1);
+            consumer.accept(Uri.parse("a/b.png"));
+            return null;
+        }).when(mMockScreenshotHelper).provideScreenshot(
+                any(), any(), any(), anyInt(), anyInt(), any(), anyInt(), any(), any());
         mGameServiceProviderInstance.start();
-        startTask(10, GAME_A_MAIN_ACTIVITY);
+        startTask(taskId, GAME_A_MAIN_ACTIVITY);
         mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
-        mFakeGameService.requestCreateGameSession(10);
+        mFakeGameService.requestCreateGameSession(taskId);
 
         FakeGameSession gameSession10 = new FakeGameSession();
         SurfacePackage mockOverlaySurfacePackage = Mockito.mock(SurfacePackage.class);
         when(mockOverlaySurfacePackage.getSurfaceControl()).thenReturn(mockOverlaySurfaceControl);
-        mFakeGameSessionService.removePendingFutureForTaskId(10)
+        mFakeGameSessionService.removePendingFutureForTaskId(taskId)
                 .complete(new CreateGameSessionResult(gameSession10, mockOverlaySurfacePackage));
 
         IGameSessionController gameSessionController = getOnlyElement(
                 mFakeGameSessionService.getCapturedCreateInvocations()).mGameSessionController;
         AndroidFuture<GameScreenshotResult> resultFuture = new AndroidFuture<>();
-        gameSessionController.takeScreenshot(10, resultFuture);
+        gameSessionController.takeScreenshot(taskId, resultFuture);
 
         GameScreenshotResult result = resultFuture.get();
         assertEquals(GameScreenshotResult.GAME_SCREENSHOT_SUCCESS, result.getStatus());
-        assertEquals(TEST_BITMAP, result.getBitmap());
     }
 
     @Test
@@ -874,7 +1125,8 @@
                 mFakeGameSessionService.getCapturedCreateInvocations())
                 .mGameSessionController.restartGame(11);
 
-        verifyZeroInteractions(mMockActivityManager);
+        verify(mMockActivityManager).registerProcessObserver(any());
+        verifyNoMoreInteractions(mMockActivityManager);
         assertThat(mMockContext.getLastStartedIntent()).isNull();
     }
 
@@ -906,7 +1158,6 @@
         dispatchTaskRemoved(taskId);
     }
 
-
     private void dispatchTaskRemoved(int taskId) {
         dispatchTaskChangeEvent(taskStackListener -> {
             taskStackListener.onTaskRemoved(taskId);
@@ -932,6 +1183,37 @@
         }
     }
 
+    private void startProcessForPackage(int processId, @Nullable String packageName) {
+        if (packageName != null) {
+            when(mMockActivityManagerInternal.getPackageNameByPid(processId)).thenReturn(
+                    packageName);
+        }
+
+        dispatchProcessActivity(processId);
+    }
+
+    private void dispatchProcessActivity(int processId) {
+        dispatchProcessChangedEvent(processObserver -> {
+            // Neither uid nor foregroundActivities are used by the implementation being tested.
+            processObserver.onForegroundActivitiesChanged(processId, /*uid=*/
+                    0, /*foregroundActivities=*/ false);
+        });
+    }
+
+    private void dispatchProcessDied(int processId) {
+        dispatchProcessChangedEvent(processObserver -> {
+            // The uid param is not used by the implementation being tested.
+            processObserver.onProcessDied(processId, /*uid=*/ 0);
+        });
+    }
+
+    private void dispatchProcessChangedEvent(
+            ThrowingConsumer<IProcessObserver> processObserverConsumer) {
+        for (IProcessObserver processObserver : mProcessObservers) {
+            processObserverConsumer.accept(processObserver);
+        }
+    }
+
     private void mockPermissionGranted(String permission) {
         mMockContext.setPermission(permission, PackageManager.PERMISSION_GRANTED);
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index b5ad459..784f732 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -754,6 +754,57 @@
         verify(mMockedBacklight, never()).setBrightness(anyFloat());
     }
 
+    @Test
+    public void testGetSystemPreferredDisplayMode() throws Exception {
+        SurfaceControl.DisplayMode displayMode1 = createFakeDisplayMode(0, 1920, 1080, 60f);
+        // preferred mode
+        SurfaceControl.DisplayMode displayMode2 = createFakeDisplayMode(1, 3840, 2160, 60f);
+
+        SurfaceControl.DisplayMode[] modes =
+                new SurfaceControl.DisplayMode[]{displayMode1, displayMode2};
+        FakeDisplay display = new FakeDisplay(PORT_A, modes, 0, 1);
+        setUpDisplay(display);
+        updateAvailableDisplays();
+        mAdapter.registerLocked();
+        waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+        assertThat(mListener.addedDisplays.size()).isEqualTo(1);
+        assertThat(mListener.changedDisplays).isEmpty();
+
+        DisplayDeviceInfo displayDeviceInfo = mListener.addedDisplays.get(
+                0).getDisplayDeviceInfoLocked();
+
+        assertThat(displayDeviceInfo.supportedModes.length).isEqualTo(modes.length);
+
+        Display.Mode defaultMode = getModeById(displayDeviceInfo, displayDeviceInfo.defaultModeId);
+        assertThat(matches(defaultMode, displayMode2)).isTrue();
+
+        // Change the display and add new preferred mode
+        SurfaceControl.DisplayMode addedDisplayInfo = createFakeDisplayMode(2, 2340, 1080, 60f);
+        modes = new SurfaceControl.DisplayMode[]{displayMode1, displayMode2, addedDisplayInfo};
+        display.dynamicInfo.supportedDisplayModes = modes;
+        display.dynamicInfo.preferredBootDisplayMode = 2;
+        setUpDisplay(display);
+        mInjector.getTransmitter().sendHotplug(display, /* connected */ true);
+        waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+        assertTrue(mListener.traversalRequested);
+        assertThat(mListener.addedDisplays.size()).isEqualTo(1);
+        assertThat(mListener.changedDisplays.size()).isEqualTo(1);
+
+        DisplayDevice displayDevice = mListener.changedDisplays.get(0);
+        displayDevice.applyPendingDisplayDeviceInfoChangesLocked();
+        displayDeviceInfo = displayDevice.getDisplayDeviceInfoLocked();
+
+        assertThat(displayDeviceInfo.supportedModes.length).isEqualTo(modes.length);
+        assertModeIsSupported(displayDeviceInfo.supportedModes, displayMode1);
+        assertModeIsSupported(displayDeviceInfo.supportedModes, displayMode2);
+        assertModeIsSupported(displayDeviceInfo.supportedModes, addedDisplayInfo);
+
+        assertThat(matches(displayDevice.getSystemPreferredDisplayModeLocked(), addedDisplayInfo))
+                .isTrue();
+    }
+
     private void assertDisplayDpi(DisplayDeviceInfo info, int expectedPort,
                                   float expectedXdpi,
                                   float expectedYDpi,
@@ -831,6 +882,16 @@
             dynamicInfo.supportedDisplayModes = modes;
             dynamicInfo.activeDisplayModeId = activeMode;
         }
+
+        private FakeDisplay(int port, SurfaceControl.DisplayMode[] modes, int activeMode,
+                int preferredMode) {
+            address = createDisplayAddress(port);
+            info = createFakeDisplayInfo();
+            dynamicInfo.supportedDisplayModes = modes;
+            dynamicInfo.activeDisplayModeId = activeMode;
+            dynamicInfo.preferredBootDisplayMode = preferredMode;
+        }
+
     }
 
     private void setUpDisplay(FakeDisplay display) {
@@ -843,6 +904,7 @@
                 .thenReturn(display.dynamicInfo);
         when(mSurfaceControlProxy.getDesiredDisplayModeSpecs(display.token))
                 .thenReturn(display.desiredDisplayModeSpecs);
+        when(mSurfaceControlProxy.getBootDisplayModeSupport()).thenReturn(true);
     }
 
     private void updateAvailableDisplays() {
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java
index 8223b8c..6f503c7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java
@@ -116,7 +116,7 @@
         when(mInjector.getDataDirStorageLowBytes()).thenReturn(STORAGE_LOW_BYTES);
         when(mInjector.getDexOptThermalCutoff()).thenReturn(PowerManager.THERMAL_STATUS_CRITICAL);
         when(mInjector.getCurrentThermalStatus()).thenReturn(PowerManager.THERMAL_STATUS_NONE);
-        when(mDexOptHelper.getOptimizablePackages()).thenReturn(DEFAULT_PACKAGE_LIST);
+        when(mDexOptHelper.getOptimizablePackages(any())).thenReturn(DEFAULT_PACKAGE_LIST);
         when(mDexOptHelper.performDexOptWithStatus(any())).thenReturn(
                 PackageDexOptimizer.DEX_OPT_PERFORMED);
 
@@ -158,7 +158,7 @@
     @Test
     public void testNoExecutionForNoOptimizablePackages() {
         initUntilBootCompleted();
-        when(mDexOptHelper.getOptimizablePackages()).thenReturn(EMPTY_PACKAGE_LIST);
+        when(mDexOptHelper.getOptimizablePackages(any())).thenReturn(EMPTY_PACKAGE_LIST);
 
         assertThat(mService.onStartJob(mJobServiceForPostBoot,
                 mJobParametersForPostBoot)).isFalse();
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS b/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS
index 46b797b..5181af1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/OWNERS
@@ -1,3 +1,4 @@
 include /services/core/java/com/android/server/pm/OWNERS
 
+per-file BackgroundDexOptServiceUnitTest.java = file:/services/core/java/com/android/server/pm/dex/OWNERS
 per-file StagingManagerTest.java = dariofreni@google.com, ioffe@google.com, olilan@google.com
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt
index ccfeb4c..fbbb814 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt
@@ -74,6 +74,10 @@
         assertThat(assertFailsWith(exceptionClass, block).message).contains(message)
     }
 
+    private fun checkPackageStartable() {
+        pms.checkPackageStartable(pms.snapshotComputer(), TEST_PACKAGE, TEST_USER_ID)
+    }
+
     @Before
     @Throws(Exception::class)
     fun setup() {
@@ -89,11 +93,11 @@
             .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON))
 
         assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) {
-            pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+            checkPackageStartable()
         }
 
         freezer.close()
-        pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+        checkPackageStartable()
     }
 
     @Test
@@ -104,16 +108,16 @@
             .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON))
 
         assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) {
-            pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+            checkPackageStartable()
         }
 
         freezer1.close()
         assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) {
-            pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+            checkPackageStartable()
         }
 
         freezer2.close()
-        pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+        checkPackageStartable()
     }
 
     @Test
@@ -123,13 +127,13 @@
             .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON))
 
         assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) {
-            pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+            checkPackageStartable()
         }
 
         freezer = null
         System.gc()
         System.runFinalization()
 
-        pms.checkPackageStartable(TEST_PACKAGE, TEST_USER_ID)
+        checkPackageStartable()
     }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt
index a6c7bfb..537a028 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceHibernationTests.kt
@@ -107,7 +107,7 @@
         whenever(appHibernationManager.isHibernatingForUser(TEST_PACKAGE_NAME, TEST_USER_ID))
             .thenReturn(true)
 
-        pm.setPackageStoppedState(TEST_PACKAGE_NAME, false, TEST_USER_ID)
+        pm.setPackageStoppedState(pm.snapshotComputer(), TEST_PACKAGE_NAME, false, TEST_USER_ID)
 
         TestableLooper.get(this).processAllMessages()
 
@@ -133,7 +133,8 @@
             .thenReturn(true)
 
         try {
-            pm.setPackageStoppedState(TEST_PACKAGE_NAME, false, TEST_USER_ID)
+            pm.setPackageStoppedState(pm.snapshotComputer(), TEST_PACKAGE_NAME, false,
+                TEST_USER_ID)
             TestableLooper.get(this).processAllMessages()
         } catch (e: Exception) {
             Assert.fail("Method throws exception when AppHibernationManager is not ready.\n$e")
@@ -156,7 +157,7 @@
         rule.system().validateFinalState()
         whenever(appHibernationManager.isHibernatingGlobally(TEST_PACKAGE_2_NAME)).thenReturn(true)
 
-        val optimizablePkgs = DexOptHelper(pm).optimizablePackages
+        val optimizablePkgs = DexOptHelper(pm).getOptimizablePackages(pm.snapshotComputer())
 
         assertTrue(optimizablePkgs.contains(TEST_PACKAGE_NAME))
         assertFalse(optimizablePkgs.contains(TEST_PACKAGE_2_NAME))
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
index b063d22..97b52a9 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
@@ -24,7 +24,6 @@
 import android.os.storage.StorageManager
 import android.util.ArrayMap
 import android.util.PackageUtils
-import com.android.internal.util.FunctionalUtils
 import com.android.server.SystemConfig.SharedLibraryEntry
 import com.android.server.compat.PlatformCompat
 import com.android.server.extendedtestutils.wheneverStatic
@@ -35,7 +34,6 @@
 import com.android.server.testutils.any
 import com.android.server.testutils.eq
 import com.android.server.testutils.mock
-import com.android.server.testutils.mockThrowOnUnmocked
 import com.android.server.testutils.nullable
 import com.android.server.testutils.spy
 import com.android.server.testutils.whenever
@@ -59,6 +57,7 @@
 import kotlin.test.assertFalse
 import kotlin.test.assertTrue
 
+@Ignore("b/216603387")
 @RunWith(JUnit4::class)
 class SharedLibrariesImplTest {
 
@@ -85,6 +84,7 @@
     private lateinit var mSharedLibrariesImpl: SharedLibrariesImpl
     private lateinit var mPms: PackageManagerService
     private lateinit var mSettings: Settings
+    private lateinit var mComputer: Computer
 
     @Mock
     private lateinit var mDeletePackageHelper: DeletePackageHelper
@@ -114,22 +114,16 @@
         mSharedLibrariesImpl.setDeletePackageHelper(mDeletePackageHelper)
         addExistingSharedLibraries()
 
+        mComputer = mock {
+            whenever(sharedLibraries) { mSharedLibrariesImpl.sharedLibraries }
+            whenever(resolveInternalPackageName(anyString(), anyLong())) { arguments[0] }
+        }
+
         whenever(mSettings.getPackageLPr(any())) { mExistingSettings[arguments[0]] }
         whenever(mRule.mocks().injector.getSystemService(StorageManager::class.java))
             .thenReturn(mStorageManager)
         whenever(mStorageManager.findPathForUuid(nullable())).thenReturn(mFile)
-        doAnswer { it.arguments[0] }.`when`(mPms).resolveInternalPackageName(any(), any())
-        doAnswer {
-            mockThrowOnUnmocked<Computer> {
-                whenever(sharedLibraries) { mSharedLibrariesImpl.sharedLibraries }
-                whenever(resolveInternalPackageName(anyString(), anyLong())) {
-                    mPms.resolveInternalPackageName(getArgument(0), getArgument(1))
-                }
-                whenever(getPackageStateInternal(anyString())) {
-                    mPms.getPackageStateInternal(getArgument(0))
-                }
-            }
-        }.`when`(mPms).snapshotComputer()
+        doAnswer { mComputer }.`when`(mPms).snapshotComputer()
         whenever(mDeletePackageHelper.deletePackageX(any(), any(), any(), any(), any()))
             .thenReturn(PackageManager.DELETE_SUCCEEDED)
         whenever(mRule.mocks().injector.compatibility).thenReturn(mPlatformCompat)
@@ -189,7 +183,8 @@
 
     @Test
     fun removeSharedLibrary() {
-        doAnswer { mutableListOf(VersionedPackage(CONSUMER_PACKAGE_NAME, 1L)) }.`when`(mPms)
+        doAnswer { mutableListOf(VersionedPackage(CONSUMER_PACKAGE_NAME, 1L)) }
+            .`when`(mComputer)
             .getPackagesUsingSharedLibrary(any(), any(), any(), any())
         val staticInfo = mSharedLibrariesImpl
             .getSharedLibraryInfo(STATIC_LIB_NAME, STATIC_LIB_VERSION)!!
@@ -253,7 +248,6 @@
         assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME))
     }
 
-    @Ignore("b/216603387")
     @Test
     fun updateSharedLibraries_withStaticLibPackage() {
         val testPackageSetting = mExistingSettings[STATIC_LIB_PACKAGE_NAME]!!
@@ -266,7 +260,6 @@
         assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(DYNAMIC_LIB_PACKAGE_NAME))
     }
 
-    @Ignore("b/216603387")
     @Test
     fun updateSharedLibraries_withConsumerPackage() {
         val testPackageSetting = mExistingSettings[CONSUMER_PACKAGE_NAME]!!
@@ -280,7 +273,6 @@
         assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(STATIC_LIB_PACKAGE_NAME))
     }
 
-    @Ignore("b/216603387")
     @Test
     fun updateAllSharedLibraries() {
         mExistingSettings.forEach {
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
index f7b1dd5..1464405 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
@@ -39,8 +39,7 @@
 import android.content.pm.ApexStagedEvent;
 import android.content.pm.IStagedApexObserver;
 import android.content.pm.PackageInstaller;
-import android.content.pm.PackageInstaller.SessionInfo;
-import android.content.pm.PackageInstaller.SessionInfo.SessionErrorCode;
+import android.content.pm.PackageManager;
 import android.content.pm.StagedApexInfo;
 import android.os.SystemProperties;
 import android.os.storage.IStorageManager;
@@ -158,10 +157,10 @@
 
         mStagingManager.restoreSessions(Arrays.asList(session1, session2), true);
 
-        assertThat(session1.getErrorCode()).isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+        assertThat(session1.getErrorCode()).isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(session1.getErrorMessage()).isEqualTo("Build fingerprint has changed");
 
-        assertThat(session2.getErrorCode()).isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+        assertThat(session2.getErrorCode()).isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(session2.getErrorMessage()).isEqualTo("Build fingerprint has changed");
     }
 
@@ -247,12 +246,12 @@
         verify(mStorageManager, never()).abortChanges(eq("abort-staged-install"), eq(false));
 
         assertThat(apexSession.getErrorCode())
-                .isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+                .isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(apexSession.getErrorMessage()).isEqualTo("apexd did not know anything about a "
                 + "staged session supposed to be activated");
 
         assertThat(apkSession.getErrorCode())
-                .isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+                .isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(apkSession.getErrorMessage()).isEqualTo("Another apex session failed");
     }
 
@@ -303,22 +302,22 @@
         verify(mStorageManager, never()).abortChanges(eq("abort-staged-install"), eq(false));
 
         assertThat(apexSession1.getErrorCode())
-                .isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+                .isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(apexSession1.getErrorMessage()).isEqualTo("APEX activation failed. "
                 + "Error: Failed for test");
 
         assertThat(apexSession2.getErrorCode())
-                .isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+                .isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(apexSession2.getErrorMessage()).isEqualTo("Staged session 101 at boot didn't "
                 + "activate nor fail. Marking it as failed anyway.");
 
         assertThat(apexSession3.getErrorCode())
-                .isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+                .isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(apexSession3.getErrorMessage()).isEqualTo("apexd did not know anything about a "
                 + "staged session supposed to be activated");
 
         assertThat(apkSession.getErrorCode())
-                .isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+                .isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(apkSession.getErrorMessage()).isEqualTo("Another apex session failed");
     }
 
@@ -351,12 +350,12 @@
         verify(mStorageManager, never()).abortChanges(eq("abort-staged-install"), eq(false));
 
         assertThat(apexSession.getErrorCode())
-                .isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+                .isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(apexSession.getErrorMessage()).isEqualTo("Staged session 1543 at boot didn't "
                 + "activate nor fail. Marking it as failed anyway.");
 
         assertThat(apkSession.getErrorCode())
-                .isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+                .isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(apkSession.getErrorMessage()).isEqualTo("Another apex session failed");
     }
 
@@ -445,11 +444,11 @@
         verify(mStorageManager, never()).abortChanges(eq("abort-staged-install"), eq(false));
 
         assertThat(apexSession.getErrorCode())
-                .isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+                .isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(apexSession.getErrorMessage()).isEqualTo("Impossible state");
 
         assertThat(apkSession.getErrorCode())
-                .isEqualTo(SessionInfo.SESSION_ACTIVATION_FAILED);
+                .isEqualTo(PackageManager.INSTALL_ACTIVATION_FAILED);
         assertThat(apkSession.getErrorMessage()).isEqualTo("Another apex session failed");
     }
 
@@ -755,7 +754,7 @@
                 /* isReady */ false,
                 /* isFailed */ false,
                 /* isApplied */false,
-                /* stagedSessionErrorCode */ PackageInstaller.SessionInfo.SESSION_NO_ERROR,
+                /* stagedSessionErrorCode */ PackageManager.INSTALL_UNKNOWN,
                 /* stagedSessionErrorMessage */ "no error");
 
         StagingManager.StagedSession stagedSession = spy(session.mStagedSession);
@@ -775,7 +774,7 @@
         private boolean mIsReady = false;
         private boolean mIsApplied = false;
         private boolean mIsFailed = false;
-        private @SessionErrorCode int mErrorCode = -1;
+        private int mErrorCode = -1;
         private String mErrorMessage;
         private boolean mIsDestroyed = false;
         private int mParentSessionId = -1;
@@ -828,7 +827,7 @@
             return this;
         }
 
-        private @SessionErrorCode int getErrorCode() {
+        private int getErrorCode() {
             return mErrorCode;
         }
 
@@ -940,7 +939,7 @@
         }
 
         @Override
-        public void setSessionFailed(@SessionErrorCode int errorCode, String errorMessage) {
+        public void setSessionFailed(int errorCode, String errorMessage) {
             Preconditions.checkState(!mIsApplied, "Already marked as applied");
             mIsFailed = true;
             mErrorCode = errorCode;
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 5230ea7..4818573 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
@@ -104,9 +104,9 @@
             pms, rule.mocks().injector, broadcastHelper, protectedPackages)
         defaultAppProvider = rule.mocks().defaultAppProvider
         testHandler = rule.mocks().handler
-        packageSetting1 = pms.getPackageStateInternal(TEST_PACKAGE_1)!!
-        packageSetting2 = pms.getPackageStateInternal(TEST_PACKAGE_2)!!
-        ownerSetting = pms.getPackageStateInternal(DEVICE_OWNER_PACKAGE)!!
+        packageSetting1 = pms.snapshotComputer().getPackageStateInternal(TEST_PACKAGE_1)!!
+        packageSetting2 = pms.snapshotComputer().getPackageStateInternal(TEST_PACKAGE_2)!!
+        ownerSetting = pms.snapshotComputer().getPackageStateInternal(DEVICE_OWNER_PACKAGE)!!
         deviceOwnerUid = UserHandle.getUid(TEST_USER_ID, ownerSetting.appId)
         packagesToSuspend = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
         uidsToSuspend = intArrayOf(packageSetting1.appId, packageSetting2.appId)
@@ -270,7 +270,7 @@
         testHandler.flush()
         assertThat(failedNames).isEmpty()
 
-        val result = suspendPackageHelper.getSuspendedPackageAppExtras(
+        val result = suspendPackageHelper.getSuspendedPackageAppExtras(pms.snapshotComputer(),
             TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)!!
 
         assertThat(result.getString(TEST_PACKAGE_1)).isEqualTo(TEST_PACKAGE_1)
@@ -286,13 +286,13 @@
             null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
         testHandler.flush()
         assertThat(failedNames).isEmpty()
-        assertThat(suspendPackageHelper.getSuspendingPackage(
+        assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(),
             TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isEqualTo(DEVICE_OWNER_PACKAGE)
-        assertThat(suspendPackageHelper.getSuspendingPackage(
+        assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(),
             TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isEqualTo(DEVICE_OWNER_PACKAGE)
-        assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(
+        assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(pms.snapshotComputer(),
             TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isNotNull()
-        assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(
+        assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(pms.snapshotComputer(),
             TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isNotNull()
 
         suspendPackageHelper.removeSuspensionsBySuspendingPackage(pms.snapshotComputer(),
@@ -311,13 +311,13 @@
             nullable(), nullable(), any(), eq(TEST_PACKAGE_2), nullable(), any(), any(),
             nullable(), nullable())
 
-        assertThat(suspendPackageHelper.getSuspendingPackage(
+        assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(),
             TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isNull()
-        assertThat(suspendPackageHelper.getSuspendingPackage(
+        assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(),
             TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isNull()
-        assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(
+        assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(pms.snapshotComputer(),
             TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isNull()
-        assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(
+        assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(pms.snapshotComputer(),
             TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isNull()
     }
 
@@ -331,7 +331,7 @@
         testHandler.flush()
         assertThat(failedNames).isEmpty()
 
-        val result = suspendPackageHelper.getSuspendedPackageLauncherExtras(
+        val result = suspendPackageHelper.getSuspendedPackageLauncherExtras(pms.snapshotComputer(),
             TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)!!
 
         assertThat(result.getString(TEST_PACKAGE_2)).isEqualTo(TEST_PACKAGE_2)
@@ -346,7 +346,7 @@
         testHandler.flush()
         assertThat(failedNames).isEmpty()
 
-        assertThat(suspendPackageHelper.isPackageSuspended(
+        assertThat(suspendPackageHelper.isPackageSuspended(pms.snapshotComputer(),
             TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isTrue()
     }
 
@@ -360,7 +360,7 @@
         testHandler.flush()
         assertThat(failedNames).isEmpty()
 
-        assertThat(suspendPackageHelper.getSuspendingPackage(
+        assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(),
             TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isEqualTo(DEVICE_OWNER_PACKAGE)
     }
 
@@ -375,7 +375,7 @@
         testHandler.flush()
         assertThat(failedNames).isEmpty()
 
-        val result = suspendPackageHelper.getSuspendedDialogInfo(
+        val result = suspendPackageHelper.getSuspendedDialogInfo(pms.snapshotComputer(),
             TEST_PACKAGE_1, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)!!
 
         assertThat(result.title).isEqualTo(TEST_PACKAGE_1)
@@ -387,8 +387,8 @@
         mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
         mockAllowList(packageSetting2, allowList(10001, 10002, 10003))
 
-        suspendPackageHelper.sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_SUSPENDED,
-                packagesToSuspend, uidsToSuspend, TEST_USER_ID)
+        suspendPackageHelper.sendPackagesSuspendedForUser(pms.snapshotComputer(),
+            Intent.ACTION_PACKAGES_SUSPENDED, packagesToSuspend, uidsToSuspend, TEST_USER_ID)
         testHandler.flush()
         verify(broadcastHelper).sendPackageBroadcast(any(), nullable(), bundleCaptor.capture(),
                 anyInt(), nullable(), nullable(), any(), nullable(), any(), nullable())
@@ -406,8 +406,8 @@
         mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
         mockAllowList(packageSetting2, allowList(10001, 10002, 10007))
 
-        suspendPackageHelper.sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_SUSPENDED,
-                packagesToSuspend, uidsToSuspend, TEST_USER_ID)
+        suspendPackageHelper.sendPackagesSuspendedForUser(pms.snapshotComputer(),
+            Intent.ACTION_PACKAGES_SUSPENDED, packagesToSuspend, uidsToSuspend, TEST_USER_ID)
         testHandler.flush()
         verify(broadcastHelper, times(2)).sendPackageBroadcast(
                 any(), nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(),
@@ -429,8 +429,8 @@
         mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
         mockAllowList(packageSetting2, null)
 
-        suspendPackageHelper.sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_SUSPENDED,
-                packagesToSuspend, uidsToSuspend, TEST_USER_ID)
+        suspendPackageHelper.sendPackagesSuspendedForUser(pms.snapshotComputer(),
+            Intent.ACTION_PACKAGES_SUSPENDED, packagesToSuspend, uidsToSuspend, TEST_USER_ID)
         testHandler.flush()
         verify(broadcastHelper, times(2)).sendPackageBroadcast(
                 any(), nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(),
@@ -449,8 +449,9 @@
     @Test
     @Throws(Exception::class)
     fun sendPackagesSuspendModifiedForUser() {
-        suspendPackageHelper.sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_SUSPENSION_CHANGED,
-                packagesToSuspend, uidsToSuspend, TEST_USER_ID)
+        suspendPackageHelper.sendPackagesSuspendedForUser(pms.snapshotComputer(),
+            Intent.ACTION_PACKAGES_SUSPENSION_CHANGED, packagesToSuspend, uidsToSuspend,
+            TEST_USER_ID)
         testHandler.flush()
         verify(broadcastHelper).sendPackageBroadcast(
                 eq(Intent.ACTION_PACKAGES_SUSPENSION_CHANGED), nullable(), bundleCaptor.capture(),
@@ -483,13 +484,13 @@
         Mockito.doReturn(DIALER_PACKAGE).`when`(defaultAppProvider)
             .getDefaultDialer(eq(TEST_USER_ID))
         Mockito.doReturn(arrayOf(INSTALLER_PACKAGE)).`when`(pms).getKnownPackageNamesInternal(
-            eq(PackageManagerInternal.PACKAGE_INSTALLER), eq(TEST_USER_ID))
+            any(), eq(PackageManagerInternal.PACKAGE_INSTALLER), eq(TEST_USER_ID))
         Mockito.doReturn(arrayOf(UNINSTALLER_PACKAGE)).`when`(pms).getKnownPackageNamesInternal(
-            eq(PackageManagerInternal.PACKAGE_UNINSTALLER), eq(TEST_USER_ID))
+            any(), eq(PackageManagerInternal.PACKAGE_UNINSTALLER), eq(TEST_USER_ID))
         Mockito.doReturn(arrayOf(VERIFIER_PACKAGE)).`when`(pms).getKnownPackageNamesInternal(
-            eq(PackageManagerInternal.PACKAGE_VERIFIER), eq(TEST_USER_ID))
+            any(), eq(PackageManagerInternal.PACKAGE_VERIFIER), eq(TEST_USER_ID))
         Mockito.doReturn(arrayOf(PERMISSION_CONTROLLER_PACKAGE)).`when`(pms)
-            .getKnownPackageNamesInternal(
+            .getKnownPackageNamesInternal(any(),
                 eq(PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER), eq(TEST_USER_ID))
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java
index 8abe46f..9d26971 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -159,8 +159,8 @@
             .when(mockContext)
                 .getSystemService(PowerManager.class);
 
-        mDexManager = new DexManager(mockContext, mPM, /*PackageDexOptimizer*/ null,
-                mInstaller, mInstallLock);
+        mDexManager = new DexManager(mockContext, /*PackageDexOptimizer*/ null,
+                mInstaller, mInstallLock, mPM);
 
         // Foo and Bar are available to user0.
         // Only Bar is available to user1;
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java
index 41d46f2..534d0a1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java
@@ -21,7 +21,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
 import android.app.AlarmManager;
 import android.content.Context;
@@ -71,10 +70,10 @@
                 .strictness(Strictness.LENIENT)
                 .mockStatic(LocalServices.class)
                 .startMocking();
-        when(mIrs.getContext()).thenReturn(mContext);
-        when(mIrs.getCompleteEconomicPolicyLocked()).thenReturn(mEconomicPolicy);
-        when(mIrs.getLock()).thenReturn(mIrs);
-        when(mContext.getSystemService(Context.ALARM_SERVICE)).thenReturn(mock(AlarmManager.class));
+        doReturn(mContext).when(mIrs).getContext();
+        doReturn(mEconomicPolicy).when(mIrs).getCompleteEconomicPolicyLocked();
+        doReturn(mIrs).when(mIrs).getLock();
+        doReturn(mock(AlarmManager.class)).when(mContext).getSystemService(Context.ALARM_SERVICE);
         mScribe = new MockScribe(mIrs);
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
index ab29e59..c2cf2ff 100644
--- a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
@@ -109,6 +109,7 @@
         long lastReclamationTime = System.currentTimeMillis();
         long remainingConsumableNarcs = 2000L;
         long consumptionLimit = 500_000L;
+        when(mIrs.getConsumptionLimitLocked()).thenReturn(consumptionLimit);
 
         Ledger ledger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE);
         ledger.recordTransaction(new Ledger.Transaction(0, 1000L, 1, null, 2000, 0));
@@ -119,8 +120,13 @@
         mScribeUnderTest.setConsumptionLimitLocked(consumptionLimit);
         mScribeUnderTest.adjustRemainingConsumableNarcsLocked(
                 remainingConsumableNarcs - consumptionLimit);
-        mScribeUnderTest.writeImmediatelyForTesting();
 
+        assertEquals(lastReclamationTime, mScribeUnderTest.getLastReclamationTimeLocked());
+        assertEquals(remainingConsumableNarcs,
+                mScribeUnderTest.getRemainingConsumableNarcsLocked());
+        assertEquals(consumptionLimit, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
+
+        mScribeUnderTest.writeImmediatelyForTesting();
         mScribeUnderTest.loadFromDiskLocked();
 
         assertEquals(lastReclamationTime, mScribeUnderTest.getLastReclamationTimeLocked());
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 152f3b3..e3be3a7 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -64,6 +64,7 @@
         "testng",
         "junit",
         "platform-compat-test-rules",
+        "ActivityContext",
     ],
 
     aidl: {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 1f016fb..56c5150 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -28,6 +28,8 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doCallRealMethod;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -61,10 +63,12 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.compatibility.common.util.TestUtils;
+import com.android.internal.compat.IPlatformCompat;
 import com.android.server.LocalServices;
 import com.android.server.accessibility.AccessibilityManagerService.AccessibilityDisplayListener;
 import com.android.server.accessibility.magnification.FullScreenMagnificationController;
 import com.android.server.accessibility.magnification.MagnificationController;
+import com.android.server.accessibility.magnification.MagnificationProcessor;
 import com.android.server.accessibility.magnification.WindowMagnificationManager;
 import com.android.server.accessibility.test.MessageCapturingHandler;
 import com.android.server.pm.UserManagerInternal;
@@ -185,7 +189,7 @@
         mA11yms.mUserStates.put(mA11yms.getCurrentUserIdLocked(), userState);
     }
 
-    private void setupAccessibilityServiceConnection() {
+    private void setupAccessibilityServiceConnection(int serviceInfoFlag) {
         final AccessibilityUserState userState = mA11yms.mUserStates.get(
                 mA11yms.getCurrentUserIdLocked());
         when(mMockServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo);
@@ -193,7 +197,12 @@
         mMockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class);
 
         when(mMockBinder.queryLocalInterface(any())).thenReturn(mMockServiceClient);
+        when(mMockSystemSupport.getKeyEventDispatcher()).thenReturn(mock(KeyEventDispatcher.class));
+        when(mMockSystemSupport.getMagnificationProcessor()).thenReturn(
+                mock(MagnificationProcessor.class));
         mTestableContext.addMockService(COMPONENT_NAME, mMockBinder);
+
+        mMockServiceInfo.flags = serviceInfoFlag;
         mAccessibilityServiceConnection = new AccessibilityServiceConnection(
                 userState,
                 mTestableContext,
@@ -256,7 +265,7 @@
     @SmallTest
     @Test
     public void testOnSystemActionsChanged() throws Exception {
-        setupAccessibilityServiceConnection();
+        setupAccessibilityServiceConnection(0);
         final AccessibilityUserState userState = mA11yms.mUserStates.get(
                 mA11yms.getCurrentUserIdLocked());
 
@@ -376,7 +385,7 @@
     @SmallTest
     @Test
     public void testOnClientChange_boundServiceCanControlMagnification_requestConnection() {
-        setupAccessibilityServiceConnection();
+        setupAccessibilityServiceConnection(0);
         when(mMockSecurityPolicy.canControlMagnification(any())).thenReturn(true);
 
         // Invokes client change to trigger onUserStateChanged.
@@ -385,6 +394,29 @@
         verify(mMockWindowMagnificationMgr).requestConnection(true);
     }
 
+    @Test
+    public void testUnbindIme_whenServiceUnbinds() {
+        setupAccessibilityServiceConnection(AccessibilityServiceInfo.FLAG_INPUT_METHOD_EDITOR);
+        mAccessibilityServiceConnection.unbindLocked();
+        verify(mMockSystemSupport, atLeastOnce()).unbindImeLocked(mAccessibilityServiceConnection);
+    }
+
+    @Test
+    public void testUnbindIme_whenServiceCrashed() {
+        setupAccessibilityServiceConnection(AccessibilityServiceInfo.FLAG_INPUT_METHOD_EDITOR);
+        mAccessibilityServiceConnection.binderDied();
+        verify(mMockSystemSupport).unbindImeLocked(mAccessibilityServiceConnection);
+    }
+
+    @Test
+    public void testUnbindIme_whenServiceStopsRequestingIme() {
+        setupAccessibilityServiceConnection(AccessibilityServiceInfo.FLAG_INPUT_METHOD_EDITOR);
+        doCallRealMethod().when(mMockServiceInfo).updateDynamicallyConfigurableProperties(
+                any(IPlatformCompat.class), any(AccessibilityServiceInfo.class));
+        mAccessibilityServiceConnection.setServiceInfo(new AccessibilityServiceInfo());
+        verify(mMockSystemSupport).unbindImeLocked(mAccessibilityServiceConnection);
+    }
+
     public static class FakeInputFilter extends AccessibilityInputFilter {
         FakeInputFilter(Context context,
                 AccessibilityManagerService service) {
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 b601d14..1ebcbe1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -4157,8 +4157,8 @@
     @Test
     public void testSetPreferentialNetworkServiceConfig_noProfileOwner() throws Exception {
         assertExpectException(SecurityException.class, null,
-                () -> dpm.setPreferentialNetworkServiceConfig(
-                        PreferentialNetworkServiceConfig.DEFAULT));
+                () -> dpm.setPreferentialNetworkServiceConfigs(
+                        List.of(PreferentialNetworkServiceConfig.DEFAULT)));
     }
 
     @Test
@@ -4198,10 +4198,10 @@
         addManagedProfile(admin1, managedProfileAdminUid, admin1);
         mContext.binder.callingUid = managedProfileAdminUid;
 
-        dpm.setPreferentialNetworkServiceConfig(PreferentialNetworkServiceConfig.DEFAULT);
+        dpm.setPreferentialNetworkServiceConfigs(
+                List.of(PreferentialNetworkServiceConfig.DEFAULT));
         assertThat(dpm.isPreferentialNetworkServiceEnabled()).isFalse();
-        assertThat(dpm.getPreferentialNetworkServiceConfig()
-                .isEnabled()).isFalse();
+        assertThat(dpm.getPreferentialNetworkServiceConfigs().get(0).isEnabled()).isFalse();
 
         ProfileNetworkPreference preferenceDetails =
                 new ProfileNetworkPreference.Builder()
@@ -4227,8 +4227,8 @@
         addManagedProfile(admin1, managedProfileAdminUid, admin1);
         mContext.binder.callingUid = managedProfileAdminUid;
 
-        dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled);
-        assertThat(dpm.getPreferentialNetworkServiceConfig()
+        dpm.setPreferentialNetworkServiceConfigs(List.of(preferentialNetworkServiceConfigEnabled));
+        assertThat(dpm.getPreferentialNetworkServiceConfigs().get(0)
                 .isEnabled()).isTrue();
         ProfileNetworkPreference preferenceDetails =
                 new ProfileNetworkPreference.Builder()
@@ -4257,8 +4257,8 @@
                         .setFallbackToDefaultConnectionAllowed(false)
                         .setIncludedUids(new int[]{1, 2})
                         .build();
-        dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled);
-        assertThat(dpm.getPreferentialNetworkServiceConfig()
+        dpm.setPreferentialNetworkServiceConfigs(List.of(preferentialNetworkServiceConfigEnabled));
+        assertThat(dpm.getPreferentialNetworkServiceConfigs().get(0)
                 .isEnabled()).isTrue();
         List<Integer> includedList = new ArrayList<>();
         includedList.add(1);
@@ -4292,8 +4292,8 @@
                         .setExcludedUids(new int[]{1, 2})
                         .build();
 
-        dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled);
-        assertThat(dpm.getPreferentialNetworkServiceConfig()
+        dpm.setPreferentialNetworkServiceConfigs(List.of(preferentialNetworkServiceConfigEnabled));
+        assertThat(dpm.getPreferentialNetworkServiceConfigs().get(0)
                 .isEnabled()).isTrue();
         List<Integer> excludedUids = new ArrayList<>();
         excludedUids.add(1);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index a9812ab..d104871 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -89,6 +89,7 @@
     private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
     private int mTvPhysicalAddress;
     private int mTvLogicalAddress;
+    private boolean mWokenUp;
 
     @Mock
     private AudioManager mAudioManager;
@@ -104,6 +105,11 @@
                 new HdmiControlService(InstrumentationRegistry.getTargetContext(),
                         Collections.emptyList()) {
                     @Override
+                    void wakeUp() {
+                        mWokenUp = true;
+                        super.wakeUp();
+                    }
+                    @Override
                     boolean isControlEnabled() {
                         return true;
                     }
@@ -308,6 +314,22 @@
     }
 
     @Test
+    public void handleTextViewOn_Dreaming() {
+        mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue(
+                HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY,
+                HdmiControlManager.TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED);
+        mTestLooper.dispatchAll();
+        mPowerManager.setInteractive(true);
+        mWokenUp = false;
+        HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(ADDR_PLAYBACK_1,
+                mTvLogicalAddress);
+        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isEqualTo(Constants.HANDLED);
+        mTestLooper.dispatchAll();
+        assertThat(mPowerManager.isInteractive()).isTrue();
+        assertThat(mWokenUp).isTrue();
+    }
+
+    @Test
     public void tvSendStandbyOnSleep_Enabled() {
         mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue(
                 HdmiControlManager.CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP,
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index 4de15c8..928c76d 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -330,11 +330,12 @@
 
     @Test
     public void testPriorityPersisted() throws Exception {
-        final JobInfo.Builder b = new Builder(92, mComponent)
+        final JobInfo job = new Builder(92, mComponent)
                 .setOverrideDeadline(5000)
                 .setPriority(JobInfo.PRIORITY_MIN)
-                .setPersisted(true);
-        final JobStatus js = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null);
+                .setPersisted(true)
+                .build();
+        final JobStatus js = JobStatus.createFromJobInfo(job, SOME_UID, null, -1, null);
         mTaskStoreUnderTest.add(js);
         waitForPendingIo();
 
@@ -342,7 +343,7 @@
         mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
         final JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
         assertEquals("Priority not correctly persisted.",
-                JobInfo.PRIORITY_MIN, loaded.getEffectivePriority());
+                JobInfo.PRIORITY_MIN, job.getPriority());
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
index 5185e15..db602ca 100644
--- a/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
@@ -98,11 +98,8 @@
     private ActivityTaskManagerInternal mMockActivityTaskManager;
     @Mock
     private ActivityManagerInternal mMockActivityManager;
-    @Mock
-    private LocaleManagerBackupHelper mMockLocaleManagerBackupHelper;
-    @Mock
-    PackageMonitor mMockPackageMonitor;
 
+    PackageMonitor mPackageMonitor;
     private LocaleManagerService mLocaleManagerService;
 
     // Object under test.
@@ -114,11 +111,14 @@
         mMockActivityTaskManager = mock(ActivityTaskManagerInternal.class);
         mMockActivityManager = mock(ActivityManagerInternal.class);
         mMockPackageManagerInternal = mock(PackageManagerInternal.class);
-        mMockPackageMonitor = mock(PackageMonitor.class);
-        mMockLocaleManagerBackupHelper = mock(ShadowLocaleManagerBackupHelper.class);
+        LocaleManagerBackupHelper mockLocaleManagerBackupHelper =
+                mock(ShadowLocaleManagerBackupHelper.class);
+        // PackageMonitor is not needed in LocaleManagerService for these tests hence it is
+        // passed as null.
         mLocaleManagerService = new LocaleManagerService(mMockContext,
                 mMockActivityTaskManager, mMockActivityManager,
-                mMockPackageManagerInternal, mMockLocaleManagerBackupHelper, mMockPackageMonitor);
+                mMockPackageManagerInternal, mockLocaleManagerBackupHelper,
+                /* mPackageMonitor= */ null);
 
         doReturn(DEFAULT_USER_ID).when(mMockActivityManager)
                 .handleIncomingUser(anyInt(), anyInt(), eq(DEFAULT_USER_ID), anyBoolean(), anyInt(),
@@ -134,6 +134,9 @@
 
         mSystemAppUpdateTracker = new SystemAppUpdateTracker(mMockContext,
             mLocaleManagerService, mStoragefile);
+
+        mPackageMonitor = new LocaleManagerServicePackageMonitor(
+                mockLocaleManagerBackupHelper, mSystemAppUpdateTracker);
     }
 
     @After
@@ -148,7 +151,7 @@
             .when(mMockPackageManager).getApplicationInfo(eq(DEFAULT_PACKAGE_NAME_1), any());
 
         // Updates the app once so that it writes to the file.
-        mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
                 Binder.getCallingUid());
         // Clear the in-memory data of updated apps
         mSystemAppUpdateTracker.getUpdatedApps().clear();
@@ -167,7 +170,7 @@
                 DEFAULT_LOCALES)).when(mMockActivityTaskManager)
                 .getApplicationConfig(anyString(), anyInt());
 
-        mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
                 Binder.getCallingUid());
 
         assertBroadcastSentToInstaller(DEFAULT_PACKAGE_NAME_1, DEFAULT_LOCALES);
@@ -186,7 +189,7 @@
                 .getApplicationConfig(anyString(), anyInt());
 
         // first update
-        mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
                 Binder.getCallingUid());
 
         assertBroadcastSentToInstaller(DEFAULT_PACKAGE_NAME_1, DEFAULT_LOCALES);
@@ -195,7 +198,7 @@
         verifyStorageFileContents(expectedAppList);
 
         // second update
-        mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
                 Binder.getCallingUid());
         // getApplicationLocales should be invoked only once on the first update.
         verify(mMockActivityTaskManager, times(1))
@@ -212,7 +215,7 @@
             /* isUpdatedSystemApp = */false))
             .when(mMockPackageManager).getApplicationInfo(eq(DEFAULT_PACKAGE_NAME_2), any());
 
-        mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_2,
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_2,
                 Binder.getCallingUid());
 
         assertTrue(!mSystemAppUpdateTracker.getUpdatedApps().contains(DEFAULT_PACKAGE_NAME_2));
@@ -231,7 +234,7 @@
             .when(mMockPackageManager).getApplicationInfo(eq(DEFAULT_PACKAGE_NAME_1), any());
         doReturn(null).when(mMockPackageManager).getInstallSourceInfo(anyString());
 
-        mSystemAppUpdateTracker.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
                 Binder.getCallingUid());
 
         // getApplicationLocales should be never be invoked if not installer is not present.
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 21c09a0..1d10b8a 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -217,7 +217,7 @@
     }
 
     @Override
-    protected boolean isCredentialSharedWithParent(int userId) {
+    protected boolean isCredentialSharableWithParent(int userId) {
         UserInfo userInfo = mUserManager.getUserInfo(userId);
         return userInfo.isCloneProfile() || userInfo.isManagedProfile();
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java b/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
index 3cb5d5f..ce322f7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
@@ -20,6 +20,7 @@
 import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+import android.app.ActivityOptions;
 import android.app.AppOpsManager;
 import android.app.IApplicationThread;
 import android.app.admin.DevicePolicyManagerInternal;
@@ -46,6 +47,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.util.SparseArray;
 
+import com.android.activitycontext.ActivityContext;
 import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
 import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
 import com.android.server.LocalServices;
@@ -240,7 +242,9 @@
                                 FEATURE_ID,
                                 ACTIVITY_COMPONENT,
                                 UserHandle.of(PRIMARY_USER).getIdentifier(),
-                                true));
+                                true,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -265,7 +269,9 @@
                                 FEATURE_ID,
                                 ACTIVITY_COMPONENT,
                                 UserHandle.of(PRIMARY_USER).getIdentifier(),
-                                false));
+                                false,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -292,7 +298,9 @@
                                 FEATURE_ID,
                                 ACTIVITY_COMPONENT,
                                 UserHandle.of(PROFILE_OF_PRIMARY_USER).getIdentifier(),
-                                true));
+                                true,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -319,7 +327,9 @@
                                 FEATURE_ID,
                                 ACTIVITY_COMPONENT,
                                 UserHandle.of(PROFILE_OF_PRIMARY_USER).getIdentifier(),
-                                false));
+                                false,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -344,7 +354,9 @@
                                 FEATURE_ID,
                                 ACTIVITY_COMPONENT,
                                 UserHandle.of(PROFILE_OF_PRIMARY_USER).getIdentifier(),
-                                true));
+                                true,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -369,7 +381,9 @@
                                 FEATURE_ID,
                                 ACTIVITY_COMPONENT,
                                 UserHandle.of(PROFILE_OF_PRIMARY_USER).getIdentifier(),
-                                false));
+                                false,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -396,7 +410,9 @@
                                 FEATURE_ID,
                                 ACTIVITY_COMPONENT,
                                 UserHandle.of(PROFILE_OF_PRIMARY_USER).getIdentifier(),
-                                true));
+                                true,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -440,7 +456,9 @@
                                 FEATURE_ID,
                                 ACTIVITY_COMPONENT,
                                 UserHandle.of(PROFILE_OF_PRIMARY_USER).getIdentifier(),
-                                false));
+                                false,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -465,7 +483,9 @@
                                 FEATURE_ID,
                                 new ComponentName(PACKAGE_TWO, "test"),
                                 UserHandle.of(PROFILE_OF_PRIMARY_USER).getIdentifier(),
-                                true));
+                                true,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -490,7 +510,9 @@
                                 FEATURE_ID,
                                 new ComponentName(PACKAGE_TWO, "test"),
                                 UserHandle.of(PROFILE_OF_PRIMARY_USER).getIdentifier(),
-                                false));
+                                false,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -515,7 +537,9 @@
                                 FEATURE_ID,
                                 ACTIVITY_COMPONENT,
                                 UserHandle.of(SECONDARY_USER).getIdentifier(),
-                                true));
+                                true,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -540,7 +564,9 @@
                                 FEATURE_ID,
                                 ACTIVITY_COMPONENT,
                                 UserHandle.of(SECONDARY_USER).getIdentifier(),
-                                false));
+                                false,
+                                /* targetTask */ null,
+                                /* options */ null));
 
         verify(mActivityTaskManagerInternal, never())
                 .startActivityAsUser(
@@ -564,7 +590,9 @@
                 FEATURE_ID,
                 ACTIVITY_COMPONENT,
                 UserHandle.of(PRIMARY_USER).getIdentifier(),
-                true);
+                true,
+                /* targetTask */ null,
+                /* options */ null);
 
         verify(mActivityTaskManagerInternal)
                 .startActivityAsUser(
@@ -578,6 +606,44 @@
                         eq(PRIMARY_USER));
     }
 
+    @Test
+    public void startActivityAsUser_sameTask_fromProfile_success() throws Exception {
+        mTestInjector.setCallingUserId(PROFILE_OF_PRIMARY_USER);
+
+        Bundle options = ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle();
+        IBinder result = ActivityContext.getWithContext(activity -> {
+            try {
+                IBinder targetTask = activity.getActivityToken();
+                mCrossProfileAppsServiceImpl.startActivityAsUser(
+                        mIApplicationThread,
+                        PACKAGE_ONE,
+                        FEATURE_ID,
+                        ACTIVITY_COMPONENT,
+                        UserHandle.of(PRIMARY_USER).getIdentifier(),
+                        true,
+                        targetTask,
+                        options);
+                return targetTask;
+            } catch (Exception re) {
+                return null;
+            }
+        });
+        if (result == null) {
+            throw new Exception();
+        }
+
+        verify(mActivityTaskManagerInternal)
+                .startActivityAsUser(
+                        nullable(IApplicationThread.class),
+                        eq(PACKAGE_ONE),
+                        eq(FEATURE_ID),
+                        any(Intent.class),
+                        eq(result),
+                        anyInt(),
+                        eq(options),
+                        eq(PRIMARY_USER));
+    }
+
     private void mockAppsInstalled(String packageName, int user, boolean installed) {
         when(mPackageManagerInternal.getPackageInfo(
                 eq(packageName),
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
index 3d21b74..27c3ca4 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
@@ -20,10 +20,15 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
 import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
 import android.platform.test.annotations.Presubmit;
 import android.util.AtomicFile;
 import android.util.Slog;
@@ -68,12 +73,17 @@
     @Mock
     PackageManagerService mMockPackageManagerInternal;
 
+    @Mock
+    Computer mSnapshot;
+
     @Before
     public void setUp() throws Exception {
         mTmpDir = mTemporaryFolder.newFolder("PackageInstallerSessionTest");
         mSessionsFile = new AtomicFile(
                 new File(mTmpDir.getAbsolutePath() + "/sessions.xml"), "package-session");
         MockitoAnnotations.initMocks(this);
+        when(mSnapshot.getPackageUid(anyString(), anyLong(), anyInt())).thenReturn(0);
+        when(mMockPackageManagerInternal.snapshotComputer()).thenReturn(mSnapshot);
     }
 
     @Test
@@ -188,7 +198,7 @@
                 /* isFailed */ false,
                 /* isApplied */false,
                 /* stagedSessionErrorCode */
-                PackageInstaller.SessionInfo.SESSION_VERIFICATION_FAILED,
+                PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
                 /* stagedSessionErrorMessage */ "some error");
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
index 050b224..946108d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
@@ -23,11 +23,10 @@
 import static org.junit.Assert.fail;
 
 import static java.lang.reflect.Modifier.isFinal;
-import static java.lang.reflect.Modifier.isPrivate;
-import static java.lang.reflect.Modifier.isProtected;
 import static java.lang.reflect.Modifier.isPublic;
 import static java.lang.reflect.Modifier.isStatic;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AppGlobals;
 import android.content.IIntentReceiver;
@@ -63,7 +62,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.regex.Pattern;
 
@@ -101,7 +99,7 @@
                     @Nullable Bundle bOptions) {
             }
 
-            public void sendPackageAddedForNewUsers(String packageName,
+            public void sendPackageAddedForNewUsers(@NonNull Computer snapshot, String packageName,
                     boolean sendBootComplete, boolean includeStopped, int appId,
                     int[] userIds, int[] instantUserIds, int dataLoaderType) {
             }
@@ -456,147 +454,6 @@
         return null;
     }
 
-    // Return the boolean locked value.  A null return means the annotation was not
-    // found.  This method will fail if the annotation is found but is not one of the
-    // known constants.
-    private Boolean getOverride(Method m) {
-        final String name = "Computer." + displayName(m);
-        final Computer.LiveImplementation annotation =
-                m.getAnnotation(Computer.LiveImplementation.class);
-        if (annotation == null) {
-            return null;
-        }
-        final int override = annotation.override();
-        if (override == Computer.LiveImplementation.MANDATORY) {
-            return true;
-        } else if (override == Computer.LiveImplementation.NOT_ALLOWED) {
-            return false;
-        } else {
-            flag(name, "invalid Live value: " + override);
-            return null;
-        }
-    }
-
-    @Test
-    public void testComputerStructure() {
-        // Verify that Copmuter methods are properly annotated and that ComputerLocked is
-        // properly populated per annotations.
-        // Call PackageManagerService.validateComputer();
-        Class base = Computer.class;
-
-        HashMap<Method, Boolean> methodType = new HashMap<>();
-
-        // Verify that all Computer methods are annotated and that the annotation
-        // parameter locked() is valid.
-        for (Method m : base.getDeclaredMethods()) {
-            final String name = "Computer." + displayName(m);
-            Boolean override = getOverride(m);
-            if (override == null) {
-                flag(name, "missing required Live annotation");
-            }
-            methodType.put(m, override);
-        }
-
-        Class coreClass = ComputerEngine.class;
-        final Method[] coreMethods = coreClass.getDeclaredMethods();
-
-        // Examine every method in the core.  If it inherits from a base method it must be
-        // "public final" if the base is NOT_ALLOWED or "public" if the base is MANDATORY.
-        // If the core method does not inherit from the base then it must be either
-        // private or protected.
-        for (Method m : base.getDeclaredMethods()) {
-            String name = "Computer." + displayName(m);
-            final boolean locked = methodType.get(m);
-            final Method core = matchMethod(m, coreMethods);
-            if (core == null) {
-                flag(name, "not overridden in ComputerEngine");
-                continue;
-            }
-            name = "ComputerEngine." + displayName(m);
-            final int modifiers = core.getModifiers();
-            if (!locked) {
-                if (!isPublic(modifiers)) {
-                    flag(name, "is not public");
-                }
-                if (!isFinal(modifiers)) {
-                    flag(name, "is not final");
-                }
-            }
-        }
-        // Any methods left in the coreMethods array must be private or protected.
-        // Protected methods must be overridden (and final) in the live list.
-        Method[] coreHelpers = new Method[coreMethods.length];
-        int coreIndex = 0;
-        for (Method m : coreMethods) {
-            if (m != null) {
-                final String name = "ComputerEngine." + displayName(m);
-                if (name.contains(".lambda$static")) {
-                    // skip static lambda function
-                    continue;
-                }
-
-                final int modifiers = m.getModifiers();
-                if (isPrivate(modifiers)) {
-                    // Okay
-                } else if (isProtected(modifiers)) {
-                    coreHelpers[coreIndex++] = m;
-                } else {
-                    flag(name, "is neither private nor protected");
-                }
-            }
-        }
-
-        Class liveClass = ComputerLocked.class;
-        final Method[] liveMethods = liveClass.getDeclaredMethods();
-
-        // Examine every method in the live list.  Every method must be final and must
-        // inherit either from base or core.  If the method inherits from a base method
-        // then the base must be MANDATORY.
-        for (Method m : base.getDeclaredMethods()) {
-            String name = "Computer." + displayName(m);
-            final boolean locked = methodType.get(m);
-            final Method live = matchMethod(m, liveMethods);
-            if (live == null) {
-                if (locked) {
-                    flag(name, "not overridden in ComputerLocked");
-                }
-                continue;
-            }
-            if (!locked) {
-                flag(name, "improperly overridden in ComputerLocked");
-                continue;
-            }
-
-            name = "ComputerLocked." + displayName(m);
-            final int modifiers = live.getModifiers();
-            if (!locked) {
-                if (!isPublic(modifiers)) {
-                    flag(name, "is not public");
-                }
-                if (!isFinal(modifiers)) {
-                    flag(name, "is not final");
-                }
-            }
-        }
-        for (Method m : coreHelpers) {
-            if (m == null) {
-                continue;
-            }
-            String name = "ComputerLocked." + displayName(m);
-            final Method live = matchMethod(m, liveMethods);
-            if (live == null) {
-                flag(name, "is not overridden in ComputerLocked");
-                continue;
-            }
-        }
-        for (Method m : liveMethods) {
-            if (m != null) {
-                String name = "ComputerLocked." + displayName(m);
-                flag(name, "illegal local method");
-            }
-        }
-    }
-
     private static PerPackageReadTimeouts[] getPerPackageReadTimeouts(String knownDigestersList) {
         final String defaultTimeouts = "3600000001:3600000002:3600000003";
         List<PerPackageReadTimeouts> result = PerPackageReadTimeouts.parseDigestersList(
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 2b34bc2..f4ab3db 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -31,11 +31,11 @@
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.annotation.NonNull;
@@ -1103,6 +1103,59 @@
         assertThat(countDownLatch.getCount(), is(0L));
     }
 
+    @Test
+    public void testRegisterAndRemoveAppId() throws PackageManagerException {
+        // Test that the first new app UID should start from FIRST_APPLICATION_UID
+        final Settings settings = makeSettings();
+        final PackageSetting ps = createPackageSetting("com.foo");
+        assertTrue(settings.registerAppIdLPw(ps, false));
+        assertEquals(10000, ps.getAppId());
+        // Set up existing app IDs: 10000, 10001, 10003
+        final PackageSetting ps1 = createPackageSetting("com.foo1");
+        ps1.setAppId(10001);
+        final PackageSetting ps2 = createPackageSetting("com.foo2");
+        ps2.setAppId(10003);
+        final PackageSetting ps3 = createPackageSetting("com.foo3");
+        assertEquals(0, ps3.getAppId());
+        assertTrue(settings.registerAppIdLPw(ps1, false));
+        assertTrue(settings.registerAppIdLPw(ps2, false));
+        assertTrue(settings.registerAppIdLPw(ps3, false));
+        assertEquals(10001, ps1.getAppId());
+        assertEquals(10003, ps2.getAppId());
+        // Expecting the new one to start with the next available uid
+        assertEquals(10002, ps3.getAppId());
+        // Remove and insert a new one and the new one should not reuse the same uid
+        settings.removeAppIdLPw(10002);
+        final PackageSetting ps4 = createPackageSetting("com.foo4");
+        assertTrue(settings.registerAppIdLPw(ps4, false));
+        assertEquals(10004, ps4.getAppId());
+        // Keep adding more
+        final PackageSetting ps5 = createPackageSetting("com.foo5");
+        assertTrue(settings.registerAppIdLPw(ps5, false));
+        assertEquals(10005, ps5.getAppId());
+        // Remove the last one and the new one should use incremented uid
+        settings.removeAppIdLPw(10005);
+        final PackageSetting ps6 = createPackageSetting("com.foo6");
+        assertTrue(settings.registerAppIdLPw(ps6, false));
+        assertEquals(10006, ps6.getAppId());
+    }
+
+    /**
+     * Test replacing a PackageSetting with a SharedUserSetting in mAppIds
+     */
+    @Test
+    public void testAddPackageSetting() throws PackageManagerException {
+        final Settings settings = makeSettings();
+        final SharedUserSetting sus1 = new SharedUserSetting(
+                "TestUser", 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/);
+        sus1.mAppId = 10001;
+        final PackageSetting ps1 = createPackageSetting("com.foo");
+        ps1.setAppId(10001);
+        assertTrue(settings.registerAppIdLPw(ps1, false));
+        settings.addPackageSettingLPw(ps1, sus1);
+        assertSame(sus1, settings.getSharedUserSettingLPr(ps1));
+    }
+
     private void verifyUserState(PackageUserState userState,
             boolean notLaunched, boolean stopped, boolean installed) {
         assertThat(userState.getEnabledState(), is(0));
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index c7b5547..06b7112 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -316,7 +316,8 @@
                 asHandle(currentUser));
         try {
             assertThat(mUserManager.removeUserWhenPossible(user1.getUserHandle(),
-                    /* overrideDevicePolicy= */ false)).isEqualTo(UserManager.REMOVE_RESULT_ERROR);
+                    /* overrideDevicePolicy= */ false))
+                            .isEqualTo(UserManager.REMOVE_RESULT_ERROR_USER_RESTRICTION);
         } finally {
             mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_USER, /* value= */ false,
                     asHandle(currentUser));
@@ -353,7 +354,8 @@
     @Test
     public void testRemoveUserWhenPossible_systemUserReturnsError() throws Exception {
         assertThat(mUserManager.removeUserWhenPossible(UserHandle.SYSTEM,
-                /* overrideDevicePolicy= */ false)).isEqualTo(UserManager.REMOVE_RESULT_ERROR);
+                /* overrideDevicePolicy= */ false))
+                        .isEqualTo(UserManager.REMOVE_RESULT_ERROR_SYSTEM_USER);
 
         assertThat(hasUser(UserHandle.USER_SYSTEM)).isTrue();
     }
@@ -363,7 +365,8 @@
     public void testRemoveUserWhenPossible_invalidUserReturnsError() throws Exception {
         assertThat(hasUser(Integer.MAX_VALUE)).isFalse();
         assertThat(mUserManager.removeUserWhenPossible(UserHandle.of(Integer.MAX_VALUE),
-                /* overrideDevicePolicy= */ false)).isEqualTo(UserManager.REMOVE_RESULT_ERROR);
+                /* overrideDevicePolicy= */ false))
+                        .isEqualTo(UserManager.REMOVE_RESULT_ERROR_USER_NOT_FOUND);
     }
 
     @MediumTest
diff --git a/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java
index 1442f1c..83139b0 100644
--- a/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java
@@ -23,9 +23,11 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.argThat;
 import static org.mockito.Mockito.eq;
@@ -37,6 +39,7 @@
 import android.Manifest;
 import android.app.ActivityManagerInternal;
 import android.app.StatusBarManager;
+import android.compat.testing.PlatformCompatChangeRule;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.om.IOverlayManager;
@@ -62,10 +65,13 @@
 import com.android.server.policy.GlobalActionsProvider;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
+import libcore.junit.util.compat.CoreCompatChangeRule;
+
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 import org.mockito.ArgumentCaptor;
@@ -73,6 +79,7 @@
 import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
 
 @RunWith(JUnit4.class)
 public class StatusBarManagerServiceTest {
@@ -88,6 +95,9 @@
     public final TestableContext mContext =
             new NoBroadcastContextWrapper(InstrumentationRegistry.getContext());
 
+    @Rule
+    public TestRule mCompatChangeRule = new PlatformCompatChangeRule();
+
     @Mock
     private ActivityTaskManagerInternal mActivityTaskManagerInternal;
     @Mock
@@ -127,6 +137,7 @@
 
         when(mMockStatusBar.asBinder()).thenReturn(mMockStatusBar);
         when(mApplicationInfo.loadLabel(any())).thenReturn(APP_NAME);
+        mockHandleIncomingUser();
 
         mStatusBarManagerService = new StatusBarManagerService(mContext);
         LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
@@ -142,6 +153,80 @@
     }
 
     @Test
+    @CoreCompatChangeRule.EnableCompatChanges(
+            {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+    public void testRequestActive_changeEnabled_OKCall() throws RemoteException {
+        int user = 0;
+        mockEverything(user);
+        mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user);
+
+        verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+    }
+
+    @Test
+    @CoreCompatChangeRule.EnableCompatChanges(
+            {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+    public void testRequestActive_changeEnabled_differentPackage_fail() throws RemoteException {
+        when(mPackageManagerInternal.getPackageUid(TEST_PACKAGE, 0L, mContext.getUserId()))
+                .thenReturn(Binder.getCallingUid() + 1);
+        try {
+            mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, 0);
+            fail("Should cause security exception");
+        } catch (SecurityException e) { }
+        verify(mMockStatusBar, never()).requestTileServiceListeningState(TEST_COMPONENT);
+    }
+
+    @Test
+    @CoreCompatChangeRule.EnableCompatChanges(
+            {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+    public void testRequestActive_changeEnabled_notCurrentUser_fail() throws RemoteException {
+        mockUidCheck();
+        int user = 0;
+        mockCurrentUserCheck(user);
+        try {
+            mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user + 1);
+            fail("Should cause illegal argument exception");
+        } catch (IllegalArgumentException e) { }
+
+        // Do not call into SystemUI
+        verify(mMockStatusBar, never()).requestTileServiceListeningState(TEST_COMPONENT);
+    }
+
+    @Test
+    @CoreCompatChangeRule.DisableCompatChanges(
+            {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+    public void testRequestActive_changeDisabled_pass() throws RemoteException {
+        int user = 0;
+        mockEverything(user);
+        mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user);
+
+        verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+    }
+
+    @Test
+    @CoreCompatChangeRule.DisableCompatChanges(
+            {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+    public void testRequestActive_changeDisabled_differentPackage_pass() throws RemoteException {
+        when(mPackageManagerInternal.getPackageUid(TEST_PACKAGE, 0L, mContext.getUserId()))
+                .thenReturn(Binder.getCallingUid() + 1);
+        mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, 0);
+
+        verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+    }
+
+    @Test
+    @CoreCompatChangeRule.DisableCompatChanges(
+            {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+    public void testRequestActive_changeDisabled_notCurrentUser_pass() throws RemoteException {
+        mockUidCheck();
+        int user = 0;
+        mockCurrentUserCheck(user);
+        mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user + 1);
+
+        verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+    }
+
+    @Test
     public void testHandleIncomingUserCalled() {
         int fakeUser = 17;
         try {
@@ -252,7 +337,7 @@
         mockCurrentUserCheck(user);
         IntentMatcher im = new IntentMatcher(
                 new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
-        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
                 eq(user), anyInt())).thenReturn(null);
 
         Callback callback = new Callback();
@@ -272,7 +357,7 @@
 
         IntentMatcher im = new IntentMatcher(
                 new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
-        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
                 eq(user), anyInt())).thenReturn(r);
         when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
                 Binder.getCallingUid(), user)).thenReturn(
@@ -294,7 +379,7 @@
 
         IntentMatcher im = new IntentMatcher(
                 new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
-        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
                 eq(user), anyInt())).thenReturn(r);
         when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
                 Binder.getCallingUid(), user)).thenReturn(
@@ -318,7 +403,7 @@
 
         IntentMatcher im = new IntentMatcher(
                 new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
-        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
                 eq(user), anyInt())).thenReturn(r);
         when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
                 Binder.getCallingUid(), user)).thenReturn(
@@ -342,7 +427,7 @@
 
         IntentMatcher im = new IntentMatcher(
                 new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
-        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
                 eq(user), anyInt())).thenReturn(r);
         when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
                 Binder.getCallingUid(), user)).thenReturn(
@@ -607,23 +692,12 @@
     public void testSetNavBarMode_invalidInputThrowsError() throws RemoteException {
         int navBarModeInvalid = -1;
 
-        assertThrows(UnsupportedOperationException.class,
+        assertThrows(IllegalArgumentException.class,
                 () -> mStatusBarManagerService.setNavBarMode(navBarModeInvalid));
         verify(mOverlayManager, never()).setEnabledExclusiveInCategory(anyString(), anyInt());
     }
 
     @Test
-    public void testSetNavBarMode_noOverlayManagerDoesNotEnable() throws RemoteException {
-        mOverlayManager = null;
-        int navBarModeKids = StatusBarManager.NAV_BAR_MODE_KIDS;
-
-        mStatusBarManagerService.setNavBarMode(navBarModeKids);
-
-        assertEquals(navBarModeKids, mStatusBarManagerService.getNavBarMode());
-        verify(mOverlayManager, never()).setEnabledExclusiveInCategory(anyString(), anyInt());
-    }
-
-    @Test
     public void testSetNavBarMode_noPackageDoesNotEnable() throws Exception {
         mContext.setMockPackageManager(mPackageManager);
         when(mPackageManager.getPackageInfo(anyString(),
@@ -641,7 +715,7 @@
     }
 
     private void mockUidCheck(String packageName) {
-        when(mPackageManagerInternal.getPackageUid(eq(packageName), anyInt(), anyInt()))
+        when(mPackageManagerInternal.getPackageUid(eq(packageName), anyLong(), anyInt()))
                 .thenReturn(Binder.getCallingUid());
     }
 
@@ -667,7 +741,7 @@
 
         IntentMatcher im = new IntentMatcher(
                 new Intent(TileService.ACTION_QS_TILE).setComponent(componentName));
-        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+        when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
                 eq(user), anyInt())).thenReturn(r);
         when(mPackageManagerInternal.getComponentEnabledSetting(componentName,
                 Binder.getCallingUid(), user)).thenReturn(
@@ -679,6 +753,15 @@
                 PROCESS_STATE_TOP);
     }
 
+    private void mockHandleIncomingUser() {
+        when(mActivityManagerInternal.handleIncomingUser(anyInt(), anyInt(), anyInt(), anyBoolean(),
+                anyInt(), anyString(), anyString())).thenAnswer(
+                    (Answer<Integer>) invocation -> {
+                        return invocation.getArgument(2); // same user
+                    }
+        );
+    }
+
     private void mockEverything(int user) {
         mockUidCheck();
         mockCurrentUserCheck(user);
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 18d3f3d..210d2fa 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -62,7 +62,10 @@
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.intThat;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -76,11 +79,13 @@
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
+import android.content.pm.ResolveInfo;
 import android.hardware.display.DisplayManager;
 import android.os.Handler;
 import android.os.Looper;
@@ -118,6 +123,7 @@
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  * Unit test for AppStandbyController.
@@ -421,8 +427,31 @@
         pib.packageName = PACKAGE_BACKGROUND_LOCATION;
         packages.add(pib);
 
-        doReturn(packages).when(mockPm).getInstalledPackagesAsUser(anyInt(), anyInt());
 
+        // Set up getInstalledPackagesAsUser().
+        doReturn(packages).when(mockPm).getInstalledPackagesAsUser(anyInt(),
+                anyInt());
+
+        // Set up getInstalledPackagesAsUser() for "MATCH_ONLY_SYSTEM"
+        doReturn(
+                packages.stream().filter(pinfo -> pinfo.applicationInfo.isSystemApp())
+                .collect(Collectors.toList())
+        ).when(mockPm).getInstalledPackagesAsUser(
+                intThat(i -> (i & PackageManager.MATCH_SYSTEM_ONLY) != 0),
+                anyInt());
+
+        // Set up queryIntentActivitiesAsUser()
+        final ArrayList<ResolveInfo> systemFrontDoorActivities = new ArrayList<>();
+        final ResolveInfo frontDoorActivity = new ResolveInfo();
+        frontDoorActivity.activityInfo = new ActivityInfo();
+        frontDoorActivity.activityInfo.packageName = pis.packageName;
+        systemFrontDoorActivities.add(frontDoorActivity);
+        doReturn(systemFrontDoorActivities).when(mockPm)
+                .queryIntentActivitiesAsUser(any(Intent.class),
+                intThat(i -> (i & PackageManager.MATCH_SYSTEM_ONLY) != 0),
+                anyInt());
+
+        // Set up other APIs.
         try {
             for (int i = 0; i < packages.size(); ++i) {
                 PackageInfo pkg = packages.get(i);
@@ -489,6 +518,7 @@
 
     @Before
     public void setUp() throws Exception {
+        LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
         LocalServices.addService(
                 UsageStatsManagerInternal.class, mock(UsageStatsManagerInternal.class));
         MyContextWrapper myContext = new MyContextWrapper(InstrumentationRegistry.getContext());
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
index 3cda2a5..ec16188 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -288,7 +288,7 @@
     }
 
     @Test
-    public void shouldIgnoreVibration_withRingerModeSilent_ignoresRingtoneOnly() {
+    public void shouldIgnoreVibration_withRingerModeSilent_ignoresRingtoneAndNotification() {
         // Vibrating settings on are overruled by ringer mode.
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED, 1);
         setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
@@ -296,7 +296,7 @@
         setRingerMode(AudioManager.RINGER_MODE_SILENT);
 
         for (int usage : ALL_USAGES) {
-            if (usage == USAGE_RINGTONE) {
+            if (usage == USAGE_RINGTONE || usage == USAGE_NOTIFICATION) {
                 assertVibrationIgnoredForUsage(usage, Vibration.Status.IGNORED_FOR_RINGER_MODE);
             } else {
                 assertVibrationNotIgnoredForUsage(usage);
@@ -305,6 +305,16 @@
     }
 
     @Test
+    public void shouldIgnoreVibration_withRingerModeSilentAndBypassFlag_allowsAllVibrations() {
+        setRingerMode(AudioManager.RINGER_MODE_SILENT);
+
+        for (int usage : ALL_USAGES) {
+            assertVibrationNotIgnoredForUsageAndFlags(usage,
+                    VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY);
+        }
+    }
+
+    @Test
     public void shouldIgnoreVibration_withRingerModeVibrate_allowsAllVibrations() {
         setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
 
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index e46e281..92736c5 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -1136,19 +1136,23 @@
     }
 
     @Test
-    public void onExternalVibration_setsExternalControl() {
+    public void onExternalVibration_setsExternalControl() throws Exception {
         mockVibrators(1);
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
         createSystemReadyService();
 
+        IBinder binderToken = mock(IBinder.class);
         ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, AUDIO_ATTRS,
-                mock(IExternalVibrationController.class));
+                mock(IExternalVibrationController.class), binderToken);
         int scale = mExternalVibratorService.onExternalVibrationStart(externalVibration);
         mExternalVibratorService.onExternalVibrationStop(externalVibration);
 
         assertNotEquals(IExternalVibratorService.SCALE_MUTE, scale);
         assertEquals(Arrays.asList(false, true, false),
                 mVibratorProviders.get(1).getExternalControlStates());
+
+        verify(binderToken).linkToDeath(any(), eq(0));
+        verify(binderToken).unlinkToDeath(any(), eq(0));
     }
 
     @Test
@@ -1160,17 +1164,19 @@
         setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
         createSystemReadyService();
 
+        IBinder firstToken = mock(IBinder.class);
+        IBinder secondToken = mock(IBinder.class);
         IExternalVibrationController firstController = mock(IExternalVibrationController.class);
         IExternalVibrationController secondController = mock(IExternalVibrationController.class);
         ExternalVibration firstVibration = new ExternalVibration(UID, PACKAGE_NAME, AUDIO_ATTRS,
-                firstController);
+                firstController, firstToken);
         int firstScale = mExternalVibratorService.onExternalVibrationStart(firstVibration);
 
         AudioAttributes ringtoneAudioAttrs = new AudioAttributes.Builder()
                 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
                 .build();
         ExternalVibration secondVibration = new ExternalVibration(UID, PACKAGE_NAME,
-                ringtoneAudioAttrs, secondController);
+                ringtoneAudioAttrs, secondController, secondToken);
         int secondScale = mExternalVibratorService.onExternalVibrationStart(secondVibration);
 
         assertNotEquals(IExternalVibratorService.SCALE_MUTE, firstScale);
@@ -1180,6 +1186,17 @@
         // Set external control called only once.
         assertEquals(Arrays.asList(false, true),
                 mVibratorProviders.get(1).getExternalControlStates());
+
+        mExternalVibratorService.onExternalVibrationStop(secondVibration);
+        mExternalVibratorService.onExternalVibrationStop(firstVibration);
+        assertEquals(Arrays.asList(false, true, false),
+                mVibratorProviders.get(1).getExternalControlStates());
+
+        verify(firstToken).linkToDeath(any(), eq(0));
+        verify(firstToken).unlinkToDeath(any(), eq(0));
+
+        verify(secondToken).linkToDeath(any(), eq(0));
+        verify(secondToken).unlinkToDeath(any(), eq(0));
     }
 
     @Test
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 71f8b8d..67382bf 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_IGNORED;
 import static android.app.Notification.FLAG_AUTO_CANCEL;
@@ -432,8 +433,8 @@
         when(mUgmInternal.newUriPermissionOwner(anyString())).thenReturn(mPermOwner);
         when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG});
         when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{PKG});
-        when(mPermissionPolicyInternal.canShowPermissionPromptForTask(
-                any(ActivityManager.RecentTaskInfo.class))).thenReturn(false);
+        when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt()))
+                .thenReturn(INVALID_TASK_ID);
         mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
         when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0});
 
@@ -971,8 +972,7 @@
     @Test
     public void testCreateNotificationChannels_FirstChannelWithFgndTaskStartsPermDialog()
             throws Exception {
-        when(mPermissionPolicyInternal.canShowPermissionPromptForTask(any(
-                ActivityManager.RecentTaskInfo.class))).thenReturn(true);
+        when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt())).thenReturn(TEST_TASK_ID);
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
         mBinderService.createNotificationChannels(PKG_NO_CHANNELS,
@@ -985,8 +985,7 @@
     @Test
     public void testCreateNotificationChannels_SecondChannelWithFgndTaskDoesntStartPermDialog()
             throws Exception {
-        when(mPermissionPolicyInternal.canShowPermissionPromptForTask(any(
-                ActivityManager.RecentTaskInfo.class))).thenReturn(true);
+        when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt())).thenReturn(TEST_TASK_ID);
         assertTrue(mBinderService.getNumNotificationChannelsForPackage(PKG, mUid, true) > 0);
 
         final NotificationChannel channel =
@@ -1001,8 +1000,7 @@
     public void testCreateNotificationChannels_FirstChannelWithBgndTaskDoesntStartPermDialog()
             throws Exception {
         reset(mPermissionPolicyInternal);
-        when(mPermissionPolicyInternal.canShowPermissionPromptForTask(any(
-                ActivityManager.RecentTaskInfo.class))).thenReturn(false);
+        when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt())).thenReturn(TEST_TASK_ID);
 
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
@@ -2707,13 +2705,10 @@
     @Test
     public void testUpdateAppNotifyCreatorBlock() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-
-        // should not trigger a broadcast
-        when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_IGNORED);
-        mService.mAppOpsCallback.opChanged(0, mUid, PKG);
+        when(mPreferencesHelper.getImportance(PKG, mUid)).thenReturn(IMPORTANCE_DEFAULT);
 
         // should trigger a broadcast
-        mBinderService.setNotificationsEnabledForPackage(PKG, 0, true);
+        mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
         Thread.sleep(500);
         waitForIdle();
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
@@ -2722,7 +2717,7 @@
         assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
                 captor.getValue().getAction());
         assertEquals(PKG, captor.getValue().getPackage());
-        assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
+        assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
     }
 
     @Test
@@ -2739,7 +2734,6 @@
 
         // should not trigger a broadcast
         when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_ALLOWED);
-        mService.mAppOpsCallback.opChanged(0, mUid, PKG);
 
         // should trigger a broadcast
         mBinderService.setNotificationsEnabledForPackage(PKG, 0, true);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
index a838872..2ba587d 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
@@ -606,9 +606,9 @@
 
     @Test
     public void testUpdateAppNotifyCreatorBlock() throws Exception {
-        when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_IGNORED);
+        when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
 
-        mService.mAppOpsCallback.opChanged(0, mUid, PKG);
+        mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
         Thread.sleep(500);
         waitForIdle();
 
@@ -618,14 +618,14 @@
         assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
                 captor.getValue().getAction());
         assertEquals(PKG, captor.getValue().getPackage());
-        assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
+        assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
     }
 
     @Test
     public void testUpdateAppNotifyCreatorUnblock() throws Exception {
-        when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_ALLOWED);
+        when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
 
-        mService.mAppOpsCallback.opChanged(0, mUid, PKG);
+        mBinderService.setNotificationsEnabledForPackage(PKG, mUid, true);
         Thread.sleep(500);
         waitForIdle();
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
index a24ba0d..46b47f4 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
@@ -88,7 +88,11 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true);
+        mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true, false);
+        PackageInfo testPkgInfo = new PackageInfo();
+        testPkgInfo.requestedPermissions = new String[]{ Manifest.permission.POST_NOTIFICATIONS };
+        when(mPackageManager.getPackageInfo(anyString(), anyLong(), anyInt()))
+                .thenReturn(testPkgInfo);
     }
 
     // TODO (b/194833441): Remove when the migration is enabled
@@ -96,7 +100,7 @@
     public void testMethodsThrowIfMigrationDisabled() throws IllegalAccessException,
             InvocationTargetException {
         PermissionHelper permHelper =
-                new PermissionHelper(mPmi, mPackageManager, mPermManager, false);
+                new PermissionHelper(mPmi, mPackageManager, mPermManager, false, false);
 
         Method[] allMethods = PermissionHelper.class.getDeclaredMethods();
         for (Method method : allMethods) {
@@ -298,6 +302,26 @@
     }
 
     @Test
+    public void testSetNotificationPermission_pkgPerm_grantedByDefaultPermSet_allUserSet()
+            throws Exception {
+        mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true, true);
+        when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+                .thenReturn(PERMISSION_DENIED);
+        when(mPermManager.getPermissionFlags(anyString(),
+                eq(Manifest.permission.POST_NOTIFICATIONS),
+                anyInt())).thenReturn(FLAG_PERMISSION_GRANTED_BY_DEFAULT);
+        PermissionHelper.PackagePermission pkgPerm = new PermissionHelper.PackagePermission(
+                "pkg", 10, true, false);
+
+        mPermissionHelper.setNotificationPermission(pkgPerm);
+        verify(mPermManager).grantRuntimePermission(
+                "pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
+        verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
+                FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_REVIEW_REQUIRED,
+                FLAG_PERMISSION_USER_SET, true, 10);
+    }
+
+    @Test
     public void testSetNotificationPermission_revokeUserSet() throws Exception {
         when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
                 .thenReturn(PERMISSION_GRANTED);
@@ -384,6 +408,22 @@
     }
 
     @Test
+    public void testSetNotificationPermission_doesntRequestNotChanged() throws Exception {
+        when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+                .thenReturn(PERMISSION_GRANTED);
+        PackageInfo testPkgInfo = new PackageInfo();
+        testPkgInfo.requestedPermissions = new String[]{ Manifest.permission.RECORD_AUDIO };
+        when(mPackageManager.getPackageInfo(anyString(), anyLong(), anyInt()))
+                .thenReturn(testPkgInfo);
+        mPermissionHelper.setNotificationPermission("pkg", 10, false, false);
+
+        verify(mPmi, never()).checkPermission(
+                eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10));
+        verify(mPermManager, never()).revokeRuntimePermission(
+                eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10), anyString());
+    }
+
+    @Test
     public void testIsPermissionFixed() throws Exception {
         when(mPermManager.getPermissionFlags(anyString(),
                 eq(Manifest.permission.POST_NOTIFICATIONS),
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 8f1eed8..7d5a0d0 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -1870,46 +1870,46 @@
     @Test
     public void testGetChannelsBypassingDndCount_noChannelsBypassing() throws Exception {
         assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
-                USER.getIdentifier()).getList().size());
+                UID_N_MR1).getList().size());
     }
 
     @Test
-    public void testGetChannelsBypassingDnd_noChannelsForUserIdBypassing()
+    public void testGetChannelsBypassingDnd_noChannelsForUidBypassing()
             throws Exception {
-        int user = 9;
+        int uid = 222;
         NotificationChannel channel = new NotificationChannel("id", "name",
                 NotificationManager.IMPORTANCE_MAX);
         channel.setBypassDnd(true);
         mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
 
         assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
-                user).getList().size());
+                uid).getList().size());
     }
 
     @Test
     public void testGetChannelsBypassingDndCount_oneChannelBypassing_groupBlocked() {
-        int user = USER.getIdentifier();
+        int uid = UID_N_MR1;
         NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
         NotificationChannel channel1 = new NotificationChannel("id1", "name1",
                 NotificationManager.IMPORTANCE_MAX);
         channel1.setBypassDnd(true);
         channel1.setGroup(ncg.getId());
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg,  /* fromTargetApp */ true);
-        mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg,  /* fromTargetApp */ true);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true);
 
         assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
-                user).getList().size());
+                uid).getList().size());
 
         // disable group
         ncg.setBlocked(true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, user, ncg,  /* fromTargetApp */ false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg,  /* fromTargetApp */ false);
         assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
-                user).getList().size());
+                uid).getList().size());
     }
 
     @Test
     public void testGetChannelsBypassingDndCount_multipleChannelsBypassing() {
-        int user = USER.getIdentifier();
+        int uid = UID_N_MR1;
         NotificationChannel channel1 = new NotificationChannel("id1", "name1",
                 NotificationManager.IMPORTANCE_MAX);
         NotificationChannel channel2 = new NotificationChannel("id2", "name2",
@@ -1920,22 +1920,22 @@
         channel2.setBypassDnd(true);
         channel3.setBypassDnd(true);
         // has DND access, so can set bypassDnd attribute
-        mHelper.createNotificationChannel(PKG_N_MR1, user, channel1, true, /*has DND access*/ true);
-        mHelper.createNotificationChannel(PKG_N_MR1, user, channel2, true, true);
-        mHelper.createNotificationChannel(PKG_N_MR1, user, channel3, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel3, true, true);
         assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
-                user).getList().size());
+                uid).getList().size());
 
         // setBypassDnd false for some channels
         channel1.setBypassDnd(false);
         channel2.setBypassDnd(false);
         assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
-                user).getList().size());
+                uid).getList().size());
 
         // setBypassDnd false for rest of the channels
         channel3.setBypassDnd(false);
         assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
-                user).getList().size());
+                uid).getList().size());
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
index abcc8c1..8ac729e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
@@ -121,7 +121,7 @@
 
     // Create a notification record with the people String array as the
     // bundled extras, and the numbers ArraySet as additional phone numbers.
-    private NotificationRecord getRecordWithPeopleInfo(String[] people,
+    private NotificationRecord getCallRecordWithPeopleInfo(String[] people,
             ArraySet<String> numbers) {
         // set up notification record
         NotificationRecord r = mock(NotificationRecord.class);
@@ -131,6 +131,8 @@
         when(sbn.getNotification()).thenReturn(notification);
         when(r.getSbn()).thenReturn(sbn);
         when(r.getPhoneNumbers()).thenReturn(numbers);
+        when(r.getCriticality()).thenReturn(CriticalNotificationExtractor.NORMAL);
+        when(r.isCategory(CATEGORY_CALL)).thenReturn(true);
         return r;
     }
 
@@ -350,11 +352,41 @@
     }
 
     @Test
+    public void testRepeatCallers_checksPhoneNumbers() {
+        // set up telephony manager behavior
+        when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
+
+        // first, record a phone call from a telephone number
+        String[] callNumber = new String[]{"tel:12345678910"};
+        mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(callNumber, null));
+
+        // set up policy to only allow repeat callers
+        Policy policy = new Policy(
+                PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE);
+
+        // make sure that a record with the phone number in extras is correctly allowed through
+        NotificationRecord r = getCallRecordWithPeopleInfo(callNumber, null);
+        assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
+
+        // make sure that a record with the phone number in the phone numbers array is also
+        // allowed through
+        NotificationRecord r2 = getCallRecordWithPeopleInfo(new String[]{"some_contact_uri"},
+                new ArraySet<>(new String[]{"12345678910"}));
+        assertFalse(mZenModeFiltering.shouldIntercept(
+                ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r2));
+
+        // A record with the phone number in neither of the above should be intercepted
+        NotificationRecord r3 = getCallRecordWithPeopleInfo(new String[]{"tel:10987654321"},
+                new ArraySet<>(new String[]{"15555555555"}));
+        assertTrue(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r3));
+    }
+
+    @Test
     public void testMatchesCallFilter_repeatCallers_directMatch() {
         // after calls given an email with an exact string match, make sure that
         // matchesCallFilter returns the right thing
         String[] mailSource = new String[]{"mailto:hello.world"};
-        mZenModeFiltering.recordCall(getRecordWithPeopleInfo(mailSource, null));
+        mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(mailSource, null));
 
         // set up policy to only allow repeat callers
         Policy policy = new Policy(
@@ -377,7 +409,7 @@
         when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
 
         String[] telSource = new String[]{"tel:+1-617-555-1212"};
-        mZenModeFiltering.recordCall(getRecordWithPeopleInfo(telSource, null));
+        mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(telSource, null));
 
         // set up policy to only allow repeat callers
         Policy policy = new Policy(
@@ -421,7 +453,7 @@
         when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
 
         String[] telSource = new String[]{"tel:%2B16175551212"};
-        mZenModeFiltering.recordCall(getRecordWithPeopleInfo(telSource, null));
+        mZenModeFiltering.recordCall(getCallRecordWithPeopleInfo(telSource, null));
 
         // set up policy to only allow repeat callers
         Policy policy = new Policy(
@@ -468,7 +500,7 @@
         String[] contactSource = new String[]{"content://contacts/lookup/uri-here"};
         ArraySet<String> contactNumbers = new ArraySet<>(
                 new String[]{"1-617-555-1212", "1-617-555-3434"});
-        NotificationRecord record = getRecordWithPeopleInfo(contactSource, contactNumbers);
+        NotificationRecord record = getCallRecordWithPeopleInfo(contactSource, contactNumbers);
         record.mergePhoneNumbers(contactNumbers);
         mZenModeFiltering.recordCall(record);
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 31be33e..fd1536c 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -43,6 +43,7 @@
 import static com.android.os.AtomsProto.DNDModeProto.ID_FIELD_NUMBER;
 import static com.android.os.AtomsProto.DNDModeProto.UID_FIELD_NUMBER;
 import static com.android.os.AtomsProto.DNDModeProto.ZEN_MODE_FIELD_NUMBER;
+import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
@@ -1611,6 +1612,35 @@
     }
 
     @Test
+    public void testAddAutomaticZenRule_beyondSystemLimit() {
+        for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) {
+            ScheduleInfo si = new ScheduleInfo();
+            si.startHour = i;
+            AutomaticZenRule zenRule = new AutomaticZenRule("name" + i,
+                    null,
+                    new ComponentName("android", "ScheduleConditionProvider"),
+                    ZenModeConfig.toScheduleConditionId(si),
+                    new ZenPolicy.Builder().build(),
+                    NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+            String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
+            assertNotNull(id);
+        }
+        try {
+            AutomaticZenRule zenRule = new AutomaticZenRule("name",
+                    null,
+                    new ComponentName("android", "ScheduleConditionProvider"),
+                    ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+                    new ZenPolicy.Builder().build(),
+                    NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+            String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
+            fail("allowed too many rules to be created");
+        } catch (IllegalArgumentException e) {
+            // yay
+        }
+
+    }
+
+    @Test
     public void testAddAutomaticZenRule_CA() {
         AutomaticZenRule zenRule = new AutomaticZenRule("name",
                 null,
diff --git a/services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java b/services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java
index 75479de..cf57181 100644
--- a/services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java
@@ -36,6 +36,9 @@
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Test class for {@link KeyCombinationManager}.
  *
@@ -47,16 +50,18 @@
 public class KeyCombinationTests {
     private KeyCombinationManager mKeyCombinationManager;
 
-    private boolean mAction1Triggered = false;
-    private boolean mAction2Triggered = false;
-    private boolean mAction3Triggered = false;
+    private final CountDownLatch mAction1Triggered = new CountDownLatch(1);
+    private final CountDownLatch mAction2Triggered = new CountDownLatch(1);
+    private final CountDownLatch mAction3Triggered = new CountDownLatch(1);
 
     private boolean mPreCondition = true;
     private static final long SCHEDULE_TIME = 300;
+    private Handler mHandler;
 
     @Before
     public void setUp() {
-        mKeyCombinationManager = new KeyCombinationManager();
+        mHandler = new Handler(Looper.getMainLooper());
+        mKeyCombinationManager = new KeyCombinationManager(mHandler);
         initKeyCombinationRules();
     }
 
@@ -67,7 +72,7 @@
                         KEYCODE_POWER) {
                     @Override
                     void execute() {
-                        mAction1Triggered = true;
+                        mAction1Triggered.countDown();
                     }
 
                     @Override
@@ -86,12 +91,17 @@
 
                     @Override
                     void execute() {
-                        mAction2Triggered = true;
+                        mAction2Triggered.countDown();
                     }
 
                     @Override
                     void cancel() {
                     }
+
+                    @Override
+                    long getKeyInterceptDelayMs() {
+                        return 0;
+                    }
                 });
 
         // Rule 3 : power + volume_up schedule and trigger action after timeout.
@@ -100,10 +110,9 @@
                     final Runnable mAction = new Runnable() {
                         @Override
                         public void run() {
-                            mAction3Triggered = true;
+                            mAction3Triggered.countDown();
                         }
                     };
-                    final Handler mHandler = new Handler(Looper.getMainLooper());
 
                     @Override
                     void execute() {
@@ -149,60 +158,74 @@
     }
 
     @Test
-    public void testTriggerRule() {
+    public void testTriggerRule() throws InterruptedException {
         final long eventTime = SystemClock.uptimeMillis();
         pressKeys(eventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_DOWN);
-        assertTrue(mAction1Triggered);
+        assertTrue(mAction1Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
 
         pressKeys(eventTime, KEYCODE_VOLUME_UP, eventTime, KEYCODE_VOLUME_DOWN);
-        assertTrue(mAction2Triggered);
+        assertTrue(mAction2Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
 
         pressKeys(eventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_UP, SCHEDULE_TIME + 50);
-        assertTrue(mAction3Triggered);
+        assertTrue(mAction3Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
     }
 
     /**
      *  Nothing should happen if there is no definition.
      */
     @Test
-    public void testNotTrigger_NoRule() {
+    public void testNotTrigger_NoRule() throws InterruptedException {
         final long eventTime = SystemClock.uptimeMillis();
         pressKeys(eventTime, KEYCODE_BACK, eventTime, KEYCODE_VOLUME_DOWN);
-        assertFalse(mAction1Triggered);
-        assertFalse(mAction2Triggered);
-        assertFalse(mAction3Triggered);
+        assertFalse(mAction1Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
+        assertFalse(mAction2Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
+        assertFalse(mAction3Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
     }
 
     /**
      *  Nothing should happen if the interval of press time is too long.
      */
     @Test
-    public void testNotTrigger_Interval() {
+    public void testNotTrigger_Interval() throws InterruptedException {
         final long eventTime = SystemClock.uptimeMillis();
         final long earlyEventTime = eventTime - 200; // COMBINE_KEY_DELAY_MILLIS = 150;
         pressKeys(earlyEventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_DOWN);
-        assertFalse(mAction1Triggered);
+        assertFalse(mAction1Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
     }
 
     /**
      *  Nothing should happen if the condition is false.
      */
     @Test
-    public void testNotTrigger_Condition() {
+    public void testNotTrigger_Condition() throws InterruptedException {
         final long eventTime = SystemClock.uptimeMillis();
         // we won't trigger action 2 because the condition is false.
         mPreCondition = false;
         pressKeys(eventTime, KEYCODE_VOLUME_UP, eventTime, KEYCODE_VOLUME_DOWN);
-        assertFalse(mAction2Triggered);
+        assertFalse(mAction2Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
     }
 
     /**
      *  Nothing should happen if the keys released too early.
      */
     @Test
-    public void testNotTrigger_EarlyRelease() {
+    public void testNotTrigger_EarlyRelease() throws InterruptedException {
         final long eventTime = SystemClock.uptimeMillis();
         pressKeys(eventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_UP);
-        assertFalse(mAction3Triggered);
+        assertFalse(mAction3Triggered.await(SCHEDULE_TIME, TimeUnit.MILLISECONDS));
     }
-}
+
+    /**
+     *  The KeyInterceptTimeout should return the max timeout value.
+     */
+    @Test
+    public void testKeyInterceptTimeout() {
+        final long eventTime = SystemClock.uptimeMillis();
+        final KeyEvent firstKeyDown = new KeyEvent(eventTime, eventTime, ACTION_DOWN,
+                KEYCODE_VOLUME_UP, 0 /* repeat */, 0 /* metaState */);
+        // Press KEYCODE_VOLUME_UP would activate rule2 and rule3,
+        // and rule2's intercept delay is 0.
+        mKeyCombinationManager.interceptKey(firstKeyDown, true);
+        assertTrue(mKeyCombinationManager.getKeyInterceptTimeout(KEYCODE_VOLUME_UP) > eventTime);
+    }
+}
\ No newline at end of file
diff --git a/services/tests/wmtests/src/com/android/server/policy/OWNERS b/services/tests/wmtests/src/com/android/server/policy/OWNERS
new file mode 100644
index 0000000..27891dc
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/policy/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/policy/OWNERS
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index d4d8b868..7689e08 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -256,6 +256,14 @@
         mActivityMetricsLogger.notifyVisibilityChanged(noDrawnActivity);
 
         verifyAsync(mLaunchObserver).onActivityLaunchCancelled(eqProto(noDrawnActivity));
+
+        // If an activity is removed immediately before visibility update, it should cancel too.
+        final ActivityRecord removedImm = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        clearInvocations(mLaunchObserver);
+        onActivityLaunched(removedImm);
+        removedImm.removeImmediately();
+        // Verify any() instead of proto because the field of record may be changed.
+        verifyAsync(mLaunchObserver).onActivityLaunchCancelled(any());
     }
 
     @Test
@@ -299,15 +307,16 @@
     @Test
     public void testOnReportFullyDrawn() {
         // Create an invisible event that should be cancelled after the next event starts.
-        onActivityLaunched(mTrampolineActivity);
-        mTrampolineActivity.mVisibleRequested = false;
+        final ActivityRecord prev = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        onActivityLaunched(prev);
+        prev.mVisibleRequested = false;
 
         mActivityOptions = ActivityOptions.makeBasic();
         mActivityOptions.setSourceInfo(SourceInfo.TYPE_LAUNCHER, SystemClock.uptimeMillis() - 10);
         onIntentStarted(mTopActivity.intent);
         notifyActivityLaunched(START_SUCCESS, mTopActivity);
         verifyAsync(mLaunchObserver).onActivityLaunched(eqProto(mTopActivity), anyInt());
-        verifyAsync(mLaunchObserver).onActivityLaunchCancelled(eqProto(mTrampolineActivity));
+        verifyAsync(mLaunchObserver).onActivityLaunchCancelled(eqProto(prev));
 
         // The activity reports fully drawn before windows drawn, then the fully drawn event will
         // be pending (see {@link WindowingModeTransitionInfo#pendingFullyDrawn}).
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 a89c5a1..f8e15041 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2184,11 +2184,17 @@
 
     @Test
     public void testSupportsPictureInPicture() {
+        final Task task = new TaskBuilder(mSupervisor)
+                .setDisplay(mDisplayContent).build();
         final ActivityRecord activity = new ActivityBuilder(mAtm)
-                .setCreateTask(true)
+                .setTask(task)
                 .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
                 .setActivityFlags(FLAG_SUPPORTS_PICTURE_IN_PICTURE)
                 .build();
+        spyOn(mDisplayContent);
+        spyOn(mDisplayContent.mDwpcHelper);
+        doReturn(true).when(mDisplayContent.mDwpcHelper).isWindowingModeSupported(
+                WINDOWING_MODE_PINNED);
 
         // Device not supports PIP
         mAtm.mSupportsPictureInPicture = false;
@@ -2201,6 +2207,15 @@
         // Activity not supports PIP
         activity.info.flags &= ~FLAG_SUPPORTS_PICTURE_IN_PICTURE;
         assertFalse(activity.supportsPictureInPicture());
+
+        // Activity supports PIP
+        activity.info.flags |= FLAG_SUPPORTS_PICTURE_IN_PICTURE;
+        assertTrue(activity.supportsPictureInPicture());
+
+        // Display not supports PIP
+        doReturn(false).when(mDisplayContent.mDwpcHelper).isWindowingModeSupported(
+                WINDOWING_MODE_PINNED);
+        assertFalse(activity.supportsPictureInPicture());
     }
 
     @Test
@@ -2217,6 +2232,19 @@
         assertTrue(activity.pictureInPictureArgs.isLaunchIntoPip());
     }
 
+    @Test
+    public void testTransferLaunchCookieWhenFinishing() {
+        final ActivityRecord activity1 = createActivityWithTask();
+        final Binder launchCookie = new Binder();
+        activity1.mLaunchCookie = launchCookie;
+        final ActivityRecord activity2 = createActivityRecord(activity1.getTask());
+        activity1.setState(PAUSED, "test");
+        activity1.makeFinishingLocked();
+
+        assertEquals(launchCookie, activity2.mLaunchCookie);
+        assertNull(activity1.mLaunchCookie);
+    }
+
     private void verifyProcessInfoUpdate(ActivityRecord activity, State state,
             boolean shouldUpdate, boolean activityChange) {
         reset(activity.app);
@@ -3073,11 +3101,11 @@
 
         // 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);
+        assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
         imeSource.setFrame(new Rect(100, 400, 500, 500));
         app.getInsetsState().addSource(imeSource);
         app.getInsetsState().setSourceVisible(ITYPE_IME, true);
-        mDisplayContent.updateImeInputAndControlTarget(app);
-        assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
 
         // 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/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
index 0c8394e..24ff3f9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
@@ -41,9 +41,11 @@
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
@@ -58,8 +60,6 @@
 import com.android.internal.app.UnlaunchableAppActivity;
 import com.android.server.LocalServices;
 import com.android.server.am.ActivityManagerService;
-import com.android.server.pm.PackageManagerService;
-import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult;
 
 import org.junit.After;
 import org.junit.Before;
@@ -113,7 +113,7 @@
     @Mock
     private KeyguardManager mKeyguardManager;
     @Mock
-    private PackageManagerService mPackageManager;
+    private IPackageManager mPackageManager;
     @Mock
     private ActivityManagerInternal mAmInternal;
     @Mock
@@ -126,7 +126,7 @@
             new SparseArray<>();
 
     @Before
-    public void setUp() {
+    public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
         mService.mAmInternal = mAmInternal;
         mInterceptor = new ActivityStartInterceptor(
@@ -279,7 +279,7 @@
     }
 
     @Test
-    public void testHarmfulAppWarning() {
+    public void testHarmfulAppWarning() throws RemoteException {
         // GIVEN the package we're about to launch has a harmful app warning set
         when(mPackageManager.getHarmfulAppWarning(TEST_PACKAGE_NAME, TEST_USER_ID))
                 .thenReturn("This app is bad");
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 6fe2d33..f9aa4b1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -308,12 +308,12 @@
     }
 
     private ActivityStarter prepareStarter(@Intent.Flags int launchFlags) {
-        return prepareStarter(launchFlags, true /* mockGetLaunchStack */, LAUNCH_MULTIPLE);
+        return prepareStarter(launchFlags, true /* mockGetRootTask */, LAUNCH_MULTIPLE);
     }
 
     private ActivityStarter prepareStarter(@Intent.Flags int launchFlags,
-            boolean mockGetLaunchStack) {
-        return prepareStarter(launchFlags, mockGetLaunchStack, LAUNCH_MULTIPLE);
+            boolean mockGetRootTask) {
+        return prepareStarter(launchFlags, mockGetRootTask, LAUNCH_MULTIPLE);
     }
 
     private void setupImeWindow() {
@@ -326,20 +326,20 @@
      * Creates a {@link ActivityStarter} with default parameters and necessary mocks.
      *
      * @param launchFlags The intent flags to launch activity.
-     * @param mockGetLaunchStack Whether to mock {@link RootWindowContainer#getLaunchRootTask} for
+     * @param mockGetRootTask Whether to mock {@link RootWindowContainer#getOrCreateRootTask} for
      *                           always launching to the testing stack. Set to false when allowing
      *                           the activity can be launched to any stack that is decided by real
      *                           implementation.
      * @return A {@link ActivityStarter} with default setup.
      */
     private ActivityStarter prepareStarter(@Intent.Flags int launchFlags,
-            boolean mockGetLaunchStack, int launchMode) {
+            boolean mockGetRootTask, int launchMode) {
         // always allow test to start activity.
         doReturn(true).when(mSupervisor).checkStartAnyActivityPermission(
                 any(), any(), any(), anyInt(), anyInt(), anyInt(), any(), any(),
                 anyBoolean(), anyBoolean(), any(), any(), any());
 
-        if (mockGetLaunchStack) {
+        if (mockGetRootTask) {
             // Instrument the stack and task used.
             final Task stack = mRootWindowContainer.getDefaultTaskDisplayArea()
                     .createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
@@ -347,9 +347,9 @@
 
             // Direct starter to use spy stack.
             doReturn(stack).when(mRootWindowContainer)
-                    .getLaunchRootTask(any(), any(), any(), anyBoolean());
-            doReturn(stack).when(mRootWindowContainer).getLaunchRootTask(any(), any(), any(), any(),
-                    anyBoolean(), any(), anyInt());
+                    .getOrCreateRootTask(any(), any(), any(), anyBoolean());
+            doReturn(stack).when(mRootWindowContainer).getOrCreateRootTask(any(), any(), any(),
+                    any(), anyBoolean(), any(), anyInt());
         }
 
         // Set up mock package manager internal and make sure no unmocked methods are called
@@ -434,7 +434,7 @@
     public void testSplitScreenDeliverToTop() {
         final ActivityStarter starter = prepareStarter(
                 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | FLAG_ACTIVITY_SINGLE_TOP,
-                false /* mockGetLaunchStack */);
+                false /* mockGetRootTask */);
         final Pair<ActivityRecord, ActivityRecord> activities = createActivitiesInSplit();
         final ActivityRecord splitPrimaryFocusActivity = activities.first;
         final ActivityRecord splitSecondReusableActivity = activities.second;
@@ -790,7 +790,7 @@
         finishingTopActivity.finishing = true;
 
         // Launch the bottom task of the target root task.
-        prepareStarter(FLAG_ACTIVITY_NEW_TASK, false /* mockGetLaunchStack */)
+        prepareStarter(FLAG_ACTIVITY_NEW_TASK, false /* mockGetRootTask */)
                 .setReason("testBringTaskToFrontWhenFocusedTaskIsFinishing")
                 .setIntent(activity.intent.addFlags(
                         FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
@@ -809,7 +809,7 @@
     @Test
     public void testDeliverIntentToTopActivityOfNonTopDisplay() {
         final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK,
-                false /* mockGetLaunchStack */);
+                false /* mockGetRootTask */);
 
         // Create a secondary display at bottom.
         final TestDisplayContent secondaryDisplay =
@@ -849,7 +849,7 @@
     @Test
     public void testBringTaskToFrontOnSecondaryDisplay() {
         final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK,
-                false /* mockGetLaunchStack */);
+                false /* mockGetRootTask */);
 
         // Create a secondary display with an activity.
         final TestDisplayContent secondaryDisplay =
@@ -943,7 +943,7 @@
     @Test
     public void testReparentTopFocusedActivityToSecondaryDisplay() {
         final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK,
-                false /* mockGetLaunchStack */);
+                false /* mockGetRootTask */);
 
         // Create a secondary display at bottom.
         final TestDisplayContent secondaryDisplay = addNewDisplayContentAt(POSITION_BOTTOM);
@@ -1076,7 +1076,7 @@
     @Test
     public void testTargetStackInSplitScreen() {
         final ActivityStarter starter =
-                prepareStarter(FLAG_ACTIVITY_LAUNCH_ADJACENT, false /* mockGetLaunchStack */);
+                prepareStarter(FLAG_ACTIVITY_LAUNCH_ADJACENT, false /* mockGetRootTask */);
         final ActivityRecord top = new ActivityBuilder(mAtm).setCreateTask(true).build();
         final ActivityOptions options = ActivityOptions.makeBasic();
         final ActivityRecord[] outActivity = new ActivityRecord[1];
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 2ea7fda..eb6395b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -36,6 +36,7 @@
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
 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.spyOn;
@@ -422,6 +423,7 @@
     public void testActivityRecordReparentToTaskFragment() {
         final ActivityRecord activity = createActivityRecord(mDc);
         final SurfaceControl activityLeash = mock(SurfaceControl.class);
+        doNothing().when(activity).setDropInputMode(anyInt());
         activity.setVisibility(true);
         activity.setSurfaceControl(activityLeash);
         final Task task = activity.getTask();
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index c21a5b6..92550a3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -30,7 +30,10 @@
 import android.annotation.NonNull;
 import android.hardware.HardwareBuffer;
 import android.platform.test.annotations.Presubmit;
+import android.window.BackEvent;
 import android.window.BackNavigationInfo;
+import android.window.IOnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
 import android.window.TaskSnapshot;
 
 import org.junit.Before;
@@ -42,15 +45,19 @@
 public class BackNavigationControllerTests extends WindowTestsBase {
 
     private BackNavigationController mBackNavigationController;
+    private IOnBackInvokedCallback mOnBackInvokedCallback;
 
     @Before
     public void setUp() throws Exception {
         mBackNavigationController = new BackNavigationController();
+        mOnBackInvokedCallback = createBackCallback();
     }
 
     @Test
     public void backTypeHomeWhenBackToLauncher() {
         Task task = createTopTaskWithActivity();
+        registerSystemOnBackInvokedCallback();
+
         BackNavigationInfo backNavigationInfo =
                 mBackNavigationController.startBackNavigation(task, new StubTransaction());
         assertThat(backNavigationInfo).isNotNull();
@@ -63,6 +70,8 @@
         Task taskA = createTask(mDefaultDisplay);
         createActivityRecord(taskA);
         Task task = createTopTaskWithActivity();
+        registerSystemOnBackInvokedCallback();
+
         BackNavigationInfo backNavigationInfo =
                 mBackNavigationController.startBackNavigation(task, new StubTransaction());
         assertThat(backNavigationInfo).isNotNull();
@@ -75,6 +84,8 @@
         Task task = createTopTaskWithActivity();
         mAtm.setFocusedTask(task.mTaskId,
                 createAppWindow(task, FIRST_APPLICATION_WINDOW, "window").mActivityRecord);
+        registerSystemOnBackInvokedCallback();
+
         BackNavigationInfo backNavigationInfo =
                 mBackNavigationController.startBackNavigation(task, new StubTransaction());
         assertThat(backNavigationInfo).isNotNull();
@@ -89,6 +100,7 @@
     public void backNavInfoFullyPopulated() {
         Task task = createTopTaskWithActivity();
         createAppWindow(task, FIRST_APPLICATION_WINDOW, "window");
+        registerSystemOnBackInvokedCallback();
 
         // We need a mock screenshot so
         TaskSnapshotController taskSnapshotController = createMockTaskSnapshotController();
@@ -104,6 +116,30 @@
         assertThat(backNavigationInfo.getTaskWindowConfiguration()).isNotNull();
     }
 
+    @Test
+    public void preparesForBackToHome() {
+        Task task = createTopTaskWithActivity();
+        ActivityRecord activity = task.getTopActivity(false, false);
+        registerSystemOnBackInvokedCallback();
+
+        BackNavigationInfo backNavigationInfo =
+                mBackNavigationController.startBackNavigation(task, new StubTransaction());
+        assertThat(typeToString(backNavigationInfo.getType()))
+                .isEqualTo(typeToString(BackNavigationInfo.TYPE_RETURN_TO_HOME));
+    }
+
+    @Test
+    public void backTypeCallback() {
+        Task task = createTopTaskWithActivity();
+        ActivityRecord activity = task.getTopActivity(false, false);
+        registerApplicationOnBackInvokedCallback();
+
+        BackNavigationInfo backNavigationInfo =
+                mBackNavigationController.startBackNavigation(task, new StubTransaction());
+        assertThat(typeToString(backNavigationInfo.getType()))
+                .isEqualTo(typeToString(BackNavigationInfo.TYPE_CALLBACK));
+    }
+
     @NonNull
     private TaskSnapshotController createMockTaskSnapshotController() {
         TaskSnapshotController taskSnapshotController = mock(TaskSnapshotController.class);
@@ -126,4 +162,30 @@
         mAtm.setFocusedTask(task.mTaskId, record);
         return task;
     }
+
+    private void registerSystemOnBackInvokedCallback() {
+        mWm.getFocusedWindowLocked().setOnBackInvokedCallback(
+                mOnBackInvokedCallback, OnBackInvokedDispatcher.PRIORITY_SYSTEM);
+    }
+
+    private void registerApplicationOnBackInvokedCallback() {
+        mWm.getFocusedWindowLocked().setOnBackInvokedCallback(
+                mOnBackInvokedCallback, OnBackInvokedDispatcher.PRIORITY_DEFAULT);
+    }
+
+    private IOnBackInvokedCallback createBackCallback() {
+        return new IOnBackInvokedCallback.Stub() {
+            @Override
+            public void onBackStarted() { }
+
+            @Override
+            public void onBackProgressed(BackEvent backEvent) { }
+
+            @Override
+            public void onBackCancelled() { }
+
+            @Override
+            public void onBackInvoked() { }
+        };
+    }
 }
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 12f987d..40b4601 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -77,7 +77,6 @@
 import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_FIXED_TRANSFORM;
-import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
@@ -108,6 +107,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.hardware.HardwareBuffer;
 import android.hardware.display.VirtualDisplay;
 import android.metrics.LogMaker;
 import android.os.Binder;
@@ -1102,6 +1102,21 @@
         assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
+    @Test
+    public void testComputeImeParent_inputTargetNotUpdate() throws Exception {
+        WindowState app1 = createWindow(null, TYPE_BASE_APPLICATION, "app1");
+        WindowState app2 = createWindow(null, TYPE_BASE_APPLICATION, "app2");
+        doReturn(true).when(mDisplayContent).shouldImeAttachedToApp();
+        mDisplayContent.setImeLayeringTarget(app1);
+        mDisplayContent.setImeInputTarget(app1);
+        assertEquals(app1.mActivityRecord.getSurfaceControl(), mDisplayContent.computeImeParent());
+        mDisplayContent.setImeLayeringTarget(app2);
+        // Expect null means no change IME parent when the IME layering target not yet
+        // request IME to be the input target.
+        assertNull(mDisplayContent.computeImeParent());
+    }
+
     @Test
     public void testInputMethodInputTarget_isClearedWhenWindowStateIsRemoved() throws Exception {
         final DisplayContent dc = createNewDisplay();
@@ -1370,7 +1385,9 @@
                 ROTATION_0 /* oldRotation */, ROTATION_90 /* newRotation */,
                 false /* forceUpdate */));
 
-        assertNotNull(mDisplayContent.getAsyncRotationController());
+        final AsyncRotationController asyncRotationController =
+                mDisplayContent.getAsyncRotationController();
+        assertNotNull(asyncRotationController);
         assertTrue(mStatusBarWindow.isAnimating(PARENTS, ANIMATION_TYPE_FIXED_TRANSFORM));
         assertTrue(mNavBarWindow.isAnimating(PARENTS, ANIMATION_TYPE_FIXED_TRANSFORM));
         // Notification shade may have its own view animation in real case so do not fade out it.
@@ -1443,6 +1460,7 @@
         mDisplayContent.setImeLayeringTarget(mAppWindow);
         LocalServices.getService(WindowManagerInternal.class).onToggleImeRequested(true /* show */,
                 app.token, app.token, mDisplayContent.mDisplayId);
+        assertTrue(asyncRotationController.isTargetToken(mImeWindow.mToken));
         assertTrue(mImeWindow.mToken.hasFixedRotationTransform());
         assertTrue(mImeWindow.isAnimating(PARENTS, ANIMATION_TYPE_FIXED_TRANSFORM));
 
@@ -1936,12 +1954,10 @@
 
         // Preparation: Simulate snapshot IME surface.
         spyOn(mWm.mTaskSnapshotController);
-        doReturn(mock(SurfaceControl.ScreenshotHardwareBuffer.class)).when(
-                mWm.mTaskSnapshotController).snapshotImeFromAttachedTask(any());
-        final SurfaceControl imeSurface = mock(SurfaceControl.class);
-        spyOn(imeSurface);
-        doReturn(true).when(imeSurface).isValid();
-        doReturn(imeSurface).when(mDisplayContent).createImeSurface(any(), any());
+        SurfaceControl.ScreenshotHardwareBuffer mockHwBuffer = mock(
+                SurfaceControl.ScreenshotHardwareBuffer.class);
+        doReturn(mock(HardwareBuffer.class)).when(mockHwBuffer).getHardwareBuffer();
+        doReturn(mockHwBuffer).when(mWm.mTaskSnapshotController).snapshotImeFromAttachedTask(any());
 
         // Preparation: Simulate snapshot Task.
         ActivityRecord act1 = createActivityRecord(mDisplayContent);
@@ -1967,21 +1983,18 @@
         final WindowState appWin2 = createWindow(null, TYPE_BASE_APPLICATION, act2, "appWin2");
         appWin2.setHasSurface(true);
         assertTrue(appWin2.canBeImeTarget());
-        doReturn(true).when(appWin1).isAnimating(PARENTS | TRANSITION,
-                ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS);
+        doReturn(true).when(appWin1).isClosing();
+        doReturn(true).when(appWin1).inAppOrRecentsTransition();
 
         // Test step 3: Verify appWin2 will be the next IME target and the IME snapshot surface will
-        // be shown at this time.
-        final Transaction t = mDisplayContent.getPendingTransaction();
-        spyOn(t);
+        // be attached and shown on the display at this time.
         mDisplayContent.computeImeTarget(true);
         assertEquals(appWin2, mDisplayContent.getImeTarget(IME_TARGET_LAYERING));
         assertTrue(mDisplayContent.shouldImeAttachedToApp());
 
-        verify(mDisplayContent, atLeast(1)).attachAndShowImeScreenshotOnTarget();
+        verify(mDisplayContent, atLeast(1)).showImeScreenshot();
         verify(mWm.mTaskSnapshotController).snapshotImeFromAttachedTask(appWin1.getTask());
         assertNotNull(mDisplayContent.mImeScreenshot);
-        verify(t).show(mDisplayContent.mImeScreenshot);
     }
 
     @UseTestDisplay(addWindows = {W_INPUT_METHOD}, addAllCommonWindows = true)
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerHelperTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerHelperTests.java
index 6e11d8c..f968999 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerHelperTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerHelperTests.java
@@ -16,13 +16,18 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
 
+import android.app.WindowConfiguration;
 import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
 import android.os.UserHandle;
@@ -37,6 +42,7 @@
 import org.junit.runner.RunWith;
 
 import java.util.List;
+import java.util.Set;
 
 /**
  * Tests for the {@link DisplayWindowPolicyControllerHelper} class.
@@ -113,6 +119,39 @@
         return activity;
     }
 
+    @Test
+    public void testIsWindowingModeSupported_noController_returnTrueForAnyWindowingMode() {
+        doReturn(null).when(mWm.mDisplayManagerInternal)
+                .getDisplayWindowPolicyController(anyInt());
+        mSecondaryDisplay = createNewDisplay();
+        assertFalse(mSecondaryDisplay.mDwpcHelper.hasController());
+
+        assertTrue(mSecondaryDisplay.mDwpcHelper.isWindowingModeSupported(WINDOWING_MODE_PINNED));
+        assertTrue(
+                mSecondaryDisplay.mDwpcHelper.isWindowingModeSupported(WINDOWING_MODE_FULLSCREEN));
+    }
+
+    @Test
+    public void testIsWindowingModeSupported_withoutSettingSupportedMode_returnFalse() {
+        assertFalse(mSecondaryDisplay.mDwpcHelper.isWindowingModeSupported(WINDOWING_MODE_PINNED));
+    }
+
+    @Test
+    public void testIsWindowingModeSupported_withoutSupportedMode_defaultSupportFullScreen() {
+        assertTrue(
+                mSecondaryDisplay.mDwpcHelper.isWindowingModeSupported(WINDOWING_MODE_FULLSCREEN));
+    }
+
+    @Test
+    public void testIsWindowingModeSupported_setPinnedMode_returnTrue() {
+        Set<Integer> supportedWindowingMode = new ArraySet<>();
+        supportedWindowingMode.add(WINDOWING_MODE_PINNED);
+
+        mDwpc.setSupportedWindowingModes(supportedWindowingMode);
+
+        assertTrue(mSecondaryDisplay.mDwpcHelper.isWindowingModeSupported(WINDOWING_MODE_PINNED));
+    }
+
     private class TestDisplayWindowPolicyController extends DisplayWindowPolicyController {
 
         ComponentName mTopActivity = null;
@@ -120,7 +159,8 @@
         ArraySet<Integer> mRunningUids = new ArraySet<>();
 
         @Override
-        public boolean canContainActivities(@NonNull List<ActivityInfo> activities) {
+        public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
+                @WindowConfiguration.WindowingMode int windowingMode) {
             return false;
         }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/MockSurfaceControlBuilder.java b/services/tests/wmtests/src/com/android/server/wm/MockSurfaceControlBuilder.java
index 66139e6..6a39d56 100644
--- a/services/tests/wmtests/src/com/android/server/wm/MockSurfaceControlBuilder.java
+++ b/services/tests/wmtests/src/com/android/server/wm/MockSurfaceControlBuilder.java
@@ -20,6 +20,8 @@
 
 import android.view.SurfaceControl;
 
+import org.mockito.Mockito;
+
 /**
  * Stubbed {@link SurfaceControl.Builder} class that returns a mocked SurfaceControl instance
  * that can be used for unit testing.
@@ -32,6 +34,8 @@
 
     @Override
     public SurfaceControl build() {
-        return mock(SurfaceControl.class);
+        SurfaceControl mockSurfaceControl = mock(SurfaceControl.class);
+        Mockito.doReturn(true).when(mockSurfaceControl).isValid();
+        return mockSurfaceControl;
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
index 1924760..9d2eb26 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
@@ -101,14 +101,63 @@
         assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
         assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
         assertEquals(0, mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
-        mPolicy.addNonHighRefreshRatePackage("com.android.test");
+        mPolicy.addRefreshRateRangeForPackage("com.android.test",
+                LOW_REFRESH_RATE, LOW_REFRESH_RATE);
         assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
         assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
         assertEquals(LOW_REFRESH_RATE,
                 mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
         assertEquals(LOW_REFRESH_RATE,
                 mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
-        mPolicy.removeNonHighRefreshRatePackage("com.android.test");
+        mPolicy.removeRefreshRateRangeForPackage("com.android.test");
+        assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
+        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+    }
+
+    @Test
+    public void testCameraRange() {
+        final WindowState cameraUsingWindow = createWindow("cameraUsingWindow");
+        cameraUsingWindow.mAttrs.packageName = "com.android.test";
+        parcelLayoutParams(cameraUsingWindow);
+        assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
+        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        mPolicy.addRefreshRateRangeForPackage("com.android.test",
+                LOW_REFRESH_RATE, MID_REFRESH_RATE);
+        assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
+        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(LOW_REFRESH_RATE,
+                mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(MID_REFRESH_RATE,
+                mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        mPolicy.removeRefreshRateRangeForPackage("com.android.test");
+        assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
+        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+    }
+
+    @Test
+    public void testCameraRange_OutOfRange() {
+        final WindowState cameraUsingWindow = createWindow("cameraUsingWindow");
+        cameraUsingWindow.mAttrs.packageName = "com.android.test";
+        parcelLayoutParams(cameraUsingWindow);
+        assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
+        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(0, mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        mPolicy.addRefreshRateRangeForPackage("com.android.test",
+                LOW_REFRESH_RATE - 10, HI_REFRESH_RATE + 10);
+        assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
+        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(LOW_REFRESH_RATE,
+                mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        assertEquals(HI_REFRESH_RATE,
+                mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+        mPolicy.removeRefreshRateRangeForPackage("com.android.test");
         assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
         assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
         assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
@@ -162,7 +211,8 @@
         overrideWindow.mAttrs.packageName = "com.android.test";
         overrideWindow.mAttrs.preferredDisplayModeId = HI_MODE_ID;
         parcelLayoutParams(overrideWindow);
-        mPolicy.addNonHighRefreshRatePackage("com.android.test");
+        mPolicy.addRefreshRateRangeForPackage("com.android.test",
+                LOW_REFRESH_RATE, LOW_REFRESH_RATE);
         assertEquals(HI_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
         assertEquals(HI_REFRESH_RATE,
                 mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
@@ -178,7 +228,8 @@
         overrideWindow.mAttrs.packageName = "com.android.test";
         overrideWindow.mAttrs.preferredRefreshRate = HI_REFRESH_RATE;
         parcelLayoutParams(overrideWindow);
-        mPolicy.addNonHighRefreshRatePackage("com.android.test");
+        mPolicy.addRefreshRateRangeForPackage("com.android.test",
+                LOW_REFRESH_RATE, LOW_REFRESH_RATE);
         assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
         assertEquals(HI_REFRESH_RATE,
                 mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
@@ -257,7 +308,8 @@
         cameraUsingWindow.mAttrs.packageName = "com.android.test";
         parcelLayoutParams(cameraUsingWindow);
 
-        mPolicy.addNonHighRefreshRatePackage("com.android.test");
+        mPolicy.addRefreshRateRangeForPackage("com.android.test",
+                LOW_REFRESH_RATE, LOW_REFRESH_RATE);
         assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
         assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
         assertEquals(LOW_REFRESH_RATE,
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index acceadf..99ba3b8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -949,7 +949,7 @@
         LaunchParamsController.LaunchParams launchParams =
                 new LaunchParamsController.LaunchParams();
         launchParams.mPreferredTaskDisplayArea = taskDisplayArea;
-        Task root = mRootWindowContainer.getLaunchRootTask(null /* r */, null /* options */,
+        Task root = mRootWindowContainer.getOrCreateRootTask(null /* r */, null /* options */,
                 null /* candidateTask */, null /* sourceTask */, true /* onTop */, launchParams,
                 0 /* launchParams */);
         assertEquals(taskDisplayArea, root.getTaskDisplayArea());
@@ -957,7 +957,7 @@
         // Making sure still getting the root task from the preferred TDA when passing in a
         // launching activity.
         ActivityRecord r = new ActivityBuilder(mAtm).build();
-        root = mRootWindowContainer.getLaunchRootTask(r, null /* options */,
+        root = mRootWindowContainer.getOrCreateRootTask(r, null /* options */,
                 null /* candidateTask */, null /* sourceTask */, true /* onTop */, launchParams,
                 0 /* launchParams */);
         assertEquals(taskDisplayArea, root.getTaskDisplayArea());
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index cb85884..33b2366 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.server.wm.RunningTasks.FLAG_ALLOWED;
 import static com.android.server.wm.RunningTasks.FLAG_CROSS_USERS;
 import static com.android.server.wm.RunningTasks.FLAG_KEEP_INTENT_EXTRA;
@@ -81,7 +82,9 @@
             rootTasks.add(task);
         }, false /* traverseTopToBottom */);
         for (int i = 0; i < numTasks; i++) {
-            createTask(rootTasks.get(i % numStacks), ".Task" + i, i, activeTime++, null);
+            final Task task =
+                    createTask(rootTasks.get(i % numStacks), ".Task" + i, i, activeTime++, null);
+            doReturn(false).when(task).isVisible();
         }
 
         // Ensure that the latest tasks were returned in order of decreasing last active time,
@@ -158,6 +161,36 @@
         }
     }
 
+    @Test
+    public void testUpdateLastActiveTimeOfVisibleTasks() {
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build();
+        final int numTasks = 10;
+        final ArrayList<Task> tasks = new ArrayList<>();
+        for (int i = 0; i < numTasks; i++) {
+            final Task task = createTask(null, ".Task" + i, i, i, null);
+            doReturn(false).when(task).isVisible();
+            tasks.add(task);
+        }
+
+        final Task visibleTask = tasks.get(0);
+        doReturn(true).when(visibleTask).isVisible();
+
+        final Task focusedTask = tasks.get(1);
+        doReturn(true).when(focusedTask).isVisible();
+        doReturn(true).when(focusedTask).isFocused();
+
+        // Ensure that the last active time of visible tasks were updated while the focused one had
+        // the largest last active time.
+        final int numFetchTasks = 5;
+        final ArrayList<RunningTaskInfo> fetchTasks = new ArrayList<>();
+        mRunningTasks.getTasks(numFetchTasks, fetchTasks,
+                FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA, mRootWindowContainer,
+                -1 /* callingUid */, PROFILE_IDS);
+        assertThat(fetchTasks).hasSize(numFetchTasks);
+        assertEquals(fetchTasks.get(0).id, focusedTask.mTaskId);
+        assertEquals(fetchTasks.get(1).id, visibleTask.mTaskId);
+    }
+
     /**
      * Create a task with a single activity in it, with the given last active time.
      */
diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
index 46ef7ed..d275818 100644
--- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
+++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
@@ -17,11 +17,13 @@
 package com.android.server.wm;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.ColorSpace;
 import android.graphics.GraphicBuffer;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.hardware.HardwareBuffer;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.view.InputWindowHandle;
@@ -135,6 +137,12 @@
     }
 
     @Override
+    @NonNull
+    public SurfaceControl.Transaction setCrop(@NonNull SurfaceControl sc, @Nullable Rect crop) {
+        return this;
+    }
+
+    @Override
     public SurfaceControl.Transaction setCornerRadius(SurfaceControl sc, float cornerRadius) {
         return this;
     }
@@ -275,6 +283,13 @@
     }
 
     @Override
+    @NonNull
+    public SurfaceControl.Transaction setBuffer(@NonNull SurfaceControl sc,
+            @Nullable HardwareBuffer buffer) {
+        return this;
+    }
+
+    @Override
     public SurfaceControl.Transaction setColorSpace(SurfaceControl sc, ColorSpace colorSpace) {
         return this;
     }
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 0debdfa..c615866 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -359,17 +359,11 @@
     public void testApplyTransaction_enforceHierarchyChange_createTaskFragment()
             throws RemoteException {
         mController.registerOrganizer(mIOrganizer);
-        final ActivityRecord activity = createActivityRecord(mDisplayContent);
-        final int uid = Binder.getCallingUid();
-        activity.info.applicationInfo.uid = uid;
-        activity.getTask().effectiveUid = uid;
+        final ActivityRecord ownerActivity = createActivityRecord(mDisplayContent);
         final IBinder fragmentToken = new Binder();
-        final TaskFragmentCreationParams params = new TaskFragmentCreationParams.Builder(
-                mOrganizerToken, fragmentToken, activity.token).build();
-        mOrganizer.applyTransaction(mTransaction);
 
         // Allow organizer to create TaskFragment and start/reparent activity to TaskFragment.
-        mTransaction.createTaskFragment(params);
+        createTaskFragmentFromOrganizer(mTransaction, ownerActivity, fragmentToken);
         mTransaction.startActivityInTaskFragment(
                 mFragmentToken, null /* callerToken */, new Intent(), null /* activityOptions */);
         mTransaction.reparentActivityToTaskFragment(mFragmentToken, mock(IBinder.class));
@@ -381,7 +375,7 @@
         final TaskFragment taskFragment = mAtm.mWindowOrganizerController
                 .getTaskFragment(fragmentToken);
         assertNotNull(taskFragment);
-        assertEquals(activity.getTask(), taskFragment.getTask());
+        assertEquals(ownerActivity.getTask(), taskFragment.getTask());
     }
 
     @Test
@@ -523,4 +517,43 @@
         mController.dispatchPendingEvents();
         verify(mOrganizer).onTaskFragmentInfoChanged(any());
     }
+
+    /**
+     * When an embedded {@link TaskFragment} is removed, we should clean up the reference in the
+     * {@link WindowOrganizerController}.
+     */
+    @Test
+    public void testTaskFragmentRemoved_cleanUpEmbeddedTaskFragment()
+            throws RemoteException {
+        mController.registerOrganizer(mIOrganizer);
+        final ActivityRecord ownerActivity = createActivityRecord(mDisplayContent);
+        final IBinder fragmentToken = new Binder();
+        createTaskFragmentFromOrganizer(mTransaction, ownerActivity, fragmentToken);
+        mAtm.getWindowOrganizerController().applyTransaction(mTransaction);
+        final TaskFragment taskFragment = mAtm.mWindowOrganizerController
+                .getTaskFragment(fragmentToken);
+
+        assertNotNull(taskFragment);
+
+        taskFragment.removeImmediately();
+
+        assertNull(mAtm.mWindowOrganizerController.getTaskFragment(fragmentToken));
+    }
+
+    /**
+     * Creates a {@link TaskFragment} with the {@link WindowContainerTransaction}. Calls
+     * {@link WindowOrganizerController#applyTransaction} to apply the transaction,
+     */
+    private void createTaskFragmentFromOrganizer(WindowContainerTransaction wct,
+            ActivityRecord ownerActivity, IBinder fragmentToken) {
+        final int uid = Binder.getCallingUid();
+        ownerActivity.info.applicationInfo.uid = uid;
+        ownerActivity.getTask().effectiveUid = uid;
+        final TaskFragmentCreationParams params = new TaskFragmentCreationParams.Builder(
+                mOrganizerToken, fragmentToken, ownerActivity.token).build();
+        mOrganizer.applyTransaction(wct);
+
+        // Allow organizer to create TaskFragment and start/reparent activity to TaskFragment.
+        wct.createTaskFragment(params);
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index fe41734..9304761 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -146,6 +146,27 @@
     }
 
     @Test
+    public void testRemoveContainer_multipleNestedTasks() {
+        final Task rootTask = createTask(mDisplayContent);
+        rootTask.mCreatedByOrganizer = true;
+        final Task task1 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
+        final Task task2 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build();
+        final ActivityRecord activity1 = createActivityRecord(task1);
+        final ActivityRecord activity2 = createActivityRecord(task2);
+        activity1.setVisible(false);
+
+        // All activities under the root task should be finishing.
+        rootTask.remove(true /* withTransition */, "test");
+        assertTrue(activity1.finishing);
+        assertTrue(activity2.finishing);
+
+        // After all activities activities are destroyed, the root task should also be removed.
+        activity1.removeImmediately();
+        activity2.removeImmediately();
+        assertFalse(rootTask.isAttached());
+    }
+
+    @Test
     public void testRemoveContainer_deferRemoval() {
         final Task rootTask = createTask(mDisplayContent);
         final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
@@ -238,6 +259,20 @@
     }
 
     @Test
+    public void testPerformClearTop() {
+        final Task task = createTask(mDisplayContent);
+        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setTask(task).build();
+        final ActivityRecord activity2 = new ActivityBuilder(mAtm).setTask(task).build();
+        // Detach from process so the activities can be removed from hierarchy when finishing.
+        activity1.detachFromProcess();
+        activity2.detachFromProcess();
+        assertNull(task.performClearTop(activity1, 0 /* launchFlags */));
+        assertFalse(task.hasChild());
+        // In real case, the task should be preserved for adding new activity.
+        assertTrue(task.isAttached());
+    }
+
+    @Test
     public void testRemoveChildForOverlayTask() {
         final Task task = createTask(mDisplayContent);
         final int taskId = task.mTaskId;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
index 7dfb5ae..4f35d55 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
@@ -44,7 +44,7 @@
     @Override
     public void resized(ClientWindowFrames frames, boolean reportDraw,
             MergedConfiguration mergedConfig, boolean forceLayout, boolean alwaysConsumeSystemBars,
-            int displayId) throws RemoteException {
+            int displayId, int seqId) throws RemoteException {
     }
 
     @Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 8474c38..7e5d017 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -32,6 +32,7 @@
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
 import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
+import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
 import static android.window.TransitionInfo.isIndependent;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -328,6 +329,7 @@
             final ActivityRecord act = createActivityRecord(tasks[i]);
             // alternate so that the transition doesn't get promoted to the display area
             act.mVisibleRequested = (i % 2) == 0; // starts invisible
+            act.visibleIgnoringKeyguard = (i % 2) == 0;
             if (i == showWallpaperTask) {
                 doReturn(true).when(act).showWallpaper();
             }
@@ -490,6 +492,86 @@
     }
 
     @Test
+    public void testOpenOpaqueTask() {
+        final Transition transition = createTestTransition(TRANSIT_OPEN);
+        ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
+        ArraySet<WindowContainer> participants = transition.mParticipants;
+
+        final Task newTask = createTask(mDisplayContent);
+        doReturn(false).when(newTask).isTranslucent(any());
+        final Task oldTask = createTask(mDisplayContent);
+        doReturn(false).when(oldTask).isTranslucent(any());
+
+        final ActivityRecord closing = createActivityRecord(oldTask);
+        closing.setOccludesParent(true);
+        final ActivityRecord opening = createActivityRecord(newTask);
+        opening.setOccludesParent(false);
+        // Start states.
+        changes.put(newTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
+        changes.put(oldTask, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
+        changes.put(opening, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
+        changes.put(closing, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
+        fillChangeMap(changes, newTask);
+        // End states.
+        closing.mVisibleRequested = true;
+        opening.mVisibleRequested = true;
+
+        final int transit = transition.mType;
+        int flags = 0;
+
+        // Check basic both tasks participating
+        participants.add(oldTask);
+        participants.add(newTask);
+        ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
+        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        assertEquals(2, info.getChanges().size());
+        assertEquals(transit, info.getType());
+
+        assertTrue((info.getChanges().get(0).getFlags() & FLAG_TRANSLUCENT) == 0);
+        assertTrue((info.getChanges().get(1).getFlags() & FLAG_TRANSLUCENT) == 0);
+    }
+
+    @Test
+    public void testOpenTranslucentTask() {
+        final Transition transition = createTestTransition(TRANSIT_OPEN);
+        ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
+        ArraySet<WindowContainer> participants = transition.mParticipants;
+
+        final Task newTask = createTask(mDisplayContent);
+        doReturn(true).when(newTask).isTranslucent(any());
+        final Task oldTask = createTask(mDisplayContent);
+        doReturn(false).when(oldTask).isTranslucent(any());
+
+        final ActivityRecord closing = createActivityRecord(oldTask);
+        closing.setOccludesParent(true);
+        final ActivityRecord opening = createActivityRecord(newTask);
+        opening.setOccludesParent(false);
+        // Start states.
+        changes.put(newTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
+        changes.put(oldTask, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
+        changes.put(opening, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
+        changes.put(closing, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
+        fillChangeMap(changes, newTask);
+        // End states.
+        closing.mVisibleRequested = true;
+        opening.mVisibleRequested = true;
+
+        final int transit = transition.mType;
+        int flags = 0;
+
+        // Check basic both tasks participating
+        participants.add(oldTask);
+        participants.add(newTask);
+        ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
+        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        assertEquals(2, info.getChanges().size());
+        assertEquals(transit, info.getType());
+
+        assertTrue((info.getChanges().get(0).getFlags() & FLAG_TRANSLUCENT) != 0);
+        assertTrue((info.getChanges().get(1).getFlags() & FLAG_TRANSLUCENT) == 0);
+    }
+
+    @Test
     public void testTimeout() {
         final TransitionController controller = new TransitionController(mAtm,
                 mock(TaskSnapshotController.class));
@@ -610,7 +692,8 @@
         statusBar.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
         final SurfaceControl.Transaction postDrawTransaction =
                 mock(SurfaceControl.Transaction.class);
-        final boolean layoutNeeded = statusBar.finishDrawing(postDrawTransaction);
+        final boolean layoutNeeded = statusBar.finishDrawing(postDrawTransaction,
+                Integer.MAX_VALUE);
         assertFalse(layoutNeeded);
 
         transactionCommittedListener.onTransactionCommitted();
@@ -660,7 +743,7 @@
         player.finish();
 
         // The controller should be cleared if the target windows are drawn.
-        statusBar.finishDrawing(mWm.mTransactionFactory.get());
+        statusBar.finishDrawing(mWm.mTransactionFactory.get(), Integer.MAX_VALUE);
         statusBar.setOrientationChanging(false);
         assertNull(mDisplayContent.getAsyncRotationController());
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
index 7d2e9bf..ea18e58 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
@@ -45,6 +45,7 @@
 import android.view.WindowInsets;
 import android.view.WindowLayout;
 import android.view.WindowManager;
+import android.window.ClientWindowFrames;
 
 import androidx.test.filters.SmallTest;
 
@@ -71,9 +72,7 @@
     private static final Insets WATERFALL_INSETS = Insets.of(6, 0, 12, 0);
 
     private final WindowLayout mWindowLayout = new WindowLayout();
-    private final Rect mDisplayFrame = new Rect();
-    private final Rect mParentFrame = new Rect();
-    private final Rect mFrame = new Rect();
+    private final ClientWindowFrames mOutFrames = new ClientWindowFrames();
 
     private WindowManager.LayoutParams mAttrs;
     private InsetsState mState;
@@ -108,7 +107,7 @@
     private void computeFrames() {
         mWindowLayout.computeFrames(mAttrs, mState, mDisplayCutoutSafe, mWindowBounds,
                 mWindowingMode, mRequestedWidth, mRequestedHeight, mRequestedVisibilities,
-                mAttachedWindowFrame, mCompatScale, mDisplayFrame, mParentFrame, mFrame);
+                mAttachedWindowFrame, mCompatScale, mOutFrames);
     }
 
     private void addDisplayCutout() {
@@ -146,9 +145,9 @@
     public void defaultParams() {
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mDisplayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mParentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.frame);
     }
 
     @Test
@@ -157,9 +156,9 @@
         mRequestedHeight = UNSPECIFIED_LENGTH;
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mDisplayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mParentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.frame);
     }
 
     @Test
@@ -173,9 +172,9 @@
         mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mDisplayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mParentFrame);
-        assertRect(0, STATUS_BAR_HEIGHT, width, STATUS_BAR_HEIGHT + height, mFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
+        assertRect(0, STATUS_BAR_HEIGHT, width, STATUS_BAR_HEIGHT + height, mOutFrames.frame);
     }
 
     @Test
@@ -186,9 +185,12 @@
         mRequestedHeight = UNSPECIFIED_LENGTH;
         computeFrames();
 
-        assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT, mDisplayFrame);
-        assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT, mParentFrame);
-        assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT, mFrame);
+        assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+                mOutFrames.displayFrame);
+        assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+                mOutFrames.parentFrame);
+        assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+                mOutFrames.frame);
     }
 
     @Test
@@ -196,9 +198,9 @@
         mAttrs.setFitInsetsTypes(WindowInsets.Type.statusBars());
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mDisplayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mParentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.frame);
     }
 
     @Test
@@ -206,9 +208,9 @@
         mAttrs.setFitInsetsTypes(WindowInsets.Type.navigationBars());
         computeFrames();
 
-        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mDisplayFrame);
-        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mParentFrame);
-        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mFrame);
+        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
+        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
+        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mOutFrames.frame);
     }
 
     @Test
@@ -216,9 +218,9 @@
         mAttrs.setFitInsetsTypes(0);
         computeFrames();
 
-        assertInsetByTopBottom(0, 0, mDisplayFrame);
-        assertInsetByTopBottom(0, 0, mParentFrame);
-        assertInsetByTopBottom(0, 0, mFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.displayFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.parentFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.frame);
     }
 
     @Test
@@ -226,9 +228,9 @@
         mAttrs.setFitInsetsSides(WindowInsets.Side.all());
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mDisplayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mParentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.frame);
     }
 
     @Test
@@ -236,9 +238,9 @@
         mAttrs.setFitInsetsSides(WindowInsets.Side.TOP);
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mDisplayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mParentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.frame);
     }
 
     @Test
@@ -246,9 +248,9 @@
         mAttrs.setFitInsetsSides(0);
         computeFrames();
 
-        assertInsetByTopBottom(0, 0, mDisplayFrame);
-        assertInsetByTopBottom(0, 0, mParentFrame);
-        assertInsetByTopBottom(0, 0, mFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.displayFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.parentFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.frame);
     }
 
     @Test
@@ -257,9 +259,9 @@
         mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(false);
         computeFrames();
 
-        assertInsetByTopBottom(0, 0, mDisplayFrame);
-        assertInsetByTopBottom(0, 0, mParentFrame);
-        assertInsetByTopBottom(0, 0, mFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.displayFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.parentFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.frame);
     }
 
     @Test
@@ -269,9 +271,9 @@
         mAttrs.setFitInsetsIgnoringVisibility(true);
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mDisplayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mParentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.frame);
     }
 
     @Test
@@ -282,9 +284,9 @@
         mAttrs.privateFlags |= PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mDisplayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, IME_HEIGHT, mParentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, IME_HEIGHT, mFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, IME_HEIGHT, mOutFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, IME_HEIGHT, mOutFrames.frame);
     }
 
     @Test
@@ -295,11 +297,11 @@
         computeFrames();
 
         assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
-                mDisplayFrame);
+                mOutFrames.displayFrame);
         assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
-                mParentFrame);
+                mOutFrames.parentFrame);
         assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
-                mFrame);
+                mOutFrames.frame);
     }
 
     @Test
@@ -310,11 +312,11 @@
         computeFrames();
 
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mDisplayFrame);
+                mOutFrames.displayFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mParentFrame);
+                mOutFrames.parentFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mFrame);
+                mOutFrames.frame);
     }
 
     @Test
@@ -325,9 +327,9 @@
         mAttrs.setFitInsetsTypes(0);
         computeFrames();
 
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mDisplayFrame);
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mParentFrame);
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mFrame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.displayFrame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.parentFrame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.frame);
     }
 
     @Test
@@ -342,9 +344,9 @@
         mAttrs.privateFlags |= PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
         computeFrames();
 
-        assertRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, mDisplayFrame);
-        assertRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, mParentFrame);
-        assertRect(0, 0, DISPLAY_WIDTH, height + DISPLAY_CUTOUT_HEIGHT, mFrame);
+        assertRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, mOutFrames.displayFrame);
+        assertRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, mOutFrames.parentFrame);
+        assertRect(0, 0, DISPLAY_WIDTH, height + DISPLAY_CUTOUT_HEIGHT, mOutFrames.frame);
     }
 
     @Test
@@ -357,11 +359,11 @@
         computeFrames();
 
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mDisplayFrame);
+                mOutFrames.displayFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mParentFrame);
+                mOutFrames.parentFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mFrame);
+                mOutFrames.frame);
     }
 
     @Test
@@ -371,9 +373,9 @@
         mAttrs.setFitInsetsTypes(0);
         computeFrames();
 
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mDisplayFrame);
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mParentFrame);
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mFrame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.displayFrame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.parentFrame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.frame);
     }
 
     @Test
@@ -384,11 +386,11 @@
         computeFrames();
 
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mDisplayFrame);
+                mOutFrames.displayFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mParentFrame);
+                mOutFrames.parentFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mFrame);
+                mOutFrames.frame);
     }
 
     @Test
@@ -398,8 +400,8 @@
         mAttrs.setFitInsetsTypes(0);
         computeFrames();
 
-        assertInsetByTopBottom(0, 0, mDisplayFrame);
-        assertInsetByTopBottom(0, 0, mParentFrame);
-        assertInsetByTopBottom(0, 0, mFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.displayFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.parentFrame);
+        assertInsetByTopBottom(0, 0, mOutFrames.frame);
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 68e90e1..08320f8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -161,7 +161,7 @@
     @Test
     public void testDismissKeyguardCanWakeUp() {
         doReturn(true).when(mWm).checkCallingPermission(anyString(), anyString());
-        doReturn(true).when(mWm.mAtmService).isDreaming();
+        doReturn(true).when(mWm.mAtmService.mKeyguardController).isShowingDream();
         doNothing().when(mWm.mAtmService.mTaskSupervisor).wakeUp(anyString());
         mWm.dismissKeyguard(null, "test-dismiss-keyguard");
         verify(mWm.mAtmService.mTaskSupervisor).wakeUp(anyString());
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index e70dd08..6a3aa78 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -29,6 +29,8 @@
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
+import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
@@ -81,6 +83,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.IBinder;
+import android.os.InputConfig;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.util.ArraySet;
@@ -501,7 +504,7 @@
         assertTrue(win.useBLASTSync());
         final SurfaceControl.Transaction drawT = new StubTransaction();
         win.prepareDrawHandlers();
-        assertTrue(win.finishDrawing(drawT));
+        assertTrue(win.finishDrawing(drawT, Integer.MAX_VALUE));
         assertEquals(drawT, handledT[0]);
         assertFalse(win.useBLASTSync());
 
@@ -690,7 +693,7 @@
             doThrow(new RemoteException("test")).when(win.mClient).resized(any() /* frames */,
                     anyBoolean() /* reportDraw */, any() /* mergedConfig */,
                     anyBoolean() /* forceLayout */, anyBoolean() /* alwaysConsumeSystemBars */,
-                    anyInt() /* displayId */);
+                    anyInt() /* displayId */, anyInt() /* seqId */);
         } catch (RemoteException ignored) {
         }
         win.reportResized();
@@ -754,10 +757,15 @@
         assertFalse(win0.canReceiveTouchInput());
     }
 
+    private boolean testFlag(int flags, int test) {
+        return (flags & test) == test;
+    }
+
     @Test
     public void testUpdateInputWindowHandle() {
         final WindowState win = createWindow(null, TYPE_APPLICATION, "win");
         win.mAttrs.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
+        win.mAttrs.flags = FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH;
         final InputWindowHandle handle = new InputWindowHandle(
                 win.mInputWindowHandle.getInputApplicationHandle(), win.getDisplayId());
         final InputWindowHandleWrapper handleWrapper = new InputWindowHandleWrapper(handle);
@@ -767,13 +775,14 @@
         mDisplayContent.getInputMonitor().populateInputWindowHandle(handleWrapper, win);
 
         assertTrue(handleWrapper.isChanged());
+        assertTrue(testFlag(handle.inputConfig, InputConfig.WATCH_OUTSIDE_TOUCH));
+        assertFalse(testFlag(handle.inputConfig, InputConfig.PREVENT_SPLITTING));
+        assertTrue(testFlag(handle.inputConfig, InputConfig.DISABLE_USER_ACTIVITY));
         // The window of standard resizable task should not use surface crop as touchable region.
         assertFalse(handle.replaceTouchableRegionWithCrop);
         assertEquals(inputChannelToken, handle.token);
         assertEquals(win.mActivityRecord.getInputApplicationHandle(false /* update */),
                 handle.inputApplicationHandle);
-        assertEquals(win.mAttrs.inputFeatures, handle.inputFeatures);
-        assertEquals(win.isVisible(), handle.visible);
 
         final SurfaceControl sc = mock(SurfaceControl.class);
         final SurfaceControl.Transaction transaction = mSystemServicesTestRule.mTransaction;
@@ -799,21 +808,18 @@
         assertEquals(rotatedBounds, handle.touchableRegion.getBounds());
 
         // Populate as an overlay to disable the input of window.
-        InputMonitor.populateOverlayInputInfo(handleWrapper, false /* isVisible */);
+        InputMonitor.populateOverlayInputInfo(handleWrapper);
         // The overlay attributes should be set.
         assertTrue(handleWrapper.isChanged());
-        assertFalse(handle.focusable);
-        assertFalse(handle.visible);
+        assertFalse(handleWrapper.isFocusable());
         assertNull(handle.token);
         assertEquals(0L, handle.dispatchingTimeoutMillis);
-        assertEquals(WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL,
-                handle.inputFeatures);
+        assertTrue(testFlag(handle.inputConfig, InputConfig.NO_INPUT_CHANNEL));
     }
 
     @Test
     public void testHasActiveVisibleWindow() {
         final int uid = ActivityBuilder.DEFAULT_FAKE_UID;
-        mAtm.mActiveUids.onUidActive(uid, 0 /* any proc state */);
 
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app", uid);
         app.mActivityRecord.setVisible(false);
@@ -841,6 +847,11 @@
         // Make the application overlay window visible. It should be a valid active visible window.
         overlay.onSurfaceShownChanged(true);
         assertTrue(mAtm.hasActiveVisibleWindow(uid));
+
+        // The number of windows should be independent of the existence of uid state.
+        mAtm.mActiveUids.onUidInactive(uid);
+        mAtm.mActiveUids.onUidActive(uid, 0 /* any proc state */);
+        assertTrue(mAtm.mActiveUids.hasNonAppVisibleWindow(uid));
     }
 
     @UseTestDisplay(addWindows = W_ACTIVITY)
@@ -938,6 +949,46 @@
         assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
     }
 
+    @Test
+    public void testAdjustImeInsetsVisibilityWhenSwitchingApps_toAppInMultiWindowMode() {
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState app2 = createWindow(null, WINDOWING_MODE_MULTI_WINDOW,
+                ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app2");
+        final WindowState imeWindow = createWindow(null, TYPE_APPLICATION, "imeWindow");
+        spyOn(imeWindow);
+        doReturn(true).when(imeWindow).isVisible();
+        mDisplayContent.mInputMethodWindow = imeWindow;
+
+        final InsetsStateController controller = mDisplayContent.getInsetsStateController();
+        controller.getImeSourceProvider().setWindowContainer(imeWindow, null, null);
+
+        // Simulate app2 in multi-window mode is going to background to switch to the fullscreen
+        // app which requests IME with updating all windows Insets State when IME is above app.
+        app2.mActivityRecord.mImeInsetsFrozenUntilStartInput = true;
+        mDisplayContent.setImeLayeringTarget(app);
+        mDisplayContent.setImeInputTarget(app);
+        assertTrue(mDisplayContent.shouldImeAttachedToApp());
+        controller.getImeSourceProvider().scheduleShowImePostLayout(app);
+        controller.getImeSourceProvider().getSource().setVisible(true);
+        controller.updateAboveInsetsState(false);
+
+        // Expect app windows behind IME can receive IME insets visible,
+        // but not for app2 in background.
+        assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
+        assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
+
+        // Simulate app plays closing transition to app2.
+        // And app2 is now IME layering target but not yet to be the IME input target.
+        mDisplayContent.setImeLayeringTarget(app2);
+        app.mActivityRecord.commitVisibility(false, false);
+        assertTrue(app.mActivityRecord.mLastImeShown);
+        assertTrue(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
+
+        // Verify the IME insets is still visible on app, but not for app2 during task switching.
+        assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
+        assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
+    }
+
     @UseTestDisplay(addWindows = {W_ACTIVITY})
     @Test
     public void testUpdateImeControlTargetWhenLeavingMultiWindow() {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 1999cfc..b290669 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -640,7 +640,7 @@
                 Slog.e(TAG, "unknown state " + state);
                 return;
             }
-            removeMessages(MSG_UPDATE_STATE);
+            if (configured == 0) removeMessages(MSG_UPDATE_STATE);
             if (connected == 1) removeMessages(MSG_FUNCTION_SWITCH_TIMEOUT);
             Message msg = Message.obtain(this, MSG_UPDATE_STATE);
             msg.arg1 = connected;
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 84bd983..3988892 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -23,6 +23,25 @@
 import static android.service.voice.HotwordDetectionService.INITIALIZATION_STATUS_UNKNOWN;
 import static android.service.voice.HotwordDetectionService.KEY_INITIALIZATION_STATUS;
 
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_ERROR;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_SUCCESS;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_NO_VALUE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_OVER_MAX_CUSTOM_VALUE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_TIMEOUT;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__AUDIO_SERVICE_DIED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__SCHEDULE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_UPDATE_STATE_AFTER_TIMEOUT;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_UPDATE_STATE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_EXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_TIMEOUT;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED;
 import static com.android.server.voiceinteraction.SoundTriggerSessionPermissionsDecorator.enforcePermissionForPreflight;
 
 import android.annotation.NonNull;
@@ -48,6 +67,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SharedMemory;
+import android.provider.DeviceConfig;
 import android.service.voice.HotwordDetectedResult;
 import android.service.voice.HotwordDetectionService;
 import android.service.voice.HotwordDetector;
@@ -91,32 +111,56 @@
     private static final String TAG = "HotwordDetectionConnection";
     static final boolean DEBUG = false;
 
+    private static final String KEY_RESTART_PERIOD_IN_SECONDS = "restart_period_in_seconds";
     // TODO: These constants need to be refined.
-    private static final long VALIDATION_TIMEOUT_MILLIS = 3000;
+    private static final long VALIDATION_TIMEOUT_MILLIS = 4000;
     private static final long MAX_UPDATE_TIMEOUT_MILLIS = 6000;
     private static final Duration MAX_UPDATE_TIMEOUT_DURATION =
             Duration.ofMillis(MAX_UPDATE_TIMEOUT_MILLIS);
     private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour
+    /**
+     * Time after which each HotwordDetectionService process is stopped and replaced by a new one.
+     * 0 indicates no restarts.
+     */
+    private static final int RESTART_PERIOD_SECONDS =
+            DeviceConfig.getInt(DeviceConfig.NAMESPACE_VOICE_INTERACTION,
+                    KEY_RESTART_PERIOD_IN_SECONDS, 0);
+    private static final int MAX_ISOLATED_PROCESS_NUMBER = 10;
+
+    // Hotword metrics
+    private static final int METRICS_INIT_UNKNOWN_TIMEOUT =
+            HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_TIMEOUT;
+    private static final int METRICS_INIT_UNKNOWN_NO_VALUE =
+            HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_NO_VALUE;
+    private static final int METRICS_INIT_UNKNOWN_OVER_MAX_CUSTOM_VALUE =
+            HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_OVER_MAX_CUSTOM_VALUE;
+    private static final int METRICS_INIT_CALLBACK_STATE_ERROR =
+            HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_ERROR;
+    private static final int METRICS_INIT_CALLBACK_STATE_SUCCESS =
+            HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_SUCCESS;
 
     private final Executor mAudioCopyExecutor = Executors.newCachedThreadPool();
     // TODO: This may need to be a Handler(looper)
     private final ScheduledExecutorService mScheduledExecutorService =
             Executors.newSingleThreadScheduledExecutor();
+    @Nullable private final ScheduledFuture<?> mCancellationTaskFuture;
     private final AtomicBoolean mUpdateStateAfterStartFinished = new AtomicBoolean(false);
     private final IBinder.DeathRecipient mAudioServerDeathRecipient = this::audioServerDied;
     private final @NonNull ServiceConnectionFactory mServiceConnectionFactory;
     private final IHotwordRecognitionStatusCallback mCallback;
+    private final int mDetectorType;
 
     final Object mLock;
     final int mVoiceInteractionServiceUid;
     final ComponentName mDetectionComponentName;
     final int mUser;
     final Context mContext;
+
     volatile HotwordDetectionServiceIdentity mIdentity;
     private IMicrophoneHotwordDetectionVoiceInteractionCallback mSoftwareCallback;
     private Instant mLastRestartInstant;
 
-    private ScheduledFuture<?> mCancellationTaskFuture;
+    private ScheduledFuture<?> mCancellationKeyPhraseDetectionFuture;
     private ScheduledFuture<?> mDebugHotwordLoggingTimeoutFuture = null;
 
     /** Identity used for attributing app ops when delivering data to the Interactor. */
@@ -132,7 +176,6 @@
     private @NonNull ServiceConnection mRemoteHotwordDetectionService;
     private IBinder mAudioFlinger;
     private boolean mDebugHotwordLogging = false;
-    private final int mDetectorType;
 
     HotwordDetectionConnection(Object lock, Context context, int voiceInteractionServiceUid,
             Identity voiceInteractorIdentity, ComponentName serviceName, int userId,
@@ -162,14 +205,20 @@
         mLastRestartInstant = Instant.now();
         updateStateAfterProcessStart(options, sharedMemory);
 
-        // TODO(volnov): we need to be smarter here, e.g. schedule it a bit more often, but wait
-        // until the current session is closed.
-        mCancellationTaskFuture = mScheduledExecutorService.scheduleAtFixedRate(() -> {
-            Slog.v(TAG, "Time to restart the process, TTL has passed");
-            synchronized (mLock) {
-                restartProcessLocked();
-            }
-        }, 30, 30, TimeUnit.MINUTES);
+        if (RESTART_PERIOD_SECONDS <= 0) {
+            mCancellationTaskFuture = null;
+        } else {
+            // TODO(volnov): we need to be smarter here, e.g. schedule it a bit more often, but wait
+            // until the current session is closed.
+            mCancellationTaskFuture = mScheduledExecutorService.scheduleAtFixedRate(() -> {
+                Slog.v(TAG, "Time to restart the process, TTL has passed");
+                synchronized (mLock) {
+                    restartProcessLocked();
+                    HotwordMetricsLogger.writeServiceRestartEvent(mDetectorType,
+                            HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__SCHEDULE);
+                }
+            }, RESTART_PERIOD_SECONDS, RESTART_PERIOD_SECONDS, TimeUnit.SECONDS);
+        }
     }
 
     private void initAudioFlingerLocked() {
@@ -200,6 +249,8 @@
             // We restart the process instead of simply sending over the new binder, to avoid race
             // conditions with audio reading in the service.
             restartProcessLocked();
+            HotwordMetricsLogger.writeServiceRestartEvent(mDetectorType,
+                    HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__AUDIO_SERVICE_DIED);
         }
     }
 
@@ -219,26 +270,32 @@
                     future.complete(null);
                     if (mUpdateStateAfterStartFinished.getAndSet(true)) {
                         Slog.w(TAG, "call callback after timeout");
+                        HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                                HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_UPDATE_STATE_AFTER_TIMEOUT,
+                                mVoiceInteractionServiceUid);
                         return;
                     }
-                    int status = bundle != null ? bundle.getInt(
-                            KEY_INITIALIZATION_STATUS,
-                            INITIALIZATION_STATUS_UNKNOWN)
-                            : INITIALIZATION_STATUS_UNKNOWN;
-                    // Add the protection to avoid unexpected status
-                    if (status > HotwordDetectionService.getMaxCustomInitializationStatus()
-                            && status != INITIALIZATION_STATUS_UNKNOWN) {
-                        status = INITIALIZATION_STATUS_UNKNOWN;
-                    }
+                    Pair<Integer, Integer> statusResultPair = getInitStatusAndMetricsResult(bundle);
+                    int status = statusResultPair.first;
+                    int initResultMetricsResult = statusResultPair.second;
                     try {
                         mCallback.onStatusReported(status);
+                        HotwordMetricsLogger.writeServiceInitResultEvent(mDetectorType,
+                                initResultMetricsResult);
                     } catch (RemoteException e) {
+                        // TODO: Add a new atom for RemoteException case, the error doesn't very
+                        // correct here
                         Slog.w(TAG, "Failed to report initialization status: " + e);
+                        HotwordMetricsLogger.writeServiceInitResultEvent(mDetectorType,
+                                METRICS_INIT_CALLBACK_STATE_ERROR);
                     }
                 }
             };
             try {
                 service.updateState(options, sharedMemory, statusCallback);
+                HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                        HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_UPDATE_STATE,
+                        mVoiceInteractionServiceUid);
             } catch (RemoteException e) {
                 // TODO: (b/181842909) Report an error to voice interactor
                 Slog.w(TAG, "Failed to updateState for HotwordDetectionService", e);
@@ -253,8 +310,12 @@
                         }
                         try {
                             mCallback.onStatusReported(INITIALIZATION_STATUS_UNKNOWN);
+                            HotwordMetricsLogger.writeServiceInitResultEvent(mDetectorType,
+                                    METRICS_INIT_UNKNOWN_TIMEOUT);
                         } catch (RemoteException e) {
                             Slog.w(TAG, "Failed to report initialization status UNKNOWN", e);
+                            HotwordMetricsLogger.writeServiceInitResultEvent(mDetectorType,
+                                    METRICS_INIT_CALLBACK_STATE_ERROR);
                         }
                     } else if (err != null) {
                         Slog.w(TAG, "Failed to update state: " + err);
@@ -264,6 +325,23 @@
                 });
     }
 
+    private static Pair<Integer, Integer> getInitStatusAndMetricsResult(Bundle bundle) {
+        if (bundle == null) {
+            return new Pair<>(INITIALIZATION_STATUS_UNKNOWN, METRICS_INIT_UNKNOWN_NO_VALUE);
+        }
+        int status = bundle.getInt(KEY_INITIALIZATION_STATUS, INITIALIZATION_STATUS_UNKNOWN);
+        if (status > HotwordDetectionService.getMaxCustomInitializationStatus()
+                && status != INITIALIZATION_STATUS_UNKNOWN) {
+            return new Pair<>(INITIALIZATION_STATUS_UNKNOWN,
+                    METRICS_INIT_UNKNOWN_OVER_MAX_CUSTOM_VALUE);
+        }
+        // TODO: should guard against negative here
+        int metricsResult = status == INITIALIZATION_STATUS_UNKNOWN
+                ? METRICS_INIT_CALLBACK_STATE_ERROR
+                : METRICS_INIT_CALLBACK_STATE_SUCCESS;
+        return new Pair<>(status, metricsResult);
+    }
+
     private boolean isBound() {
         synchronized (mLock) {
             return mRemoteHotwordDetectionService.isBound();
@@ -281,7 +359,9 @@
             removeServiceUidForAudioPolicy(mIdentity.getIsolatedUid());
         }
         mIdentity = null;
-        mCancellationTaskFuture.cancel(/* may interrupt */ true);
+        if (mCancellationTaskFuture != null) {
+            mCancellationTaskFuture.cancel(/* may interrupt */ true);
+        }
         if (mAudioFlinger != null) {
             mAudioFlinger.unlinkToDeath(mAudioServerDeathRecipient, /* flags= */ 0);
         }
@@ -480,12 +560,31 @@
                     Slog.d(TAG, "onDetected");
                 }
                 synchronized (mLock) {
+                    // TODO: If the dsp trigger comes in after the timeout, we will log both events.
+                    // Because we don't enforce the timeout yet. We should add some synchronizations
+                    // within the runnable to prevent the race condition to log both events.
+                    if (mCancellationKeyPhraseDetectionFuture != null) {
+                        mCancellationKeyPhraseDetectionFuture.cancel(true);
+                    }
+                    HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                            mDetectorType,
+                            HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED);
                     if (!mValidatingDspTrigger) {
                         Slog.i(TAG, "Ignoring #onDetected due to a process restart");
+                        HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                                mDetectorType,
+                                HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_EXCEPTION);
                         return;
                     }
                     mValidatingDspTrigger = false;
-                    enforcePermissionsForDataDelivery();
+                    try {
+                        enforcePermissionsForDataDelivery();
+                    } catch (SecurityException e) {
+                        HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                                mDetectorType,
+                                HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_EXCEPTION);
+                        throw e;
+                    }
                     externalCallback.onKeyphraseDetected(recognitionEvent, result);
                     if (result != null) {
                         Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result)
@@ -503,8 +602,17 @@
                     Slog.d(TAG, "onRejected");
                 }
                 synchronized (mLock) {
+                    if (mCancellationKeyPhraseDetectionFuture != null) {
+                        mCancellationKeyPhraseDetectionFuture.cancel(true);
+                    }
+                    HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                            mDetectorType,
+                            HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED);
                     if (!mValidatingDspTrigger) {
                         Slog.i(TAG, "Ignoring #onRejected due to a process restart");
+                        HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                                mDetectorType,
+                                HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_EXCEPTION);
                         return;
                     }
                     mValidatingDspTrigger = false;
@@ -519,11 +627,20 @@
         synchronized (mLock) {
             mValidatingDspTrigger = true;
             mRemoteHotwordDetectionService.run(
-                    service -> service.detectFromDspSource(
-                            recognitionEvent,
-                            recognitionEvent.getCaptureFormat(),
-                            VALIDATION_TIMEOUT_MILLIS,
-                            internalCallback));
+                    service -> {
+                        // TODO: avoid allocate every time
+                        mCancellationKeyPhraseDetectionFuture = mScheduledExecutorService.schedule(
+                                () -> HotwordMetricsLogger
+                                        .writeKeyphraseTriggerEvent(mDetectorType,
+                                        HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_TIMEOUT),
+                                VALIDATION_TIMEOUT_MILLIS,
+                                TimeUnit.MILLISECONDS);
+                        service.detectFromDspSource(
+                                recognitionEvent,
+                                recognitionEvent.getCaptureFormat(),
+                                VALIDATION_TIMEOUT_MILLIS,
+                                internalCallback);
+                    });
         }
     }
 
@@ -624,10 +741,16 @@
             }
             final boolean useHotwordDetectionService = mHotwordDetectionConnection != null;
             if (useHotwordDetectionService) {
+                HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                        HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP,
+                        HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER);
                 mRecognitionEvent = recognitionEvent;
                 mHotwordDetectionConnection.detectFromDspSource(
                         recognitionEvent, mExternalCallback);
             } else {
+                HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                        HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR,
+                        HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER);
                 mExternalCallback.onKeyphraseDetected(recognitionEvent, null);
             }
         }
@@ -656,6 +779,7 @@
     }
 
     public void dump(String prefix, PrintWriter pw) {
+        pw.print(prefix); pw.print("RESTART_PERIOD_SECONDS="); pw.println(RESTART_PERIOD_SECONDS);
         pw.print(prefix);
         pw.print("mBound=" + mRemoteHotwordDetectionService.isBound());
         pw.print(", mValidatingDspTrigger=" + mValidatingDspTrigger);
@@ -772,7 +896,8 @@
         ServiceConnection createLocked() {
             ServiceConnection connection =
                     new ServiceConnection(mContext, mIntent, mBindingFlags, mUser,
-                            IHotwordDetectionService.Stub::asInterface, ++mRestartCount);
+                            IHotwordDetectionService.Stub::asInterface,
+                            mRestartCount++ % MAX_ISOLATED_PROCESS_NUMBER);
             connection.connect();
 
             updateAudioFlinger(connection, mAudioFlinger);
@@ -791,6 +916,7 @@
 
         private boolean mRespectServiceConnectionStatusChanged = true;
         private boolean mIsBound = false;
+        private boolean mIsLoggedFirstConnect = false;
 
         ServiceConnection(@NonNull Context context,
                 @NonNull Intent intent, int bindingFlags, int userId,
@@ -814,6 +940,12 @@
                     return;
                 }
                 mIsBound = connected;
+                if (connected && !mIsLoggedFirstConnect) {
+                    mIsLoggedFirstConnect = true;
+                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                            HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED,
+                            mVoiceInteractionServiceUid);
+                }
             }
         }
 
@@ -844,13 +976,25 @@
         protected boolean bindService(
                 @NonNull android.content.ServiceConnection serviceConnection) {
             try {
-                return mContext.bindIsolatedService(
+                HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                        HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE,
+                        mVoiceInteractionServiceUid);
+                boolean bindResult = mContext.bindIsolatedService(
                         mIntent,
                         Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE | mBindingFlags,
                         "hotword_detector_" + mInstanceNumber,
                         mExecutor,
                         serviceConnection);
+                if (!bindResult) {
+                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                            HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL,
+                            mVoiceInteractionServiceUid);
+                }
+                return bindResult;
             } catch (IllegalArgumentException e) {
+                HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                        HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL,
+                        mVoiceInteractionServiceUid);
                 Slog.wtf(TAG, "Can't bind to the hotword detection service!", e);
                 return false;
             }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
new file mode 100644
index 0000000..940aed3
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
@@ -0,0 +1,154 @@
+/*
+ * 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.voiceinteraction;
+
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__NORMAL_DETECTOR;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__NORMAL_DETECTOR;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__NORMAL_DETECTOR;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+
+import android.service.voice.HotwordDetector;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+/**
+ * A utility class for logging hotword statistics event.
+ */
+public final class HotwordMetricsLogger {
+
+    private static final int METRICS_INIT_DETECTOR_SOFTWARE =
+            HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+    private static final int METRICS_INIT_DETECTOR_DSP =
+            HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+    private static final int METRICS_INIT_NORMAL_DETECTOR =
+            HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
+
+    private HotwordMetricsLogger() {
+        // Class only contains static utility functions, and should not be instantiated
+    }
+
+    /**
+     * Logs information related to create hotword detector.
+     */
+    public static void writeDetectorCreateEvent(int detectorType, boolean isCreated, int uid) {
+        int metricsDetectorType = getCreateMetricsDetectorType(detectorType);
+        FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_CREATE_REQUESTED,
+                metricsDetectorType, isCreated, uid);
+    }
+
+    /**
+     * Logs information related to hotword detection service init result.
+     */
+    public static void writeServiceInitResultEvent(int detectorType, int result) {
+        int metricsDetectorType = getInitMetricsDetectorType(detectorType);
+        FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED,
+                metricsDetectorType, result);
+    }
+
+    /**
+     * Logs information related to hotword detection service restarting.
+     */
+    public static void writeServiceRestartEvent(int detectorType, int reason) {
+        int metricsDetectorType = getRestartMetricsDetectorType(detectorType);
+        FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED,
+                metricsDetectorType, reason);
+    }
+
+    /**
+     * Logs information related to keyphrase trigger.
+     */
+    public static void writeKeyphraseTriggerEvent(int detectorType, int result) {
+        int metricsDetectorType = getKeyphraseMetricsDetectorType(detectorType);
+        FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED,
+                metricsDetectorType, result);
+    }
+
+    /**
+     * Logs information related to hotword detector events.
+     */
+    public static void writeDetectorEvent(int detectorType, int event, int uid) {
+        int metricsDetectorType = getDetectorMetricsDetectorType(detectorType);
+        FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS,
+                metricsDetectorType, event, uid);
+    }
+
+    private static int getCreateMetricsDetectorType(int detectorType) {
+        switch (detectorType) {
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
+                return HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
+                return HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+            default:
+                return HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__NORMAL_DETECTOR;
+        }
+    }
+
+    private static int getRestartMetricsDetectorType(int detectorType) {
+        switch (detectorType) {
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
+                return HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
+                return HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+            default:
+                return HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__NORMAL_DETECTOR;
+        }
+    }
+
+    private static int getInitMetricsDetectorType(int detectorType) {
+        switch (detectorType) {
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
+                return METRICS_INIT_DETECTOR_SOFTWARE;
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
+                return METRICS_INIT_DETECTOR_DSP;
+            default:
+                return METRICS_INIT_NORMAL_DETECTOR;
+        }
+    }
+
+    private static int getKeyphraseMetricsDetectorType(int detectorType) {
+        switch (detectorType) {
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
+                return HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
+                return HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+            default:
+                return HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR;
+        }
+    }
+
+    private static int getDetectorMetricsDetectorType(int detectorType) {
+        switch (detectorType) {
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
+                return HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
+                return HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+            default:
+                return HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__NORMAL_DETECTOR;
+        }
+    }
+}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index fb4d73c..0519873 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -462,24 +462,33 @@
             IHotwordRecognitionStatusCallback callback,
             int detectorType) {
         Slog.v(TAG, "updateStateLocked");
+        int voiceInteractionServiceUid = mInfo.getServiceInfo().applicationInfo.uid;
         if (mHotwordDetectionComponentName == null) {
             Slog.w(TAG, "Hotword detection service name not found");
+            logDetectorCreateEventIfNeeded(callback, detectorType, false,
+                    voiceInteractionServiceUid);
             throw new IllegalStateException("Hotword detection service name not found");
         }
         ServiceInfo hotwordDetectionServiceInfo = getServiceInfoLocked(
                 mHotwordDetectionComponentName, mUser);
         if (hotwordDetectionServiceInfo == null) {
             Slog.w(TAG, "Hotword detection service info not found");
+            logDetectorCreateEventIfNeeded(callback, detectorType, false,
+                    voiceInteractionServiceUid);
             throw new IllegalStateException("Hotword detection service info not found");
         }
         if (!isIsolatedProcessLocked(hotwordDetectionServiceInfo)) {
             Slog.w(TAG, "Hotword detection service not in isolated process");
+            logDetectorCreateEventIfNeeded(callback, detectorType, false,
+                    voiceInteractionServiceUid);
             throw new IllegalStateException("Hotword detection service not in isolated process");
         }
         if (!Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE.equals(
                 hotwordDetectionServiceInfo.permission)) {
             Slog.w(TAG, "Hotword detection service does not require permission "
                     + Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE);
+            logDetectorCreateEventIfNeeded(callback, detectorType, false,
+                    voiceInteractionServiceUid);
             throw new SecurityException("Hotword detection service does not require permission "
                     + Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE);
         }
@@ -488,17 +497,23 @@
                 mInfo.getServiceInfo().packageName) == PackageManager.PERMISSION_GRANTED) {
             Slog.w(TAG, "Voice interaction service should not hold permission "
                     + Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE);
+            logDetectorCreateEventIfNeeded(callback, detectorType, false,
+                    voiceInteractionServiceUid);
             throw new SecurityException("Voice interaction service should not hold permission "
                     + Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE);
         }
 
         if (sharedMemory != null && !sharedMemory.setProtect(OsConstants.PROT_READ)) {
             Slog.w(TAG, "Can't set sharedMemory to be read-only");
+            logDetectorCreateEventIfNeeded(callback, detectorType, false,
+                    voiceInteractionServiceUid);
             throw new IllegalStateException("Can't set sharedMemory to be read-only");
         }
 
         mDetectorType = detectorType;
 
+        logDetectorCreateEventIfNeeded(callback, detectorType, true,
+                voiceInteractionServiceUid);
         if (mHotwordDetectionConnection == null) {
             mHotwordDetectionConnection = new HotwordDetectionConnection(mServiceStub, mContext,
                     mInfo.getServiceInfo().applicationInfo.uid, voiceInteractorIdentity,
@@ -509,6 +524,15 @@
         }
     }
 
+    private void logDetectorCreateEventIfNeeded(IHotwordRecognitionStatusCallback callback,
+            int detectorType, boolean isCreated, int voiceInteractionServiceUid) {
+        if (callback != null) {
+            HotwordMetricsLogger.writeDetectorCreateEvent(detectorType, true,
+                    voiceInteractionServiceUid);
+        }
+
+    }
+
     public void shutdownHotwordDetectionServiceLocked() {
         if (DEBUG) {
             Slog.d(TAG, "shutdownHotwordDetectionServiceLocked");
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 27d423b..bce6809 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -3171,9 +3171,14 @@
      *
      * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, android.os.Bundle)}.
      *
+     * @param connectionManagerPhoneAccount The connection manager account to use for managing
+     *                                      this call
+     * @param request Details about the outgoing call
+     * @return The {@code Connection} object to satisfy this call, or the result of an invocation
+     *         of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call
      * @hide
      */
-    @SystemApi
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public @Nullable Connection onCreateUnknownConnection(
             @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index 3a3b363..d2a4c3e 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -1090,6 +1090,13 @@
      */
     public static final int NO_RETRY_FAILURE = 0x1000B;
 
+    /**
+     * Traffic descriptors in DataCallResponse is empty.
+     *
+     * @hide
+     */
+    public static final int NO_TRAFFIC_DESCRIPTORS = 0x1000C;
+
     private static final Map<Integer, String> sFailCauseMap;
     static {
         sFailCauseMap = new HashMap<>();
@@ -1524,6 +1531,7 @@
         sFailCauseMap.put(SERVICE_TEMPORARILY_UNAVAILABLE, "SERVICE_TEMPORARILY_UNAVAILABLE");
         sFailCauseMap.put(REQUEST_NOT_SUPPORTED, "REQUEST_NOT_SUPPORTED");
         sFailCauseMap.put(NO_RETRY_FAILURE, "NO_RETRY_FAILURE");
+        sFailCauseMap.put(NO_TRAFFIC_DESCRIPTORS, "NO_TRAFFIC_DESCRIPTORS");
     }
 
     private DataFailCause() {
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 0aaafef..b6cacaf 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1976,7 +1976,7 @@
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public void addSubscriptionInfoRecord(@NonNull String uniqueId, @Nullable String displayName,
-            int slotIndex, int subscriptionType) {
+            int slotIndex, @SubscriptionType int subscriptionType) {
         if (VDBG) {
             logd("[addSubscriptionInfoRecord]+ uniqueId:" + uniqueId
                     + ", displayName:" + displayName + ", slotIndex:" + slotIndex
@@ -2012,7 +2012,8 @@
      * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public void removeSubscriptionInfoRecord(@NonNull String uniqueId, int subscriptionType) {
+    public void removeSubscriptionInfoRecord(@NonNull String uniqueId,
+            @SubscriptionType int subscriptionType) {
         if (VDBG) {
             logd("[removeSubscriptionInfoRecord]+ uniqueId:" + uniqueId
                     + ", subscriptionType: " + subscriptionType);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 1eb391d..3f430ab 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8352,24 +8352,6 @@
     }
 
     /**
-     * Get P-CSCF address from PCO after data connection is established or modified.
-     * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
-     * @return array of P-CSCF address
-     * @hide
-     */
-    public String[] getPcscfAddress(String apnType) {
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony == null)
-                return new String[0];
-            return telephony.getPcscfAddress(apnType, getOpPackageName(), getAttributionTag());
-        } catch (RemoteException e) {
-            return new String[0];
-        }
-    }
-
-
-    /**
      * Resets the {@link android.telephony.ims.ImsService} associated with the specified sim slot.
      * Used by diagnostic apps to force the IMS stack to be disabled and re-enabled in an effort to
      * recover from scenarios where the {@link android.telephony.ims.ImsService} gets in to a bad
@@ -16790,7 +16772,10 @@
      * Callback to listen for when the set of packages with carrier privileges for a SIM changes.
      *
      * @hide
+     * @deprecated Use {@link CarrierPrivilegesCallback} instead. This API will be removed soon
+     * prior to API finalization.
      */
+    @Deprecated
     @SystemApi
     public interface CarrierPrivilegesListener {
         /**
@@ -16810,6 +16795,54 @@
     }
 
     /**
+     * Callbacks to listen for when the set of packages with carrier privileges for a SIM changes.
+     *
+     * <p>Of note, when multiple callbacks are registered, they may be triggered one after another.
+     * The ordering of them is not guaranteed and thus should not be depend on.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface CarrierPrivilegesCallback {
+        /**
+         * Called when the set of packages with carrier privileges has changed.
+         *
+         * <p>Of note, this callback will <b>not</b> be fired if a carrier triggers a SIM profile
+         * switch and the same set of packages remains privileged after the switch.
+         *
+         * <p>At registration, the callback will receive the current set of privileged packages.
+         *
+         * @param privilegedPackageNames The updated set of package names that have carrier
+         *                               privileges
+         * @param privilegedUids         The updated set of UIDs that have carrier privileges
+         */
+        void onCarrierPrivilegesChanged(
+                @NonNull Set<String> privilegedPackageNames, @NonNull Set<Integer> privilegedUids);
+
+        /**
+         * Called when the {@link CarrierService} for the current user profile has changed.
+         *
+         * <p>This method does nothing by default. Clients that are interested in the carrier
+         * service change should override this method to get package name and UID info.
+         *
+         * <p>At registration, the callback will receive the current carrier service info.
+         *
+         * <p>Of note, this callback will <b>not</b> be fired if a carrier triggers a SIM profile
+         * switch and the same carrier service remains after switch.
+         *
+         * @param carrierServicePackageName package name of the {@link CarrierService}. May be
+         *                                  {@code null} when no carrier service is detected.
+         * @param carrierServiceUid         UID of the {@link CarrierService}. May be
+         *                                  {@link android.os.Process#INVALID_UID} if no carrier
+         *                                  service is detected.
+         */
+        default void onCarrierServiceChanged(
+                @Nullable String carrierServicePackageName, int carrierServiceUid) {
+            // do nothing by default
+        }
+    }
+
+    /**
      * Registers a {@link CarrierPrivilegesListener} on the given {@code logicalSlotIndex} to
      * receive callbacks when the set of packages with carrier privileges changes. The callback will
      * immediately be called with the latest state.
@@ -16818,7 +16851,10 @@
      * @param executor The executor where {@code listener} will be invoked
      * @param listener The callback to register
      * @hide
+     * @deprecated Use {@link #unregisterCarrierPrivilegesCallback} instead. This API will be
+     * removed prior to API finalization.
      */
+    @Deprecated
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public void addCarrierPrivilegesListener(
@@ -16842,7 +16878,10 @@
      * Unregisters an existing {@link CarrierPrivilegesListener}.
      *
      * @hide
+     * @deprecated Use {@link #unregisterCarrierPrivilegesCallback} instead. This API will be
+     * removed prior to API finalization.
      */
+    @Deprecated
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public void removeCarrierPrivilegesListener(@NonNull CarrierPrivilegesListener listener) {
@@ -16890,4 +16929,53 @@
             ex.rethrowAsRuntimeException();
         }
     }
+
+    /**
+     * Registers a {@link CarrierPrivilegesCallback} on the given {@code logicalSlotIndex} to
+     * receive callbacks when the set of packages with carrier privileges changes. The callback will
+     * immediately be called with the latest state.
+     *
+     * @param logicalSlotIndex The SIM slot to listen on
+     * @param executor The executor where {@code callback} will be invoked
+     * @param callback The callback to register
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public void registerCarrierPrivilegesCallback(
+            int logicalSlotIndex,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull CarrierPrivilegesCallback callback) {
+        if (mContext == null) {
+            throw new IllegalStateException("Telephony service is null");
+        } else if (executor == null || callback == null) {
+            throw new IllegalArgumentException(
+                    "CarrierPrivilegesCallback and executor must be non-null");
+        }
+        mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
+        if (mTelephonyRegistryMgr == null) {
+            throw new IllegalStateException("Telephony registry service is null");
+        }
+        mTelephonyRegistryMgr.addCarrierPrivilegesCallback(logicalSlotIndex, executor, callback);
+    }
+
+    /**
+     * Unregisters an existing {@link CarrierPrivilegesCallback}.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public void unregisterCarrierPrivilegesCallback(@NonNull CarrierPrivilegesCallback callback) {
+        if (mContext == null) {
+            throw new IllegalStateException("Telephony service is null");
+        } else if (callback == null) {
+            throw new IllegalArgumentException("CarrierPrivilegesCallback must be non-null");
+        }
+        mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
+        if (mTelephonyRegistryMgr == null) {
+            throw new IllegalStateException("Telephony registry service is null");
+        }
+        mTelephonyRegistryMgr.removeCarrierPrivilegesCallback(callback);
+    }
 }
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index fc94ebf..532679c 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1103,8 +1103,10 @@
         sb.append(", ").append(MVNO_TYPE_INT_MAP.get(mMvnoType));
         sb.append(", ").append(mMvnoMatchData);
         sb.append(", ").append(mPermanentFailed);
-        sb.append(", ").append(mNetworkTypeBitmask);
-        sb.append(", ").append(mLingeringNetworkTypeBitmask);
+        sb.append(", ").append(TelephonyManager.convertNetworkTypeBitmaskToString(
+                mNetworkTypeBitmask));
+        sb.append(", ").append(TelephonyManager.convertNetworkTypeBitmaskToString(
+                mLingeringNetworkTypeBitmask));
         sb.append(", ").append(mApnSetId);
         sb.append(", ").append(mCarrierId);
         sb.append(", ").append(mSkip464Xlat);
diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index ec73471..77d4837 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -50,12 +50,13 @@
      */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({RESULT_SUCCESS, RESULT_ERROR_UNSUPPORTED, RESULT_ERROR_INVALID_ARG, RESULT_ERROR_BUSY,
-            RESULT_ERROR_ILLEGAL_STATE})
+            RESULT_ERROR_ILLEGAL_STATE, RESULT_ERROR_TEMPORARILY_UNAVAILABLE,
+            RESULT_ERROR_INVALID_RESPONSE})
     public @interface ResultCode {}
 
     /** Request is completed successfully */
     public static final int RESULT_SUCCESS              = 0;
-    /** Request is not support */
+    /** Request is not supported */
     public static final int RESULT_ERROR_UNSUPPORTED    = 1;
     /** Request contains invalid arguments */
     public static final int RESULT_ERROR_INVALID_ARG    = 2;
@@ -68,6 +69,11 @@
      * @hide
      */
     public static final int RESULT_ERROR_TEMPORARILY_UNAVAILABLE = 5;
+    /**
+     * Request failed to complete due to an invalid response.
+     * @hide
+     */
+    public static final int RESULT_ERROR_INVALID_RESPONSE = 6;
 
     private final IDataServiceCallback mCallback;
 
@@ -255,6 +261,8 @@
                 return "RESULT_ERROR_ILLEGAL_STATE";
             case RESULT_ERROR_TEMPORARILY_UNAVAILABLE:
                 return "RESULT_ERROR_TEMPORARILY_UNAVAILABLE";
+            case RESULT_ERROR_INVALID_RESPONSE:
+                return "RESULT_ERROR_INVALID_RESPONSE";
             default:
                 return "Unknown(" + resultCode + ")";
         }
diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
index 493ad5e..1ccb464 100644
--- a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
@@ -48,6 +48,9 @@
         @Override
         public void sendMessage(SipMessage sipMessage, long configVersion) {
             SipDelegate d = mDelegate;
+            if (d == null) {
+                return;
+            }
             final long token = Binder.clearCallingIdentity();
             try {
                 mExecutor.execute(() -> d.sendMessage(sipMessage, configVersion));
@@ -59,6 +62,9 @@
         @Override
         public void notifyMessageReceived(String viaTransactionId)  {
             SipDelegate d = mDelegate;
+            if (d == null) {
+                return;
+            }
             final long token = Binder.clearCallingIdentity();
             try {
                 mExecutor.execute(() -> d.notifyMessageReceived(viaTransactionId));
@@ -71,6 +77,9 @@
         @Override
         public void notifyMessageReceiveError(String viaTransactionId, int reason) {
             SipDelegate d = mDelegate;
+            if (d == null) {
+                return;
+            }
             final long token = Binder.clearCallingIdentity();
             try {
                 mExecutor.execute(() -> d.notifyMessageReceiveError(viaTransactionId, reason));
@@ -83,6 +92,9 @@
         @Override
         public void cleanupSession(String callId)  {
             SipDelegate d = mDelegate;
+            if (d == null) {
+                return;
+            }
             final long token = Binder.clearCallingIdentity();
             try {
                 mExecutor.execute(() -> d.cleanupSession(callId));
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index dc96b35..a5e2c1f 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -978,14 +978,6 @@
      boolean isManualNetworkSelectionAllowed(int subId);
 
     /**
-     * Get P-CSCF address from PCO after data connection is established or modified.
-     * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
-     * @param callingPackage The package making the call.
-     * @param callingFeatureId The feature in the package.
-     */
-    String[] getPcscfAddress(String apnType, String callingPackage, String callingFeatureId);
-
-    /**
      * Set IMS registration state
      */
     void setImsRegistrationState(boolean registered);
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index b905212..546d2ce 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -424,4 +424,24 @@
      */
     @Deprecated
     public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable";
+
+    /**
+     * <p>Broadcast sent to show Emergency notification due to Voice Over Wifi availability
+     *
+     * <p class="note">
+     * You can <em>not</em> receive this through components declared
+     * in manifests, only by explicitly registering for it with
+     * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver,
+     * android.content.IntentFilter) Context.registerReceiver()}.
+     *
+     * <p class="note">
+     * Requires no permission.
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system.
+     *
+     * @hide
+     */
+    public static final String ACTION_VOWIFI_ENABLED
+            = "com.android.internal.telephony.ACTION_VOWIFI_ENABLED";
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
index 71e576a..7f49663 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
@@ -44,7 +44,6 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 219749605)
 class LaunchAppShowImeAndDialogThemeAppTest(private val testSpec: FlickerTestParameter) {
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
     private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
index a9564fd..e7a3354 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
@@ -46,6 +46,7 @@
 import com.android.server.wm.traces.common.WindowManagerConditionsFactory
 import org.junit.Assume.assumeFalse
 import org.junit.Assume.assumeTrue
+import org.junit.Before
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -61,8 +62,7 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group2
-@FlakyTest(bugId = 219757170)
-class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) {
+open class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) {
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
     private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
 
@@ -72,6 +72,11 @@
         WindowManagerConditionsFactory.isHomeActivityVisible()
     ))
 
+    @Before
+    open fun before() {
+        assumeFalse(isShellTransitionsEnabled)
+    }
+
     @FlickerBuilderProvider
     fun buildFlicker(): FlickerBuilder {
         return FlickerBuilder(instrumentation).apply {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt
new file mode 100644
index 0000000..7ffa513
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.wm.flicker.ime
+
+import android.platform.test.annotations.Postsubmit
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.annotation.Group2
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test IME window opening transitions.
+ * To run this test: `atest FlickerTests:ReOpenImeWindowTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Group2
+@FlakyTest(bugId = 221854428)
+class ReOpenImeWindowTest_ShellTransit(private val testSpec: FlickerTestParameter)
+    : ReOpenImeWindowTest(testSpec) {
+    @Before
+    override fun before() {
+        Assume.assumeTrue(isShellTransitionsEnabled)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
index b0e53e9..c3a4769 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
@@ -74,7 +74,7 @@
      * Checks that the nav bar layer starts invisible, becomes visible during unlocking animation
      * and remains visible at the end
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun navBarLayerVisibilityChanges() {
         testSpec.assertLayers {
diff --git a/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java b/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
index 18f9623..bf8bd14 100644
--- a/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
+++ b/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
@@ -18,11 +18,13 @@
 import android.annotation.Nullable;
 import android.inputmethodservice.InputMethodService;
 import android.util.Log;
+import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
 import android.widget.FrameLayout;
+import android.widget.TextView;
 import android.widget.Toast;
 
 import java.util.Random;
@@ -79,6 +81,14 @@
         view.setPadding(0, 0, 0, 0);
         view.addView(inner, new FrameLayout.LayoutParams(
                 FrameLayout.LayoutParams.MATCH_PARENT, height));
+        TextView text = new TextView(this);
+        text.setText("Handwriting IME");
+        text.setTextSize(13f);
+        text.setTextColor(getColor(android.R.color.white));
+        text.setGravity(Gravity.CENTER);
+        text.setLayoutParams(new FrameLayout.LayoutParams(
+                FrameLayout.LayoutParams.MATCH_PARENT, height));
+        view.addView(text);
         inner.setBackgroundColor(0xff0110fe); // blue
 
         return view;
diff --git a/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java b/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
index 4ffdc92..87a5b90 100644
--- a/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
+++ b/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
@@ -33,6 +33,7 @@
     private static final long FINISH_TIMEOUT = 2500;
     private final HandwritingIme.HandwritingFinisher mHwCanceller;
     private final HandwritingIme.StylusConsumer mConsumer;
+    private final int mTopInset;
     private Paint mPaint;
     private Path  mPath;
     private float mX, mY;
@@ -63,6 +64,7 @@
         setLayoutParams(new ViewGroup.LayoutParams(
                 metrics.getBounds().width() - insets.left - insets.right,
                 metrics.getBounds().height() - insets.top - insets.bottom));
+        mTopInset = insets.top;
     }
 
     @Override
@@ -74,12 +76,14 @@
     }
 
     private void stylusStart(float x, float y) {
+        y = y - mTopInset;
         mPath.moveTo(x, y);
         mX = x;
         mY = y;
     }
 
     private void stylusMove(float x, float y) {
+        y = y - mTopInset;
         float dx = Math.abs(x - mX);
         float dy = Math.abs(y - mY);
         if (mPath.isEmpty()) {
diff --git a/tests/TrustTests/AndroidManifest.xml b/tests/TrustTests/AndroidManifest.xml
index c94152d..68bc1f69 100644
--- a/tests/TrustTests/AndroidManifest.xml
+++ b/tests/TrustTests/AndroidManifest.xml
@@ -23,7 +23,9 @@
     <uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" />
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
     <uses-permission android:name="android.permission.DEVICE_POWER" />
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <uses-permission android:name="android.permission.MANAGE_USERS" />
     <uses-permission android:name="android.permission.PROVIDE_TRUST_AGENT" />
     <uses-permission android:name="android.permission.TRUST_LISTENER" />
 
diff --git a/tests/TrustTests/TEST_MAPPING b/tests/TrustTests/TEST_MAPPING
new file mode 100644
index 0000000..b9c46bf
--- /dev/null
+++ b/tests/TrustTests/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+  "presubmit": [
+    {
+      "name": "TrustTests",
+      "options": [
+        {
+          "include-filter": "android.trust.test"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tests/TrustTests/src/android/trust/test/LockUserTest.kt b/tests/TrustTests/src/android/trust/test/LockUserTest.kt
index 83fc28f..8f200a6 100644
--- a/tests/TrustTests/src/android/trust/test/LockUserTest.kt
+++ b/tests/TrustTests/src/android/trust/test/LockUserTest.kt
@@ -25,7 +25,6 @@
 import androidx.test.ext.junit.rules.ActivityScenarioRule
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.google.common.truth.Truth.assertThat
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.RuleChain
@@ -49,7 +48,6 @@
         .around(lockStateTrackingRule)
         .around(trustAgentRule)
 
-    @Ignore("Causes issues with subsequent tests") // TODO: Enable test
     @Test
     fun lockUser_locksTheDevice() {
         Log.i(TAG, "Locking user")
diff --git a/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt b/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
index bc100ba..006525d 100644
--- a/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
+++ b/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
@@ -20,6 +20,8 @@
 import android.util.Log
 import android.view.WindowManagerGlobal
 import androidx.test.core.app.ApplicationProvider.getApplicationContext
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import androidx.test.uiautomator.UiDevice
 import com.android.internal.widget.LockPatternUtils
 import com.android.internal.widget.LockscreenCredential
 import com.google.common.truth.Truth.assertWithMessage
@@ -32,6 +34,7 @@
  */
 class ScreenLockRule : TestRule {
     private val context: Context = getApplicationContext()
+    private val uiDevice = UiDevice.getInstance(getInstrumentation())
     private val windowManager = WindowManagerGlobal.getWindowManagerService()
     private val lockPatternUtils = LockPatternUtils(context)
     private var instantLockSavedValue = false
@@ -48,19 +51,21 @@
             } finally {
                 removeScreenLock()
                 revertLockOnPowerButton()
+                verifyKeyguardDismissed()
             }
         }
     }
 
     private fun verifyNoScreenLockAlreadySet() {
         assertWithMessage("Screen Lock must not already be set on device")
-            .that(lockPatternUtils.isSecure(context.userId))
-            .isFalse()
+                .that(lockPatternUtils.isSecure(context.userId))
+                .isFalse()
     }
 
     private fun verifyKeyguardDismissed() {
         val maxWaits = 30
         var waitCount = 0
+
         while (windowManager.isKeyguardLocked && waitCount < maxWaits) {
             Log.i(TAG, "Keyguard still showing; attempting to dismiss and wait 50ms ($waitCount)")
             windowManager.dismissKeyguard(null, null)
@@ -68,19 +73,19 @@
             waitCount++
         }
         assertWithMessage("Keyguard should be unlocked")
-            .that(windowManager.isKeyguardLocked)
-            .isFalse()
+                .that(windowManager.isKeyguardLocked)
+                .isFalse()
     }
 
     private fun setScreenLock() {
         lockPatternUtils.setLockCredential(
-            LockscreenCredential.createPin(PIN),
-            LockscreenCredential.createNone(),
-            context.userId
+                LockscreenCredential.createPin(PIN),
+                LockscreenCredential.createNone(),
+                context.userId
         )
         assertWithMessage("Screen Lock should now be set")
-            .that(lockPatternUtils.isSecure(context.userId))
-            .isTrue()
+                .that(lockPatternUtils.isSecure(context.userId))
+                .isTrue()
         Log.i(TAG, "Device PIN set to $PIN")
     }
 
@@ -90,14 +95,25 @@
     }
 
     private fun removeScreenLock() {
-        lockPatternUtils.setLockCredential(
-            LockscreenCredential.createNone(),
-            LockscreenCredential.createPin(PIN),
-            context.userId
-        )
-        Log.i(TAG, "Device PIN cleared; waiting 50 ms then dismissing Keyguard")
-        Thread.sleep(50)
-        windowManager.dismissKeyguard(null, null)
+        var lockCredentialUnset = lockPatternUtils.setLockCredential(
+                LockscreenCredential.createNone(),
+                LockscreenCredential.createPin(PIN),
+                context.userId)
+        Thread.sleep(100)
+        assertWithMessage("Lock screen credential should be unset")
+                .that(lockCredentialUnset)
+                .isTrue()
+
+        lockPatternUtils.setLockScreenDisabled(true, context.userId)
+        Thread.sleep(100)
+        assertWithMessage("Lockscreen needs to be disabled")
+                .that(lockPatternUtils.isLockScreenDisabled(context.userId))
+                .isTrue()
+
+        // this is here because somehow it helps the keyguard not get stuck
+        uiDevice.sleep()
+        Thread.sleep(500) // delay added to avoid initiating camera by double clicking power
+        uiDevice.wakeUp()
     }
 
     private fun revertLockOnPowerButton() {
diff --git a/tests/componentalias/src/android/content/componentalias/tests/BaseComponentAliasTest.java b/tests/componentalias/src/android/content/componentalias/tests/BaseComponentAliasTest.java
index 9658d6f..164f61c 100644
--- a/tests/componentalias/src/android/content/componentalias/tests/BaseComponentAliasTest.java
+++ b/tests/componentalias/src/android/content/componentalias/tests/BaseComponentAliasTest.java
@@ -37,7 +37,7 @@
     protected static final Context sContext = InstrumentationRegistry.getTargetContext();
 
     protected static final DeviceConfigStateHelper sDeviceConfig = new DeviceConfigStateHelper(
-            DeviceConfig.NAMESPACE_ACTIVITY_MANAGER);
+            DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS);
     @Before
     public void enableComponentAliasWithCompatFlag() throws Exception {
         Assume.assumeTrue(Build.isDebuggable());
diff --git a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasEnableWithDeviceConfigTest.java b/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasEnableWithDeviceConfigTest.java
index 52c6d5b..ee20379 100644
--- a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasEnableWithDeviceConfigTest.java
+++ b/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasEnableWithDeviceConfigTest.java
@@ -28,7 +28,7 @@
 
 public class ComponentAliasEnableWithDeviceConfigTest {
     protected static final DeviceConfigStateHelper sDeviceConfig = new DeviceConfigStateHelper(
-            DeviceConfig.NAMESPACE_ACTIVITY_MANAGER);
+            DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS);
 
     @AfterClass
     public static void restoreDeviceConfig() throws Exception {
diff --git a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasNotSupportedOnUserBuildTest.java b/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasNotSupportedOnUserBuildTest.java
index 7935476..0899886 100644
--- a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasNotSupportedOnUserBuildTest.java
+++ b/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasNotSupportedOnUserBuildTest.java
@@ -32,7 +32,7 @@
  */
 public class ComponentAliasNotSupportedOnUserBuildTest {
     protected static final DeviceConfigStateHelper sDeviceConfig = new DeviceConfigStateHelper(
-            DeviceConfig.NAMESPACE_ACTIVITY_MANAGER);
+            DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS);
 
     @AfterClass
     public static void restoreDeviceConfig() throws Exception {
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index 7b1f7a5..b673957 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -60,7 +60,7 @@
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
-import android.telephony.TelephonyManager.CarrierPrivilegesListener;
+import android.telephony.TelephonyManager.CarrierPrivilegesCallback;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
@@ -187,11 +187,11 @@
         return captor.getValue();
     }
 
-    private List<CarrierPrivilegesListener> getCarrierPrivilegesListeners() {
-        final ArgumentCaptor<CarrierPrivilegesListener> captor =
-                ArgumentCaptor.forClass(CarrierPrivilegesListener.class);
+    private List<CarrierPrivilegesCallback> getCarrierPrivilegesCallbacks() {
+        final ArgumentCaptor<CarrierPrivilegesCallback> captor =
+                ArgumentCaptor.forClass(CarrierPrivilegesCallback.class);
         verify(mTelephonyManager, atLeastOnce())
-                .addCarrierPrivilegesListener(anyInt(), any(), captor.capture());
+                .registerCarrierPrivilegesCallback(anyInt(), any(), captor.capture());
 
         return captor.getAllValues();
     }
@@ -270,12 +270,12 @@
         assertNotNull(getOnSubscriptionsChangedListener());
 
         verify(mTelephonyManager, times(2))
-                .addCarrierPrivilegesListener(anyInt(), any(HandlerExecutor.class), any());
+                .registerCarrierPrivilegesCallback(anyInt(), any(HandlerExecutor.class), any());
         verify(mTelephonyManager)
-                .addCarrierPrivilegesListener(eq(0), any(HandlerExecutor.class), any());
+                .registerCarrierPrivilegesCallback(eq(0), any(HandlerExecutor.class), any());
         verify(mTelephonyManager)
-                .addCarrierPrivilegesListener(eq(1), any(HandlerExecutor.class), any());
-        assertEquals(2, getCarrierPrivilegesListeners().size());
+                .registerCarrierPrivilegesCallback(eq(1), any(HandlerExecutor.class), any());
+        assertEquals(2, getCarrierPrivilegesCallbacks().size());
     }
 
     @Test
@@ -287,10 +287,10 @@
         final OnSubscriptionsChangedListener listener = getOnSubscriptionsChangedListener();
         verify(mSubscriptionManager).removeOnSubscriptionsChangedListener(eq(listener));
 
-        for (CarrierPrivilegesListener carrierPrivilegesListener :
-                getCarrierPrivilegesListeners()) {
+        for (CarrierPrivilegesCallback carrierPrivilegesCallback :
+                getCarrierPrivilegesCallbacks()) {
             verify(mTelephonyManager)
-                    .removeCarrierPrivilegesListener(eq(carrierPrivilegesListener));
+                    .unregisterCarrierPrivilegesCallback(eq(carrierPrivilegesCallback));
         }
     }
 
@@ -303,15 +303,15 @@
         mTelephonySubscriptionTracker.setReadySubIdsBySlotId(readySubIdsBySlotId);
         doReturn(1).when(mTelephonyManager).getActiveModemCount();
 
-        List<CarrierPrivilegesListener> carrierPrivilegesListeners =
-                getCarrierPrivilegesListeners();
+        List<CarrierPrivilegesCallback> carrierPrivilegesCallbacks =
+                getCarrierPrivilegesCallbacks();
 
         mTelephonySubscriptionTracker.onReceive(mContext, buildTestMultiSimConfigBroadcastIntent());
         mTestLooper.dispatchAll();
 
-        for (CarrierPrivilegesListener carrierPrivilegesListener : carrierPrivilegesListeners) {
+        for (CarrierPrivilegesCallback carrierPrivilegesCallback : carrierPrivilegesCallbacks) {
             verify(mTelephonyManager)
-                    .removeCarrierPrivilegesListener(eq(carrierPrivilegesListener));
+                    .unregisterCarrierPrivilegesCallback(eq(carrierPrivilegesCallback));
         }
 
         // Expect cache cleared for inactive slots.
@@ -323,9 +323,9 @@
         // Expect a new CarrierPrivilegesListener to have been registered for slot 0, and none other
         // (2 previously registered during startup, for slots 0 & 1)
         verify(mTelephonyManager, times(3))
-                .addCarrierPrivilegesListener(anyInt(), any(HandlerExecutor.class), any());
+                .registerCarrierPrivilegesCallback(anyInt(), any(HandlerExecutor.class), any());
         verify(mTelephonyManager, times(2))
-                .addCarrierPrivilegesListener(eq(0), any(HandlerExecutor.class), any());
+                .registerCarrierPrivilegesCallback(eq(0), any(HandlerExecutor.class), any());
 
         // Verify that this triggers a re-evaluation
         verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
@@ -391,8 +391,8 @@
     public void testOnCarrierPrivilegesChanged() throws Exception {
         setupReadySubIds();
 
-        final CarrierPrivilegesListener listener = getCarrierPrivilegesListeners().get(0);
-        listener.onCarrierPrivilegesChanged(Collections.emptyList(), new int[] {});
+        final CarrierPrivilegesCallback callback = getCarrierPrivilegesCallbacks().get(0);
+        callback.onCarrierPrivilegesChanged(Collections.emptySet(), Collections.emptySet());
         mTestLooper.dispatchAll();
 
         verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 42715f9..8d35eee 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -1038,6 +1038,13 @@
         continue;
       }
 
+      if (maybe_name.value().substr(0, std::strlen("removed_")) == "removed_") {
+        // Skip resources that have been removed from the framework, but leave a hole so that
+        // other staged resources don't shift and break apps previously compiled against them
+        next_id.id++;
+        continue;
+      }
+
       ParsedResource& entry_res = out_resource->child_resources.emplace_back(ParsedResource{
           .name = ResourceName{{}, *parsed_type, maybe_name.value().to_string()},
           .source = item_source,
diff --git a/tools/aapt2/tools/finalize_res.py b/tools/aapt2/tools/finalize_res.py
new file mode 100755
index 0000000..0e4d865
--- /dev/null
+++ b/tools/aapt2/tools/finalize_res.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python3
+# -*- coding: 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.
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Finalize resource values in <staging-public-group> tags
+and convert those to <staging-public-group-final>
+
+Usage: $ANDROID_BUILD_TOP/frameworks/base/tools/aapt2/tools/finalize_res.py \
+           $ANDROID_BUILD_TOP/frameworks/base/core/res/res/values/public-staging.xml \
+           $ANDROID_BUILD_TOP/frameworks/base/core/res/res/values/public-final.xml
+"""
+
+import re
+import sys
+
+resTypes = ["attr", "id", "style", "string", "dimen", "color", "array", "drawable", "layout",
+            "anim", "animator", "interpolator", "mipmap", "integer", "transition", "raw", "bool",
+            "fraction"]
+
+_type_ids = {}
+_type = ""
+
+_lowest_staging_first_id = 0x01FFFFFF
+
+"""
+    Created finalized <public> declarations for staging resources, ignoring them if they've been
+    prefixed with removed_. The IDs are assigned without holes starting from the last ID for that
+    type currently finalized in public-final.xml.
+"""
+def finalize_item(raw):
+    name = raw.group(1)
+    if re.match(r'_*removed.+', name):
+        return ""
+    id = _type_ids[_type]
+    _type_ids[_type] += 1
+    return '  <public type="%s" name="%s" id="%s" />\n' % (_type, name, '0x{0:0{1}x}'.format(id, 8))
+
+
+"""
+    Finalizes staging-public-groups if they have any entries in them. Also keeps track of the
+    lowest first-id of the non-empty groups so that the next release's staging-public-groups can
+    be assigned the next down shifted first-id.
+"""
+def finalize_group(raw):
+    global _type, _lowest_staging_first_id
+    _type = raw.group(1)
+    id = int(raw.group(2), 16)
+    _type_ids[_type] = _type_ids.get(_type, id)
+    (res, count) = re.subn(' {0,4}<public name="(.+?)" */>\n', finalize_item, raw.group(3))
+    if count > 0:
+        res = raw.group(0).replace("staging-public-group",
+                                   "staging-public-group-final") + '\n' + res
+        _lowest_staging_first_id = min(id, _lowest_staging_first_id)
+    return res
+
+"""
+    Collects the max ID for each resType so that the new IDs can be assigned afterwards
+"""
+def collect_ids(raw):
+    for m in re.finditer(r'<public type="(.+?)" name=".+?" id="(.+?)" />', raw):
+        type = m.group(1)
+        id = int(m.group(2), 16)
+        _type_ids[type] = max(id + 1, _type_ids.get(type, 0))
+
+
+with open(sys.argv[1], "r+") as stagingFile:
+    with open(sys.argv[2], "r+") as finalFile:
+        existing = finalFile.read()
+        # Cut out the closing resources tag so that it can be concatenated easily later
+        existing = "\n".join(existing.rsplit("</resources>", 1))
+
+        # Collect the IDs from the existing already finalized resources
+        collect_ids(existing)
+
+        staging = stagingFile.read()
+        stagingSplit = staging.rsplit("<resources>")
+        staging = stagingSplit[1]
+        staging = re.sub(
+            r'<staging-public-group type="(.+?)" first-id="(.+?)">(.+?)</staging-public-group>',
+            finalize_group, staging, flags=re.DOTALL)
+        staging = re.sub(r' *\n', '\n', staging)
+        staging = re.sub(r'\n{3,}', '\n\n', staging)
+
+        # First write the existing finalized declarations and then append the new stuff
+        finalFile.seek(0)
+        finalFile.write(existing.strip("\n"))
+        finalFile.write("\n\n")
+        finalFile.write(staging.strip("\n"))
+        finalFile.write("\n")
+        finalFile.truncate()
+
+        stagingFile.seek(0)
+        # Include the documentation from public-staging.xml that was previously split out
+        stagingFile.write(stagingSplit[0])
+        # Write the next platform header
+        stagingFile.write("<resources>\n\n")
+        stagingFile.write("  <!-- ===============================================================\n")
+        stagingFile.write("    Resources added in version NEXT of the platform\n\n")
+        stagingFile.write("    NOTE: After this version of the platform is forked, changes cannot be made to the root\n")
+        stagingFile.write("    branch's groups for that release. Only merge changes to the forked platform branch.\n")
+        stagingFile.write("    =============================================================== -->\n")
+        stagingFile.write("  <eat-comment/>\n\n")
+
+        # Seed the next release's staging-public-groups as empty declarations,
+        # so its easy for another developer to expose a new public resource
+        nextId = _lowest_staging_first_id - 0x00010000
+        for resType in resTypes:
+            stagingFile.write('  <staging-public-group type="%s" first-id="%s">\n'
+                              '  </staging-public-group>\n\n' %
+                              (resType, '0x{0:0{1}x}'.format(nextId, 8)))
+            nextId -= 0x00010000
+
+        # Close the resources tag and truncate, since the file will be shorter than the previous
+        stagingFile.write("</resources>\n")
+        stagingFile.truncate()
diff --git a/tools/finalize_res/finalize_res.py b/tools/finalize_res/finalize_res.py
deleted file mode 100755
index aaf0187..0000000
--- a/tools/finalize_res/finalize_res.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python3
-#-*- coding: utf-8 -*-
-
-# Copyright (C) 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Finalize resource values in <staging-public-group> tags
-
-Usage: finalize_res.py core/res/res/values/public.xml public_finalized.xml
-"""
-
-import re, sys, codecs
-
-def finalize_item(raw):
-    global _type, _id
-    _id += 1
-    return '<public type="%s" name="%s" id="%s" />' % (_type, raw.group(1), '0x{0:0{1}x}'.format(_id-1,8))
-
-def finalize_group(raw):
-    global _type, _id
-    _type = raw.group(1)
-    _id = int(raw.group(2), 16)
-    return re.sub(r'<public name="(.+?)" */>', finalize_item, raw.group(3))
-
-with open(sys.argv[1]) as f:
-    raw = f.read()
-    raw = re.sub(r'<staging-public-group type="(.+?)" first-id="(.+?)">(.+?)</staging-public-group>', finalize_group, raw, flags=re.DOTALL)
-    with open(sys.argv[2], "w") as f:
-        f.write(raw)
diff --git a/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt b/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt
index 1aec9b8..2e60f64 100644
--- a/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt
+++ b/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt
@@ -21,8 +21,6 @@
 import com.android.codegen.CANONICAL_BUILDER_CLASS
 import com.android.codegen.CODEGEN_NAME
 import com.android.codegen.CODEGEN_VERSION
-import com.sun.tools.javac.code.Symbol
-import com.sun.tools.javac.code.Type
 import java.io.File
 import java.io.FileNotFoundException
 import javax.annotation.processing.AbstractProcessor
@@ -33,6 +31,7 @@
 import javax.lang.model.element.Element
 import javax.lang.model.element.ElementKind
 import javax.lang.model.element.TypeElement
+import javax.lang.model.type.ExecutableType
 import javax.tools.Diagnostic
 
 private const val STALE_FILE_THRESHOLD_MS = 1000
@@ -102,14 +101,13 @@
             append(" ")
             append(elem.annotationMirrors.joinToString(" ", transform = { annotationToString(it) }))
             append(" ")
-            if (elem is Symbol) {
-                if (elem.type is Type.MethodType) {
-                    append((elem.type as Type.MethodType).returnType)
-                } else {
-                    append(elem.type)
-                }
-                append(" ")
+            val type = elem.asType()
+            if (type is ExecutableType) {
+                append(type.returnType)
+            } else {
+                append(type)
             }
+            append(" ")
             append(elem)
         }
     }
@@ -234,4 +232,4 @@
     override fun getSupportedSourceVersion(): SourceVersion {
         return SourceVersion.latest()
     }
-}
\ No newline at end of file
+}
diff --git a/tools/validatekeymaps/Android.bp b/tools/validatekeymaps/Android.bp
index 0423b7a..ff24d16 100644
--- a/tools/validatekeymaps/Android.bp
+++ b/tools/validatekeymaps/Android.bp
@@ -32,7 +32,7 @@
         "libui-types",
     ],
     target: {
-        linux_glibc: {
+        host_linux: {
             static_libs: [
                 // libbinder is only available for linux
                 "libbinder",
diff --git a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
index 9604475..d85a5bd 100644
--- a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
+++ b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
@@ -963,6 +963,25 @@
     }
 
     /**
+     * Get the max number of SSIDs that the driver supports per scan.
+     *
+     * @param ifaceName Name of the interface.
+     */
+    public int getMaxSsidsPerScan(@NonNull String ifaceName) {
+        IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
+        if (scannerImpl == null) {
+            Log.e(TAG, "No valid wificond scanner interface handler for iface=" + ifaceName);
+            return 0;
+        }
+        try {
+            return scannerImpl.getMaxSsidsPerScan();
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to getMaxSsidsPerScan");
+        }
+        return 0;
+    }
+
+    /**
      * Return scan type for the parcelable {@link SingleScanSettings}
      */
     private static int getScanType(@WifiAnnotations.ScanType int scanType) {